[{"data":1,"prerenderedAt":550},["ShallowReactive",2],{"api-nav":3,"api-changelog":351},[4,28,57,95,115,301,317,331],{"id":5,"title":6,"links":7,"groups":27},"start","Start here",[8,11,15,18,21,24],{"title":9,"to":10},"Overview","\u002Fapi",{"title":12,"to":13,"status":14},"Quickstart","\u002Fapi\u002Fquickstart","available",{"title":16,"to":17,"status":14},"Environments","\u002Fapi\u002Fenvironments",{"title":19,"to":20,"status":14},"Authentication","\u002Fapi\u002Fauthentication",{"title":22,"to":23,"status":14},"Organizations","\u002Fapi\u002Forganizations",{"title":25,"to":26,"status":14},"Permissions","\u002Fapi\u002Fpermissions",[],{"id":29,"title":30,"links":31,"groups":56},"concepts","Concepts",[32,35,38,41,44,47,50,53],{"title":33,"to":34,"status":14},"Requests and responses","\u002Fapi\u002Frequests-and-responses",{"title":36,"to":37,"status":14},"Identifiers","\u002Fapi\u002Fidentifiers",{"title":39,"to":40,"status":14},"Pagination","\u002Fapi\u002Fpagination",{"title":42,"to":43},"Errors","\u002Fapi\u002Ferrors",{"title":45,"to":46,"status":14},"Rate limits","\u002Fapi\u002Frate-limits",{"title":48,"to":49,"status":14},"Retries","\u002Fapi\u002Fretries-and-idempotency",{"title":51,"to":52,"status":14},"Security","\u002Fapi\u002Fsecurity",{"title":54,"to":55,"status":14},"Versioning","\u002Fapi\u002Fversioning",[],{"id":58,"title":59,"links":60,"groups":94},"resources","Guides",[61,64,67,70,73,76,79,82,85,88,91],{"title":62,"to":63,"status":14},"Students","\u002Fapi\u002Fguides\u002Fstudents",{"title":65,"to":66,"status":14},"Bulk registration","\u002Fapi\u002Fguides\u002Fbulk-registration",{"title":68,"to":69,"status":14},"Passwords","\u002Fapi\u002Fguides\u002Fpasswords",{"title":71,"to":72,"status":14},"Supervisors","\u002Fapi\u002Fguides\u002Fsupervisors",{"title":74,"to":75,"status":14},"Reference data","\u002Fapi\u002Fguides\u002Freference-data",{"title":77,"to":78,"status":14},"API account","\u002Fapi\u002Fguides\u002Fapi-account",{"title":80,"to":81,"status":14},"Sign-in links","\u002Fapi\u002Fguides\u002Fsign-in-links",{"title":83,"to":84,"status":14},"Exams","\u002Fapi\u002Fguides\u002Fexams",{"title":86,"to":87,"status":14},"Applications","\u002Fapi\u002Fguides\u002Fapplications",{"title":89,"to":90,"status":14},"Group challenges","\u002Fapi\u002Fguides\u002Fgroup-challenges",{"title":92,"to":93,"status":14},"Certificates and reports","\u002Fapi\u002Fguides\u002Fcertificates-and-reports",[],{"id":96,"title":97,"links":98,"groups":114},"tutorials","Tutorials",[99,102,105,108,111],{"title":100,"to":101,"status":14},"Register and apply","\u002Fapi\u002Ftutorials\u002Fregister-and-apply",{"title":103,"to":104,"status":14},"Send a student to the panel","\u002Fapi\u002Ftutorials\u002Fsend-student-to-panel",{"title":106,"to":107,"status":14},"Change an application","\u002Fapi\u002Ftutorials\u002Fchange-an-application",{"title":109,"to":110,"status":14},"Collect results","\u002Fapi\u002Ftutorials\u002Fcollect-results",{"title":112,"to":113,"status":14},"Token handling","\u002Fapi\u002Ftutorials\u002Ftoken-handling",[],{"id":116,"title":117,"links":118,"groups":125},"reference","Reference",[119,122],{"title":120,"to":121},"All endpoints","\u002Fapi\u002Freference",{"title":123,"to":124},"Sandbox console","\u002Fapi\u002Fconsole",[126,135,145,166,206,212,230,255,271],{"tag":127,"slug":128,"links":129},"Health","health",[130],{"title":131,"to":132,"method":133,"deprecated":134},"Check that the API is up","\u002Fapi\u002Freference\u002Fget-health","GET",false,{"tag":77,"slug":136,"links":137},"api-account",[138,142],{"title":139,"to":140,"method":141,"deprecated":134},"Revoke the token you send, before it expires","\u002Fapi\u002Freference\u002Frevoke-token","POST",{"title":143,"to":144,"method":133,"deprecated":134},"Fetch the API account your token belongs to","\u002Fapi\u002Freference\u002Fget-current-api-account",{"tag":74,"slug":146,"links":147},"reference-data",[148,151,154,157,160,163],{"title":149,"to":150,"method":133,"deprecated":134},"List the countries a student can be registered in","\u002Fapi\u002Freference\u002Flist-countries",{"title":152,"to":153,"method":133,"deprecated":134},"Fetch one country by its id","\u002Fapi\u002Freference\u002Fget-country",{"title":155,"to":156,"method":133,"deprecated":134},"List the grades a student can be registered with","\u002Fapi\u002Freference\u002Flist-grades",{"title":158,"to":159,"method":133,"deprecated":134},"Fetch one grade by its id","\u002Fapi\u002Freference\u002Fget-grade",{"title":161,"to":162,"method":133,"deprecated":134},"List the organizations and their ids","\u002Fapi\u002Freference\u002Flist-organizations",{"title":164,"to":165,"method":133,"deprecated":134},"Fetch one organization by its id","\u002Fapi\u002Freference\u002Fget-organization",{"tag":62,"slug":167,"links":168},"students",[169,172,175,178,181,184,187,191,194,197,200,203],{"title":170,"to":171,"method":133,"deprecated":134},"List your students","\u002Fapi\u002Freference\u002Flist-students",{"title":173,"to":174,"method":141,"deprecated":134},"Register a student","\u002Fapi\u002Freference\u002Fregister-student",{"title":176,"to":177,"method":141,"deprecated":134},"Check a registration without registering the student","\u002Fapi\u002Freference\u002Fcheck-student-registration",{"title":179,"to":180,"method":141,"deprecated":134},"Register many students at once","\u002Fapi\u002Freference\u002Fcreate-student-import",{"title":182,"to":183,"method":133,"deprecated":134},"Follow a batch of students you sent","\u002Fapi\u002Freference\u002Fget-student-import",{"title":185,"to":186,"method":133,"deprecated":134},"Fetch one of your students","\u002Fapi\u002Freference\u002Fget-student",{"title":188,"to":189,"method":190,"deprecated":134},"Update one of your students","\u002Fapi\u002Freference\u002Fupdate-student","PUT",{"title":192,"to":193,"method":190,"deprecated":134},"Set the sign-in password of one of your students","\u002Fapi\u002Freference\u002Fset-student-password",{"title":195,"to":196,"method":133,"deprecated":134},"List your students who can use this organization","\u002Fapi\u002Freference\u002Flist-org-students",{"title":198,"to":199,"method":133,"deprecated":134},"Fetch one of your students, if they can use this organization","\u002Fapi\u002Freference\u002Fget-org-student",{"title":201,"to":202,"method":190,"deprecated":134},"Update one of your students and give them access to this organization","\u002Fapi\u002Freference\u002Fupdate-org-student",{"title":204,"to":205,"method":190,"deprecated":134},"Link one of your students to a supervisor on this organization","\u002Fapi\u002Freference\u002Flink-student-supervisor",{"tag":80,"slug":207,"links":208},"sign-in-links",[209],{"title":210,"to":211,"method":141,"deprecated":134},"Create a single-use sign-in link for one of your students","\u002Fapi\u002Freference\u002Fcreate-signin-link",{"tag":83,"slug":213,"links":214},"exams",[215,218,221,224,227],{"title":216,"to":217,"method":133,"deprecated":134},"List the exams open for applications","\u002Fapi\u002Freference\u002Flist-exams",{"title":219,"to":220,"method":133,"deprecated":134},"List an organization’s exam categories","\u002Fapi\u002Freference\u002Flist-exam-categories",{"title":222,"to":223,"method":133,"deprecated":134},"Fetch one exam category","\u002Fapi\u002Freference\u002Fget-exam-category",{"title":225,"to":226,"method":133,"deprecated":134},"List the exams one of your students can apply to","\u002Fapi\u002Freference\u002Flist-available-exams",{"title":228,"to":229,"method":133,"deprecated":134},"Fetch one exam that is open for applications","\u002Fapi\u002Freference\u002Fget-exam",{"tag":86,"slug":231,"links":232},"applications",[233,236,239,242,245,248,251],{"title":234,"to":235,"method":133,"deprecated":134},"List your students’ applications in this organization","\u002Fapi\u002Freference\u002Flist-applications",{"title":237,"to":238,"method":141,"deprecated":134},"Enter one of your students for an exam","\u002Fapi\u002Freference\u002Fcreate-application",{"title":240,"to":241,"method":133,"deprecated":134},"List your students’ applications for one exam","\u002Fapi\u002Freference\u002Flist-exam-applications",{"title":243,"to":244,"method":133,"deprecated":134},"List one of your students’ applications in this organization","\u002Fapi\u002Freference\u002Flist-student-applications",{"title":246,"to":247,"method":133,"deprecated":134},"Fetch one of your students’ applications","\u002Fapi\u002Freference\u002Fget-application",{"title":249,"to":250,"method":190,"deprecated":134},"Move one of your students’ applications to another exam","\u002Fapi\u002Freference\u002Fmove-application",{"title":252,"to":253,"method":254,"deprecated":134},"Withdraw one of your students from an exam","\u002Fapi\u002Freference\u002Fdelete-application","DELETE",{"tag":256,"slug":257,"links":258},"Documents","documents",[259,262,265,268],{"title":260,"to":261,"method":133,"deprecated":134},"Download a certificate file","\u002Fapi\u002Freference\u002Fdownload-certificate",{"title":263,"to":264,"method":133,"deprecated":134},"List one of your students’ released certificates","\u002Fapi\u002Freference\u002Flist-student-certificates",{"title":266,"to":267,"method":133,"deprecated":134},"Download a result report file","\u002Fapi\u002Freference\u002Fdownload-report",{"title":269,"to":270,"method":133,"deprecated":134},"List one of your students’ released result reports","\u002Fapi\u002Freference\u002Flist-student-reports",{"tag":89,"slug":272,"links":273},"group-challenges",[274,277,280,283,286,289,292,295,298],{"title":275,"to":276,"method":133,"deprecated":134},"List the group challenges an organization runs","\u002Fapi\u002Freference\u002Flist-group-challenges",{"title":278,"to":279,"method":133,"deprecated":134},"Fetch one group challenge","\u002Fapi\u002Freference\u002Fget-group-challenge",{"title":281,"to":282,"method":133,"deprecated":134},"List the groups your students are in for a group challenge","\u002Fapi\u002Freference\u002Flist-group-challenge-groups",{"title":284,"to":285,"method":133,"deprecated":134},"Fetch one group, with its steps and files","\u002Fapi\u002Freference\u002Fget-group-challenge-group",{"title":287,"to":288,"method":133,"deprecated":134},"List what has happened in one group","\u002Fapi\u002Freference\u002Flist-group-challenge-activity",{"title":290,"to":291,"method":141,"deprecated":134},"Send a group’s finished work for one of your students","\u002Fapi\u002Freference\u002Fsubmit-group-challenge-work",{"title":293,"to":294,"method":141,"deprecated":134},"Submit one step of a group for one of your students","\u002Fapi\u002Freference\u002Fsubmit-group-challenge-step",{"title":296,"to":297,"method":133,"deprecated":134},"List your students’ eligibility and groups for a group challenge","\u002Fapi\u002Freference\u002Flist-group-challenge-students",{"title":299,"to":300,"method":133,"deprecated":134},"Fetch one of your students’ eligibility and group for a group challenge","\u002Fapi\u002Freference\u002Fget-group-challenge-student",{"id":302,"title":303,"links":304,"groups":316},"clients","Clients",[305,307,310,313],{"title":9,"to":306,"status":14},"\u002Fapi\u002Fclients",{"title":308,"to":309,"status":14},"Node.js","\u002Fapi\u002Fclients\u002Fnode",{"title":311,"to":312,"status":14},"PHP","\u002Fapi\u002Fclients\u002Fphp",{"title":314,"to":315,"status":14},"Build your own","\u002Fapi\u002Fclients\u002Fbuild-your-own",[],{"id":318,"title":319,"links":320,"groups":330},"agents","AI agents",[321,324,327],{"title":322,"to":323},"AI connections","\u002Fapi\u002Fmcp",{"title":325,"to":326},"What it can do","\u002Fapi\u002Fmcp\u002Ftools",{"title":328,"to":329},"Agent skills","\u002Fapi\u002Fskills",[],{"id":332,"title":333,"links":334,"groups":350},"help","Help",[335,338,341,344,347],{"title":336,"to":337,"status":14},"Glossary","\u002Fapi\u002Fglossary",{"title":339,"to":340,"status":14},"FAQ","\u002Fapi\u002Ffaq",{"title":342,"to":343,"status":14},"Troubleshooting","\u002Fapi\u002Ftroubleshooting",{"title":345,"to":346,"status":14},"Support","\u002Fapi\u002Fsupport",{"title":348,"to":349},"Changelog","\u002Fapi\u002Fchangelog",[],[352,384,396,427,446],{"path":353,"version":354,"date":355,"breaking":134,"summary":356,"description":357,"changes":358,"longForm":383,"preview":134},"\u002Fapi\u002Fchangelog\u002F1-2-0","1.2.0","2026-10-01","Nine new operations under one new tag, Group challenges, behind two new permissions, group-challenge\u002Fread and group-challenge\u002Fsubmit. Nothing that worked against 1.1.1 changes.","Follow your students through an organization's group challenges, and submit their steps and their group's finished work for them.",[359,371,376,380],{"type":360,"breaking":134,"text":361,"operations":362},"added","Group challenges, a new resource under `\u002Fv1\u002F{organizationId}\u002Fgroup-challenge` with the tag \"Group challenges\" and the permission `group-challenge\u002Fread` (also granted by `*\u002Fread`, `*\u002F*` and `*`): `listGroupChallenges` and `getGroupChallenge` read the challenges an organization runs; `listGroupChallengeStudents` and `getGroupChallengeStudent` say where each of your students stands (eligible by grade, in a group, the group's state) and give the `panelPath` to send them to with `createSigninLink`; `listGroupChallengeGroups` and `getGroupChallengeGroup` read the groups your students are in, with each step and its files; `listGroupChallengeActivity` lists what happened in a group. Only your own students are named: every other person is their role alone. The operations answer `404` on an organization where group challenges are not switched on.",[363,364,365,366,367,368,369,370],"listGroupChallenges","getGroupChallenge","listGroupChallengeStudents","getGroupChallengeStudent","createSigninLink","listGroupChallengeGroups","getGroupChallengeGroup","listGroupChallengeActivity",{"type":360,"breaking":134,"text":372,"operations":373},"Submitting group challenge work for one of your students, behind the new permission `group-challenge\u002Fsubmit` (also granted by `*\u002F*` and `*`, not by `*\u002Fread`): `submitGroupChallengeStep` submits a group's open step and opens the next, and `submitGroupChallengeWork` sends the group's finished work and e-mails its members and teacher. Both take `{ \"studentId\": \"\u003CstudentId>\" }`, a student of yours who is an active member of the group, and are recorded in the group's history as your account acting for them. Repeating a submit that already happened answers `200` with `changed: false`.",[374,375],"submitGroupChallengeStep","submitGroupChallengeWork",{"type":377,"breaking":134,"text":378,"operations":379},"changed","`submitGroupChallengeStep` and `submitGroupChallengeWork` are the first operations whose `409 conflict` carries `error.details.reason` (`challenge_closed`, `window_closed`, `payment_pending`, `group_not_confirmed`, `step_locked`, `step_empty`, `steps_incomplete`), and whose `503 service_unavailable` carries `details.reason: busy` with `Retry-After: 1` when the group is being changed by someone else. The error reference for both codes says so.",[374,375],{"type":377,"breaking":134,"text":381,"operations":382},"The agent kit has a seventh skill, `following-group-challenges-via-api`: reading where your students stand with `listGroupChallengeStudents` and `getGroupChallengeGroup` before submitting with `submitGroupChallengeStep` or `submitGroupChallengeWork`, never looping on a `409`, and sending a student to a challenge with `createSigninLink` and `panelPath`.",[365,369,374,375,367],true,{"path":385,"version":386,"date":387,"breaking":134,"summary":388,"description":389,"changes":390,"longForm":383,"preview":134},"\u002Fapi\u002Fchangelog\u002F1-1-1","1.1.1","2026-09-18","A documentation release. The published agent kit now carries six skills instead of two, including one written against bulk registration, and none of them describes anything but this API. Every call that worked against 1.1.0 works unchanged.","The agent kit grows from two skills to six, all of them about this REST API. No operation, field, permission or error code changed.",[391],{"type":377,"breaking":134,"text":392,"operations":393},"The agent kit published at https:\u002F\u002Fhub.main-team.org\u002Fapi\u002Fskills now has six skills instead of two, all of them about this REST API: `integrating-main-team-api` (tokens, the envelopes, pagination, rate limits, retries and idempotency, polling, every error code), `registering-a-main-team-student`, `registering-main-team-students-from-spreadsheets`, `enrolling-students-in-olympiad-exams-via-api`, `downloading-results-and-certificates-via-api` and `managing-api-access-and-tokens`. The spreadsheet skill is now written against `createStudentImport` and `getStudentImport`: it builds one request body of 30 to 1000 rows, reads the `422` row list, and polls the import until it has succeeded or failed. Nothing in the kit describes the MCP server, which is a separate service. No operation, field, permission or error code changed.",[394,395],"createStudentImport","getStudentImport",{"path":397,"version":398,"date":399,"breaking":134,"summary":400,"description":401,"changes":402,"longForm":383,"preview":134},"\u002Fapi\u002Fchangelog\u002F1-1-0","1.1.0","2026-09-17","Three new operations — bulk registration, its status, and a registration pre-check — with an email filter on listStudents, a signedIn field and filter on listOrgStudents, and an optional details object on error bodies. Nothing that worked against 1.0.1 changes.","Register a whole class in one request, check a registration before you send it, and filter your student lists by email address and by sign-in.",[403,407,410,413,417,421],{"type":360,"breaking":134,"text":404,"operations":405},"`createStudentImport`: `POST \u002Fv1\u002Fstudent\u002Fimport` registers 30 to 1000 students in one request. Every row follows `registerStudent`'s rules and takes everything it takes except `password`, plus an optional `externalRef` of your own that is echoed back. The whole batch is checked before anything is queued; the answer is `202` with the import and a `Location` header, and the students are registered in the background. **They are written in one transaction: a batch registers every row or registers nothing**, so there is no partial import to reconcile. Each student gets the same welcome email `registerStudent` sends. Limits: one unfinished import per account (`409` otherwise), 10 requests an hour, and bodies up to 1.5 MB on this operation where every other takes 100 kB. Sending the same rows again inside 24 hours answers with the import you already have rather than a second one. It needs `student\u002Fcreate` on `mto`, the permission registration needs.",[394,406],"registerStudent",{"type":360,"breaking":134,"text":408,"operations":409},"`getStudentImport`: `GET \u002Fv1\u002Fstudent\u002Fimport\u002F{importId}` returns one of your imports and one page of its rows, with `page` and `limit`. `status` is `queued`, `running`, `succeeded`, `failed` or `cancelled`; on `succeeded` every row carries the student's `_id`, and on anything else no student of that batch was registered. An import stops being readable 30 days after it finishes and then answers `404`, as does one another account sent. It needs `student\u002Fcreate` on `mto`.",[395],{"type":360,"breaking":134,"text":411,"operations":412},"Error bodies may carry an optional `details` object, and `createStudentImport` is the first operation to send one: its `422` puts every row it cannot register in `error.details.rows`, each with its position, the property at fault and a code to branch on. Ignore a `details` you do not recognise; no other operation sends one.",[394],{"type":360,"breaking":134,"text":414,"operations":415},"`checkStudentRegistration`: `POST \u002Fv1\u002Fstudent\u002Fcheck` runs the checks `registerStudent` makes before it creates anything, on the same body without `password`, and answers `200` with what they found: `valid`; every `country`, `grade`, `city` or `school` that matches nothing, with the message registration would refuse it with; the `_id` each reference resolves to; and whether one of your students already has the email address, with that student's `_id`. Nothing is created and no username is issued. It needs `student\u002Fcreate` on `mto`, the permission registration needs. Only your own students are checked for the address, so an address a student on another account holds is still refused by `registerStudent` alone.",[416,406],"checkStudentRegistration",{"type":360,"breaking":134,"text":418,"operations":419},"`listStudents`: an optional `email` query parameter lists only your students who have one of up to 100 addresses, separated by commas, matched exactly and without regard to case. A value that is not such a list is refused with `400 bad_request`.",[420],"listStudents",{"type":360,"breaking":134,"text":422,"operations":423},"`listOrgStudents`: each student carries `signedIn`, whether they have signed in to that organization at least once, and an optional `signedIn` query parameter, `true` or `false`, lists only the students who have or only those who have not. Any other value is refused with `400 bad_request`. `createApplication` and `linkStudentSupervisor` on an organization need the student to have signed in there once.",[424,425,426],"listOrgStudents","createApplication","linkStudentSupervisor",{"path":428,"version":429,"date":430,"breaking":134,"summary":431,"description":432,"changes":433,"longForm":383,"preview":134},"\u002Fapi\u002Fchangelog\u002F1-0-1","1.0.1","2026-09-15","The sandbox is live and the contract names it as a second server, and the panel now requires students to confirm their email address. No operation, field or error code changes.","The sandbox is live, with test payments and the Try it console, and the panel now asks students to confirm their email address before they use it.",[434,437,440,443],{"type":360,"breaking":134,"text":435,"operations":436},"The contract's server list names the sandbox, `https:\u002F\u002Fapisnd.main-team.org`, after production, marked `x-environment: sandbox`. Production stays the first entry, so a tool that takes the first server still calls production. No operation changes.",[],{"type":377,"breaking":134,"text":438,"operations":439},"The sandbox is live at `https:\u002F\u002Fapisnd.main-team.org\u002Fv1`. It runs the same release as production, with separate accounts issued by an operator, seeded reference data with production's organization ids, no emails and test-mode payments. Registration is open there, with the same permissions and rate limits as in production. The official client libraries accept only the production base URL, so call the sandbox over HTTPS directly. The \"Try it\" console on the reference pages works against the sandbox with a token you paste. Students pay in the sandbox's panels with Stripe's test cards, such as 4242 4242 4242 4242; the Environments page lists them. Test cards never work in production.",[],{"type":377,"breaking":134,"text":441,"operations":442},"`createSigninLink`: a student whose email address is not confirmed must now confirm it before they can use the panel, My Exams included, so they confirm before they can start an exam. The panel asks for a 6-digit code on every page until the address is confirmed, and the student can no longer put it off; signing out is the only way out. A student already inside an exam room is not interrupted. Only the confirmation on the student's core record counts. A code is valid for 15 minutes, and a new one can be requested after 60 seconds. The sandbox sends no emails, so its panels don't ask. Have your students confirm well before an exam day, for example right after their first sign-in. The request, its answers and the link are unchanged.",[367],{"type":377,"breaking":134,"text":444,"operations":445},"Documentation corrections: the pages that called the sandbox planned now describe it as it runs, and every page that called the panel's email confirmation prompt optional now describes it as required. The pages no longer write a current version number into their text: the API reference shows the version they describe, and the changelog lists every version.",[],{"path":447,"version":448,"date":430,"breaking":134,"summary":449,"description":450,"changes":451,"longForm":383,"preview":134},"\u002Fapi\u002Fchangelog\u002F1-0-0","1.0.0","Initial release of the v1 partner API, with 35 operations for students, sign-in links, exams, applications, certificates and reports.","The first release of the Main Team API. Every operation, and the behaviors your integration can rely on from the start.",[452,456,461,470,478,481,489,498,505,508,511,514,517,520,523,526,529,532,535,538,541,544,547],{"type":360,"breaking":134,"text":453,"operations":454},"Health: `getHealth`.",[455],"getHealth",{"type":360,"breaking":134,"text":457,"operations":458},"API account: `getCurrentApiAccount`, `revokeToken`.",[459,460],"getCurrentApiAccount","revokeToken",{"type":360,"breaking":134,"text":462,"operations":463},"Reference data: `listCountries`, `getCountry`, `listGrades`, `getGrade`, `listOrganizations`, `getOrganization`.",[464,465,466,467,468,469],"listCountries","getCountry","listGrades","getGrade","listOrganizations","getOrganization",{"type":360,"breaking":134,"text":471,"operations":472},"Students: `listStudents`, `getStudent`, `registerStudent`, `updateStudent`, `setStudentPassword`, `listOrgStudents`, `getOrgStudent`, `updateOrgStudent`, `linkStudentSupervisor`.",[420,473,406,474,475,424,476,477,426],"getStudent","updateStudent","setStudentPassword","getOrgStudent","updateOrgStudent",{"type":360,"breaking":134,"text":479,"operations":480},"Sign-in links: `createSigninLink`.",[367],{"type":360,"breaking":134,"text":482,"operations":483},"Exams: `listExamCategories`, `getExamCategory`, `listExams`, `listAvailableExams`, `getExam`.",[484,485,486,487,488],"listExamCategories","getExamCategory","listExams","listAvailableExams","getExam",{"type":360,"breaking":134,"text":490,"operations":491},"Applications: `listApplications`, `listExamApplications`, `listStudentApplications`, `getApplication`, `createApplication`, `moveApplication`, `deleteApplication`.",[492,493,494,495,425,496,497],"listApplications","listExamApplications","listStudentApplications","getApplication","moveApplication","deleteApplication",{"type":360,"breaking":134,"text":499,"operations":500},"Documents: `listStudentCertificates`, `downloadCertificate`, `listStudentReports`, `downloadReport`.",[501,502,503,504],"listStudentCertificates","downloadCertificate","listStudentReports","downloadReport",{"type":360,"breaking":134,"text":506,"operations":507},"Authentication with self-signed HS256 tokens, where `kid` and `sub` are the apiKey, and `iat` and `exp` are required with a lifetime of at most 3600 seconds and 30 seconds of clock tolerance. Every authentication failure answers the same `401 unauthorized`.",[],{"type":360,"breaking":134,"text":509,"operations":510},"Permissions by role, checked against the organization each request acts on. An operation with no permission granted answers `403 forbidden`.",[],{"type":360,"breaking":134,"text":512,"operations":513},"Response envelopes: `{ success, message, data, pagination? }` on success, and `{ error: { code, message, documentation_url, request_id } }` on failure, with an `X-Request-Id` header on every response. `documentation_url` is the code's entry on the partner documentation, `https:\u002F\u002Fhub.main-team.org\u002Fapi\u002Ferrors#\u003Ccode>`.",[],{"type":360,"breaking":134,"text":515,"operations":516},"Pagination with `page` (default 1) and `limit` (default 20, at most 100).",[],{"type":360,"breaking":134,"text":518,"operations":519},"A rate limit of 100 requests per 60 seconds for each account and each operation, with `Retry-After` and `X-RateLimit-*` headers. Each operation has its own budget. Going over answers `429 too_many_requests` with the message \"Too many requests to this operation. Wait the number of seconds in Retry-After, then try again.\"",[],{"type":360,"breaking":134,"text":521,"operations":522},"`createSigninLink`: sign-in links that are valid for 120 seconds and work once, for a student with access to that organization.",[367],{"type":360,"breaking":134,"text":524,"operations":525},"`getStudent`, `getOrgStudent`, `getCountry`, `getGrade`, `getOrganization` and `getExamCategory` answer `404 not_found` for an id they cannot show, as every single read does. A student of another account answers like a missing one.",[473,476,465,467,469,485],{"type":360,"breaking":134,"text":527,"operations":528},"`getApplication`, `moveApplication` and `deleteApplication` answer `404` with \"Application not found!\" alike for a missing application and one of another account's student.",[495,496,497],{"type":360,"breaking":134,"text":530,"operations":531},"`listOrganizations` and `getOrganization` serve the five organizations that run exams: `stem`, `hilingua`, `neo`, `gmath` and `coding`. On every operation with `organizationId` in its path, the id of any other organization, `mto`'s included, answers `404 not_found` with \"Organization not found!\", as an id that names no organization does.",[468,469],{"type":360,"breaking":134,"text":533,"operations":534},"`getCurrentApiAccount` returns the account's `roles`, each with `effect`, `action`, `target` and, when set, `authorized`, to compare with an operation's `x-permission`.",[459],{"type":360,"breaking":134,"text":536,"operations":537},"`registerStudent` requires `firstName`, `lastName`, `email`, `birth`, `sex`, `country`, `grade`, `city` and `school`, with `birth` a date that exists, as DD\u002FMM\u002FYYYY, and names a missing field in its `400` (\"lastName should not be empty\"). `updateStudent` and `updateOrgStudent` hold the fields they are sent to the same rules, and refuse `null` for `firstName`, `lastName`, `birth`, `sex` and `phone`. `registerStudent` refuses a `null` `phone` too.",[406,474,477],{"type":360,"breaking":134,"text":539,"operations":540},"`activatedPlatformsThisSeason` on `registerStudent`, `updateStudent` and `updateOrgStudent` takes `common`, `stem`, `hilingua`, `neo`, `gmath` and `coding`. The two updates add to the student's list and never remove from it. `updateOrgStudent` without the field, even with an empty body, adds its own organization, unless the list already holds `common`. All three refuse `null` for it with `400`; `registerStudent` without it stores `[\"common\"]`.",[406,474,477],{"type":360,"breaking":134,"text":542,"operations":543},"Passwords: a `password` at `registerStudent`, and `setStudentPassword`, need `auth\u002Fsignin` on `mto`. A password is 5 characters to 72 bytes and contains none of the student's own details. `setStudentPassword` answers `409` once the student has confirmed their email address.",[406,475],{"type":360,"breaking":134,"text":545,"operations":546},"`linkStudentSupervisor` answers every refusal with the same `404` \"Not found!\".",[426],{"type":360,"breaking":134,"text":548,"operations":549},"`createApplication` is safe to repeat: the same student and exam answer `200` with the existing application.",[425],1791554614805]