Register many students at once
- Bearer token
- Permission
student/create - Core record
Registers 30 to 1000 students in one request. Every row follows registerStudent’s rules exactly, so read that operation first: this one is the same registration, a class at a time.
It answers before it registers anybody. The whole batch is checked while you wait — every field, every country, grade, city and school, and every email address — and then 202 with an import you read to follow it. The Location header is where to read it. Nothing exists yet when you get that answer: poll getStudentImport every few seconds until status is no longer queued or running.
All of them or none of them. The students are written in one transaction, so a batch either registers every row or registers nothing. There is no partial import to reconcile and nothing to undo. A batch that fails says why, and you fix the rows and send it again.
No passwords. A row takes everything registerStudent takes except password: hashing is deliberately slow, and a thousand of them would keep the batch waiting and leave the plaintext queued meanwhile. Sign the students in with createSigninLink, or set a password per student afterwards with setStudentPassword.
The welcome email is the one registerStudent sends, one per student, with the same text.
Limits. One unfinished import per account: send the next batch when this one has finished. 10 requests an hour. Bodies up to 1.5 MB here, where every other operation takes 100 kB.
Sending the same batch twice is safe. The same rows from your account inside 24 hours answer with the import you already have, not a second one, so a request whose answer you never saw can simply be sent again.
If anything is wrong with the rows the answer is 422, nothing is queued, and error.details.rows lists every row at fault with its position, property and a code to branch on. Fix them and send the batch again.
Request body
studentsarray of StudentImportRowrequiredThe students to register, 30 to 1000 of them. Below that, call
registerStudentper student: an import is queued and answered before it runs, and for a handful of students the round trip is not worth the wait.min items
30max items100013 fields of each item
firstNamestringrequiredThe student’s first name. Printed on certificates and reports, followed by
lastName.example
JanelastNamestringrequiredThe student’s surname. Printed on certificates and reports after
firstName. It cannot be empty.example
DoebirthstringrequiredDate of birth as
DD/MM/YYYY, and a date that exists:31/02/2008is refused. An ISO date such as2008-05-14is refused.pattern
^(0[1-9]|[12]\d|3[01])\/(0[1-9]|1[0-2])\/\d{4}$example14/05/2008sexstringrequiredOne of
m,forn.one of
mfnexample
femailstringrequiredThe student’s email address, stored in lower case. An address belongs to one student on the whole platform, so one already registered, by your account or another, is refused with 409.
format
emailexamplejane.doe@example.comemail2stringLeave this out. Any value but an empty one is refused with 400.
phonestringA phone number, stored as you send it. No format is checked. On an update,
""clears it.example
+1 555 0100countrystringrequiredThe
_idof a country, fromlistCountries(GET /v1/country). An id only: a name or an ISO code is refused. Its two-letter code starts the student’susername.pattern
^[0-9a-fA-F]{24}$example6650a1b2c3d4e5f6a7b8c9d1gradestringrequiredThe
_idof a grade, fromlistGrades(GET /v1/grade), or its name,1to12. Either way the grade’s_idis what is stored. One that matches no grade is refused with 400. The grade decides which exams the student is offered.example
10schoolstringrequiredThe
_idof a school, or its name withincountryandcity, matched without regard to case. There is no list of schools to look one up in: send the name your records hold. One that matches no school is refused with 400; no school is ever created.example
Springfield High SchoolcitystringrequiredThe
_idof a city, or its name withincountry, matched without regard to case. There is no list of cities to look one up in: send the name your records hold. One that matches no city is refused with 400; no city is ever created.example
SpringfieldactivatedPlatformsThisSeasonarray of stringThe organizations the student takes part in this season, by
slug(aslistOrganizationsgives it, exceptmto: the core record, which every student is on), orcommonfor every organization. Registration sets["common"]when you leave it out;nullis refused with 400. At most 6 entries.each one of
commonstemhilinguaneogmathcodingmax items
6example["common"]externalRefstringYour own reference for this row, echoed back when you read the import. Not stored on the student and not required to be unique. At most 64 characters.
max length
64exampleroster-2026-114
clientReferencestringYour own name for this batch, echoed back when you read the import. At most 64 characters.
max length
64exampleyear-10-autumn-2026
Responses
202 Accepted
Accepted: message is "Import accepted. The students are registered in the background; read the import to follow it.".
Or message is "You already sent this batch. Its import is unchanged.": You sent these exact rows inside the last 24 hours. The import in data is the one you already have; no second one was made.
Body
successbooleanrequiredAlways
trueon a success.one of
truemessagestringrequireddataobject · StudentImportResponserequiredA batch of students you asked to register, and what has happened to it.
11 fields of data
_idstringrequiredThe import’s
_id. Read it withgetStudentImport.example
65f0c2a1d3e4f5a6b7c8d901statusstringrequiredqueueduntil a server picks it up,runningwhile it registers, thensucceededorfailed.cancelledmeans an operator stopped it. There is no partial import: on anything butsucceededno student of this batch was registered.one of
queuedrunningsucceededfailedcancelledexample
queuedtotalnumberrequiredHow many rows you sent.
example
250registerednumberrequiredHow many students were registered:
totalonce the import has succeeded, and 0 until then and for ever after a failure.example
250clientReferencestringThe
clientReferenceyou sent, if you sent one.example
year-10-autumn-2026failureobject · StudentImportFailureResponseSet once the import has failed or been cancelled.
2 fields of failure
codestringrequiredA stable machine code.
rows_rejected: a row stopped being registrable between the check and the write, most often because its address was registered in between; the rows say which.forbidden: the account may no longer register students.cancelled: an operator stopped it.internal_error: something failed on our side.example
rows_rejectedmessagestringrequiredWritten for a person, and may change: never branch on it.
example
Two rows could no longer be registered. Nothing was registered.
studentsarray of StudentImportRowResponserequiredOne page of the rows, in the order you sent them. Page it with
pageandlimit;pagination.totalcounts every row. Absent from the answer tocreateStudentImport, which has nothing to report yet.6 fields of each item
rownumberrequiredThe row’s position in the
studentsyou sent, counting from 0.example
0emailstringrequiredThe address you sent for this row, in lower case.
format
emailexamplejane.doe@example.comexternalRefstringThe
externalRefyou sent for this row, if you sent one.example
roster-2026-114statusstringrequiredpendinguntil the import runs, thenregisteredfor every row when it succeeds, orskippedfor every row when it does not. An import registers all of its students or none of them.one of
pendingregisteredskippedexample
registeredstudentIdstringThe student’s
_id, on aregisteredrow. Use it withgetStudent,createSigninLinkandcreateApplication.example
6650a1b2c3d4e5f6a7b8c9d0errorobject · StudentImportRowErrorResponseWhy this row could not be registered, when it could not.
4 fields of error
codestringrequiredA stable machine code: branch on this.
invalid_fieldandunexpected_fieldare the row’s own rules;unknown_referenceis acountry,grade,cityorschoolthat matches nothing;duplicate_in_requestis the same address twice in your own body;email_taken_by_your_studentis one of your students;email_unavailableis an address that cannot be registered, and the answer never says who holds it.one of
invalid_fieldunexpected_fieldunknown_referenceduplicate_in_requestemail_taken_by_your_studentemail_unavailableexample
email_taken_by_your_studentmessagestringrequiredWritten for a person, and may change: never branch on it.
example
One of your students already has this email address.studentIdstringOn
email_taken_by_your_student: the_idof the student of yours who has the address, so you can update them instead.example
6650a1b2c3d4e5f6a7b8c9d0duplicateOfnumberOn
duplicate_in_request: the earlier row in your own body with the same address.example
12
createdAtstringrequiredWhen you sent it.
format
date-timeexample2026-10-06T08:15:00.000ZstartedAtstringWhen a server picked it up.
format
date-timeexample2026-10-06T08:15:04.000ZfinishedAtstringWhen it ended, whichever way it ended.
format
date-timeexample2026-10-06T08:15:09.000ZexpiresAtstringrequiredWhen this import stops being readable. After it,
getStudentImportanswers 404, exactly as it does for an import that never existed. The students stay registered.format
date-timeexample2026-11-05T08:15:09.000Z
Headers
LocationstringThe import’s own path,
/v1/student/import/{importId}. Read it to follow the batch.X-RateLimit-LimitintegerRequests your account may make to this operation per window (10 per 3600 seconds).
X-RateLimit-RemainingintegerRequests left in the current window.
X-RateLimit-ResetintegerSeconds until the current window ends.
Example
{
"data": {
"_id": "65f0c2a1d3e4f5a6b7c8d901",
"clientReference": "year-10-autumn-2026",
"createdAt": "2026-10-06T08:15:00.000Z",
"expiresAt": "2026-11-05T08:15:09.000Z",
"failure": {
"code": "rows_rejected",
"message": "Two rows could no longer be registered. Nothing was registered."
},
"finishedAt": "2026-10-06T08:15:09.000Z",
"registered": 250,
"startedAt": "2026-10-06T08:15:04.000Z",
"status": "queued",
"students": [
{
"email": "jane.doe@example.com",
"error": {
"code": "email_taken_by_your_student",
"duplicateOf": 12,
"message": "One of your students already has this email address.",
"studentId": "6650a1b2c3d4e5f6a7b8c9d0"
},
"externalRef": "roster-2026-114",
"row": 0,
"status": "registered",
"studentId": "6650a1b2c3d4e5f6a7b8c9d0"
}
],
"total": 250
},
"message": "Import accepted. The students are registered in the background; read the import to follow it.",
"success": true
}400 Bad request
bad_request: The body is not valid JSON, breaks a field’s rules, or has a field this operation does not accept ("property <name> should not exist").bad_request: A row breaks one ofregisterStudent’s rules. The message names the row and the property, counting rows from 0.bad_request:studentshas fewer than 30 rows or more than 1000. Below 30, callregisterStudentper student.bad_request: A row carriespassword, which this operation does not take, or any other property it does not accept.
When
bad_requestThe body is not valid JSON, breaks a field’s rules, or has a field this operation does not accept ("property <name> should not exist").
bad_requestA row breaks one of
registerStudent’s rules. The message names the row and the property, counting rows from 0.bad_requeststudentshas fewer than 30 rows or more than 1000. Below 30, callregisterStudentper student.bad_requestA row carries
password, which this operation does not take, or any other property it does not accept.
Example
{
"error": {
"code": "bad_request",
"documentation_url": "https://hub.main-team.org/api/errors#bad_request",
"message": "The request was malformed or contained invalid parameters.",
"request_id": "0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8e"
}
}Fields of the error body
errorobject · ErrorDetailrequiredWhat went wrong.
5 fields of error
codestringrequiredA stable machine code: branch on this. Each one is explained at
documentation_url.one of
invalid_emailbad_requestunauthorizedforbiddennot_foundconflictpayload_too_largeunsupported_media_typeunprocessable_entitytoo_many_requestsinternal_errorservice_unavailableexample
not_foundmessagestringrequiredWritten for a person, and may change: never branch on it.
example
Not found!documentation_urlstringrequiredWhere this code is explained.
format
uriexamplehttps://hub.main-team.org/api/errors#not_foundrequest_idstringrequiredThis request’s id, also sent as the
X-Request-Idresponse header: the one you sent, when it was acceptable, or else one the API made. Quote it when you report a problem.example
0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8edetailsobjectPresent only where an operation says so, and then with the shape that operation documents — the rows it could not accept, say. Treat it as absent everywhere else, and ignore a
detailsyou do not recognise.
401 Unauthorized
unauthorized: The token is missing or malformed, is not signed with your account’s apiSecret, breaks the iat and exp rules, has expired or been revoked, or its account is not active. All of these answer the same.
When
unauthorizedThe token is missing or malformed, is not signed with your account’s
apiSecret, breaks theiatandexprules, has expired or been revoked, or its account is not active. All of these answer the same.
Example
{
"error": {
"code": "unauthorized",
"documentation_url": "https://hub.main-team.org/api/errors#unauthorized",
"message": "Authentication is required or the provided credentials are invalid.",
"request_id": "0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8e"
}
}Fields of the error body
errorobject · ErrorDetailrequiredWhat went wrong.
5 fields of error
codestringrequiredA stable machine code: branch on this. Each one is explained at
documentation_url.one of
invalid_emailbad_requestunauthorizedforbiddennot_foundconflictpayload_too_largeunsupported_media_typeunprocessable_entitytoo_many_requestsinternal_errorservice_unavailableexample
not_foundmessagestringrequiredWritten for a person, and may change: never branch on it.
example
Not found!documentation_urlstringrequiredWhere this code is explained.
format
uriexamplehttps://hub.main-team.org/api/errors#not_foundrequest_idstringrequiredThis request’s id, also sent as the
X-Request-Idresponse header: the one you sent, when it was acceptable, or else one the API made. Quote it when you report a problem.example
0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8edetailsobjectPresent only where an operation says so, and then with the shape that operation documents — the rows it could not accept, say. Treat it as absent everywhere else, and ignore a
detailsyou do not recognise.
403 Forbidden
forbidden: The token is valid, but no role on your account allows student/create on mto, the organization every operation without :organizationId acts on, or a role denies it.
When
forbiddenThe token is valid, but no role on your account allows
student/createonmto, the organization every operation without:organizationIdacts on, or a role denies it.
Example
{
"error": {
"code": "forbidden",
"documentation_url": "https://hub.main-team.org/api/errors#forbidden",
"message": "Insufficient role permissions",
"request_id": "0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8e"
}
}Fields of the error body
errorobject · ErrorDetailrequiredWhat went wrong.
5 fields of error
codestringrequiredA stable machine code: branch on this. Each one is explained at
documentation_url.one of
invalid_emailbad_requestunauthorizedforbiddennot_foundconflictpayload_too_largeunsupported_media_typeunprocessable_entitytoo_many_requestsinternal_errorservice_unavailableexample
not_foundmessagestringrequiredWritten for a person, and may change: never branch on it.
example
Not found!documentation_urlstringrequiredWhere this code is explained.
format
uriexamplehttps://hub.main-team.org/api/errors#not_foundrequest_idstringrequiredThis request’s id, also sent as the
X-Request-Idresponse header: the one you sent, when it was acceptable, or else one the API made. Quote it when you report a problem.example
0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8edetailsobjectPresent only where an operation says so, and then with the shape that operation documents — the rows it could not accept, say. Treat it as absent everywhere else, and ignore a
detailsyou do not recognise.
404 Not found
not_found: Bulk registration is not switched on for the environment you are calling. Nothing was queued. Ask support before you build against it.
When
not_foundBulk registration is not switched on for the environment you are calling. Nothing was queued. Ask support before you build against it.
Example
{
"error": {
"code": "not_found",
"documentation_url": "https://hub.main-team.org/api/errors#not_found",
"message": "The requested resource could not be found.",
"request_id": "0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8e"
}
}Fields of the error body
errorobject · ErrorDetailrequiredWhat went wrong.
5 fields of error
codestringrequiredA stable machine code: branch on this. Each one is explained at
documentation_url.one of
invalid_emailbad_requestunauthorizedforbiddennot_foundconflictpayload_too_largeunsupported_media_typeunprocessable_entitytoo_many_requestsinternal_errorservice_unavailableexample
not_foundmessagestringrequiredWritten for a person, and may change: never branch on it.
example
Not found!documentation_urlstringrequiredWhere this code is explained.
format
uriexamplehttps://hub.main-team.org/api/errors#not_foundrequest_idstringrequiredThis request’s id, also sent as the
X-Request-Idresponse header: the one you sent, when it was acceptable, or else one the API made. Quote it when you report a problem.example
0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8edetailsobjectPresent only where an operation says so, and then with the shape that operation documents — the rows it could not accept, say. Treat it as absent everywhere else, and ignore a
detailsyou do not recognise.
409 Conflict
conflict: You already have an import that has not finished. Read it, and send the next one when it has.
When
conflictYou already have an import that has not finished. Read it, and send the next one when it has.
Example
{
"error": {
"code": "conflict",
"documentation_url": "https://hub.main-team.org/api/errors#conflict",
"message": "You already have an import that has not finished. Read it, and send the next one when it has. (65f0c2a1d3e4f5a6b7c8d901)",
"request_id": "0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8e"
}
}Fields of the error body
errorobject · ErrorDetailrequiredWhat went wrong.
5 fields of error
codestringrequiredA stable machine code: branch on this. Each one is explained at
documentation_url.one of
invalid_emailbad_requestunauthorizedforbiddennot_foundconflictpayload_too_largeunsupported_media_typeunprocessable_entitytoo_many_requestsinternal_errorservice_unavailableexample
not_foundmessagestringrequiredWritten for a person, and may change: never branch on it.
example
Not found!documentation_urlstringrequiredWhere this code is explained.
format
uriexamplehttps://hub.main-team.org/api/errors#not_foundrequest_idstringrequiredThis request’s id, also sent as the
X-Request-Idresponse header: the one you sent, when it was acceptable, or else one the API made. Quote it when you report a problem.example
0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8edetailsobjectPresent only where an operation says so, and then with the shape that operation documents — the rows it could not accept, say. Treat it as absent everywhere else, and ignore a
detailsyou do not recognise.
413 Payload too large
payload_too_large: The body is larger than 1.5 MB.
When
payload_too_largeThe body is larger than 1.5 MB.
Example
{
"error": {
"code": "payload_too_large",
"documentation_url": "https://hub.main-team.org/api/errors#payload_too_large",
"message": "request entity too large",
"request_id": "0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8e"
}
}Fields of the error body
errorobject · ErrorDetailrequiredWhat went wrong.
5 fields of error
codestringrequiredA stable machine code: branch on this. Each one is explained at
documentation_url.one of
invalid_emailbad_requestunauthorizedforbiddennot_foundconflictpayload_too_largeunsupported_media_typeunprocessable_entitytoo_many_requestsinternal_errorservice_unavailableexample
not_foundmessagestringrequiredWritten for a person, and may change: never branch on it.
example
Not found!documentation_urlstringrequiredWhere this code is explained.
format
uriexamplehttps://hub.main-team.org/api/errors#not_foundrequest_idstringrequiredThis request’s id, also sent as the
X-Request-Idresponse header: the one you sent, when it was acceptable, or else one the API made. Quote it when you report a problem.example
0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8edetailsobjectPresent only where an operation says so, and then with the shape that operation documents — the rows it could not accept, say. Treat it as absent everywhere else, and ignore a
detailsyou do not recognise.
415 Unsupported media type
unsupported_media_type: The body declares a charset that is not a UTF one (send UTF-8), or a Content-Encoding other than gzip, deflate or br.
When
unsupported_media_typeThe body declares a charset that is not a UTF one (send UTF-8), or a
Content-Encodingother than gzip, deflate or br.
Example
{
"error": {
"code": "unsupported_media_type",
"documentation_url": "https://hub.main-team.org/api/errors#unsupported_media_type",
"message": "unsupported charset \"ISO-8859-1\"",
"request_id": "0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8e"
}
}Fields of the error body
errorobject · ErrorDetailrequiredWhat went wrong.
5 fields of error
codestringrequiredA stable machine code: branch on this. Each one is explained at
documentation_url.one of
invalid_emailbad_requestunauthorizedforbiddennot_foundconflictpayload_too_largeunsupported_media_typeunprocessable_entitytoo_many_requestsinternal_errorservice_unavailableexample
not_foundmessagestringrequiredWritten for a person, and may change: never branch on it.
example
Not found!documentation_urlstringrequiredWhere this code is explained.
format
uriexamplehttps://hub.main-team.org/api/errors#not_foundrequest_idstringrequiredThis request’s id, also sent as the
X-Request-Idresponse header: the one you sent, when it was acceptable, or else one the API made. Quote it when you report a problem.example
0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8edetailsobjectPresent only where an operation says so, and then with the shape that operation documents — the rows it could not accept, say. Treat it as absent everywhere else, and ignore a
detailsyou do not recognise.
422 Unprocessable entity
unprocessable_entity: One or more rows cannot be registered. Nothing was queued. error.details.rows lists every row at fault with a code to branch on: invalid_field, unexpected_field, unknown_reference, duplicate_in_request, email_taken_by_your_student (with that student’s _id) and email_unavailable, which never says who holds the address. The list is left out, and only counted, when the only problem is unavailable addresses and your account has already been shown those rows several times today.
When
unprocessable_entityOne or more rows cannot be registered. Nothing was queued.
error.details.rowslists every row at fault with acodeto branch on:invalid_field,unexpected_field,unknown_reference,duplicate_in_request,email_taken_by_your_student(with that student’s_id) andemail_unavailable, which never says who holds the address. The list is left out, and only counted, when the only problem is unavailable addresses and your account has already been shown those rows several times today.
Example
{
"error": {
"code": "unprocessable_entity",
"details": {
"rejected": 3,
"rows": [
{
"code": "invalid_field",
"field": "birth",
"message": "birth must be a real date in DD/MM/YYYY format",
"row": 4
},
{
"code": "email_taken_by_your_student",
"field": "email",
"message": "One of your students already has this email address.",
"row": 17,
"studentId": "652f1c9b8e4b2a0012a3c4d5"
},
{
"code": "duplicate_in_request",
"duplicateOf": 12,
"field": "email",
"message": "Row 12 has the same email address.",
"row": 31
}
],
"total": 250,
"truncated": false
},
"documentation_url": "https://hub.main-team.org/api/errors#unprocessable_entity",
"message": "3 of 250 rows cannot be registered. Nothing was registered and no import was queued; error.details.rows lists every problem.",
"request_id": "0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8e"
}
}Fields of the error body
errorobject · ErrorDetailrequiredWhat went wrong.
5 fields of error
codestringrequiredA stable machine code: branch on this. Each one is explained at
documentation_url.one of
invalid_emailbad_requestunauthorizedforbiddennot_foundconflictpayload_too_largeunsupported_media_typeunprocessable_entitytoo_many_requestsinternal_errorservice_unavailableexample
not_foundmessagestringrequiredWritten for a person, and may change: never branch on it.
example
Not found!documentation_urlstringrequiredWhere this code is explained.
format
uriexamplehttps://hub.main-team.org/api/errors#not_foundrequest_idstringrequiredThis request’s id, also sent as the
X-Request-Idresponse header: the one you sent, when it was acceptable, or else one the API made. Quote it when you report a problem.example
0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8edetailsobjectPresent only where an operation says so, and then with the shape that operation documents — the rows it could not accept, say. Treat it as absent everywhere else, and ignore a
detailsyou do not recognise.
429 Too many requests
too_many_requests: Your account has made more than 10 requests to this operation in the current hour. Wait the seconds in Retry-After before sending again. This operation has a budget of its own, lower than the 100 per 60 seconds every other operation gets.
When
too_many_requestsYour account has made more than 10 requests to this operation in the current hour. Wait the seconds in
Retry-Afterbefore sending again. This operation has a budget of its own, lower than the 100 per 60 seconds every other operation gets.
Headers
Retry-AfterintegerSeconds to wait before sending again; a request sent sooner is refused too.
Example
{
"error": {
"code": "too_many_requests",
"documentation_url": "https://hub.main-team.org/api/errors#too_many_requests",
"message": "Too many requests to this operation. Wait the number of seconds in Retry-After, then try again.",
"request_id": "0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8e"
}
}Fields of the error body
errorobject · ErrorDetailrequiredWhat went wrong.
5 fields of error
codestringrequiredA stable machine code: branch on this. Each one is explained at
documentation_url.one of
invalid_emailbad_requestunauthorizedforbiddennot_foundconflictpayload_too_largeunsupported_media_typeunprocessable_entitytoo_many_requestsinternal_errorservice_unavailableexample
not_foundmessagestringrequiredWritten for a person, and may change: never branch on it.
example
Not found!documentation_urlstringrequiredWhere this code is explained.
format
uriexamplehttps://hub.main-team.org/api/errors#not_foundrequest_idstringrequiredThis request’s id, also sent as the
X-Request-Idresponse header: the one you sent, when it was acceptable, or else one the API made. Quote it when you report a problem.example
0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8edetailsobjectPresent only where an operation says so, and then with the shape that operation documents — the rows it could not accept, say. Treat it as absent everywhere else, and ignore a
detailsyou do not recognise.
500 Internal error
internal_error: Something failed on our side. Retry later, and quote request_id if it goes on.
When
internal_errorSomething failed on our side. Retry later, and quote
request_idif it goes on.
Example
{
"error": {
"code": "internal_error",
"documentation_url": "https://hub.main-team.org/api/errors#internal_error",
"message": "An unexpected error occurred.",
"request_id": "0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8e"
}
}Fields of the error body
errorobject · ErrorDetailrequiredWhat went wrong.
5 fields of error
codestringrequiredA stable machine code: branch on this. Each one is explained at
documentation_url.one of
invalid_emailbad_requestunauthorizedforbiddennot_foundconflictpayload_too_largeunsupported_media_typeunprocessable_entitytoo_many_requestsinternal_errorservice_unavailableexample
not_foundmessagestringrequiredWritten for a person, and may change: never branch on it.
example
Not found!documentation_urlstringrequiredWhere this code is explained.
format
uriexamplehttps://hub.main-team.org/api/errors#not_foundrequest_idstringrequiredThis request’s id, also sent as the
X-Request-Idresponse header: the one you sent, when it was acceptable, or else one the API made. Quote it when you report a problem.example
0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8edetailsobjectPresent only where an operation says so, and then with the shape that operation documents — the rows it could not accept, say. Treat it as absent everywhere else, and ignore a
detailsyou do not recognise.
503 Service unavailable
service_unavailable: This server is already checking another batch. Nothing was queued; wait the seconds inRetry-Afterand send it again.service_unavailable: Bulk registration is paused for a scheduled window, such as an exam morning. Nothing was queued;Retry-Afteris how long the window lasts. An import already queued is not lost — it waits and then runs.service_unavailable: Checking the batch took too long. Nothing was queued; send it again, or in smaller batches.
When
service_unavailableThis server is already checking another batch. Nothing was queued; wait the seconds in
Retry-Afterand send it again.service_unavailableBulk registration is paused for a scheduled window, such as an exam morning. Nothing was queued;
Retry-Afteris how long the window lasts. An import already queued is not lost — it waits and then runs.service_unavailableChecking the batch took too long. Nothing was queued; send it again, or in smaller batches.
Headers
Retry-AfterintegerSeconds to wait before sending again; a request sent sooner is refused too.
Example
{
"error": {
"code": "service_unavailable",
"documentation_url": "https://hub.main-team.org/api/errors#service_unavailable",
"message": "This server is already checking another import. Send it again in a few seconds.",
"request_id": "0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8e"
}
}Fields of the error body
errorobject · ErrorDetailrequiredWhat went wrong.
5 fields of error
codestringrequiredA stable machine code: branch on this. Each one is explained at
documentation_url.one of
invalid_emailbad_requestunauthorizedforbiddennot_foundconflictpayload_too_largeunsupported_media_typeunprocessable_entitytoo_many_requestsinternal_errorservice_unavailableexample
not_foundmessagestringrequiredWritten for a person, and may change: never branch on it.
example
Not found!documentation_urlstringrequiredWhere this code is explained.
format
uriexamplehttps://hub.main-team.org/api/errors#not_foundrequest_idstringrequiredThis request’s id, also sent as the
X-Request-Idresponse header: the one you sent, when it was acceptable, or else one the API made. Quote it when you report a problem.example
0b5c6d0e-8f7a-4b1c-9d2e-3f4a5b6c7d8edetailsobjectPresent only where an operation says so, and then with the shape that operation documents — the rows it could not accept, say. Treat it as absent everywhere else, and ignore a
detailsyou do not recognise.