[{"data":1,"prerenderedAt":1394},["ShallowReactive",2],{"api-nav":3,"api-guide:\u002Fapi\u002Fenvironments":351,"api-spec:guide:\u002Fapi\u002Fenvironments":1389},[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",[],{"id":352,"title":16,"body":353,"description":1379,"extension":1380,"meta":1381,"navTitle":16,"navigation":1382,"operations":1383,"order":1385,"path":17,"section":5,"seo":1386,"status":14,"stem":1387,"__hash__":1388},"apiGuides\u002Fapi\u002Fenvironments.md",{"type":354,"value":355,"toc":1363},"minimark",[356,360,365,423,451,454,499,509,512,515,531,544,555,557,560,698,709,712,715,782,786,789,796,840,848,853,857,864,884,888,891,914,919,923,941,948,952,1071,1076,1080,1086,1104,1168,1171,1181,1264,1269,1273,1280,1284,1296,1300,1311,1335,1340,1343,1359],[357,358,359],"p",{},"The API has two live environments: production, and a sandbox for building and testing your integration. This page covers both, explains how to reach the API (HTTPS, from your servers only), and shows how to monitor it.",[361,362,364],"h2",{"id":363},"base-urls","Base URLs",[366,367,368,387],"table",{},[369,370,371],"thead",{},[372,373,374,378,381,384],"tr",{},[375,376,377],"th",{},"Environment",[375,379,380],{},"Base URL",[375,382,383],{},"Status",[375,385,386],{},"Use it for",[388,389,390,408],"tbody",{},[372,391,392,396,402,405],{},[393,394,395],"td",{},"Production",[393,397,398],{},[399,400,401],"code",{},"https:\u002F\u002Fapi.main-team.org\u002Fv1",[393,403,404],{},"Available",[393,406,407],{},"Real students, real exams, real results",[372,409,410,413,418,420],{},[393,411,412],{},"Sandbox",[393,414,415],{},[399,416,417],{},"https:\u002F\u002Fapisnd.main-team.org\u002Fv1",[393,419,404],{},[393,421,422],{},"Building and testing your integration without touching real data",[357,424,425,426,429,430,432,433,436,437,440,441,443,444,447,448,450],{},"Every API route is under ",[399,427,428],{},"\u002Fv1",". The version is part of the path, so ",[399,431,428],{}," stays stable until a future major version, and a new major version would get a new prefix. The bare host, ",[399,434,435],{},"https:\u002F\u002Fapi.main-team.org\u002F",", answers ",[399,438,439],{},"404 not_found",", as does any path under ",[399,442,428],{}," that is not a route. See ",[445,446,54],"a",{"href":55}," for what can change within ",[399,449,428],{},".",[357,452,453],{},"Keep the base URL in configuration, not in code, so that moving between environments only means changing a setting:",[455,456,461],"pre",{"className":457,"code":458,"language":459,"meta":460,"style":460},"language-bash shiki shiki-themes github-light-high-contrast github-dark-high-contrast","# production\nMTO_API_BASE=https:\u002F\u002Fapi.main-team.org\u002Fv1\n# sandbox\n# MTO_API_BASE=https:\u002F\u002Fapisnd.main-team.org\u002Fv1\n","bash","",[399,462,463,472,487,493],{"__ignoreMap":460},[464,465,468],"span",{"class":466,"line":467},"line",1,[464,469,471],{"class":470},"sLBg1","# production\n",[464,473,475,479,483],{"class":466,"line":474},2,[464,476,478],{"class":477},"suds8","MTO_API_BASE",[464,480,482],{"class":481},"sHUrx","=",[464,484,486],{"class":485},"sT6z2","https:\u002F\u002Fapi.main-team.org\u002Fv1\n",[464,488,490],{"class":466,"line":489},3,[464,491,492],{"class":470},"# sandbox\n",[464,494,496],{"class":466,"line":495},4,[464,497,498],{"class":470},"# MTO_API_BASE=https:\u002F\u002Fapisnd.main-team.org\u002Fv1\n",[357,500,501,502,505,506,450],{},"The official ",[445,503,504],{"href":306},"client libraries"," accept only the production base URL. To call the sandbox, send plain HTTPS requests, or use a client of your own such as the one in ",[445,507,508],{"href":315},"Build your own client",[361,510,395],{"id":511},"production",[357,513,514],{},"Production is the live platform. Every request acts on real data:",[516,517,518,522,525,528],"ul",{},[519,520,521],"li",{},"A student you register is a real account on the platform.",[519,523,524],{},"A sign-in link you mint signs a real browser in as that student.",[519,526,527],{},"An application you create enters a real student for a real exam session.",[519,529,530],{},"Certificates and reports are the students' real results.",[357,532,533,534,538,539,543],{},"There is no test mode and no \"dry run\" flag in production. The API has no route that deletes a student, so a student registered by mistake stays registered. Build and test your integration against the ",[445,535,537],{"href":536},"#sandbox","sandbox"," first. When you move to production, agree your first writes with us (",[445,540,542],{"href":541},"mailto:info@main-team.org","info@main-team.org","). For example, use one agreed test student rather than inventing new ones on every run.",[545,546,548],"callout",{"type":547},"warn",[357,549,550,551,554],{},"Do not point automated tests or CI pipelines at production. Read-only checks, such as ",[399,552,553],{},"validate-me"," or listing organizations, are safe. Anything that registers students or creates applications is not: run it against the sandbox.",[361,556,412],{"id":537},[357,558,559],{},"The sandbox is a separate copy of the platform for integration work. It runs the same release of the API as production and follows each production release. It has its own data and holds no real students, and nothing you do there reaches production.",[366,561,562,572],{},[369,563,564],{},[372,565,566,568,570],{},[375,567],{},[375,569,395],{},[375,571,412],{},[388,573,574,586,599,610,624,638,649,664,676,687],{},[372,575,576,578,582],{},[393,577,380],{},[393,579,580],{},[399,581,401],{},[393,583,584],{},[399,585,417],{},[372,587,588,591,594],{},[393,589,590],{},"Accounts",[393,592,593],{},"Issued by an operator on request",[393,595,596,597],{},"Separate accounts, issued by an operator from the sandbox's own panel. Ask at ",[445,598,542],{"href":541},[372,600,601,604,607],{},[393,602,603],{},"Credentials",[393,605,606],{},"Work only in production",[393,608,609],{},"Work only in the sandbox",[372,611,612,614,617],{},[393,613,74],{},[393,615,616],{},"Real countries, grades, organizations and exams",[393,618,619,620,623],{},"Seeded reference data. The organization ",[399,621,622],{},"_id","s are the same as in production; there may be fewer exams",[372,625,626,628,631],{},[393,627,62],{},[393,629,630],{},"Real students",[393,632,633,634,637],{},"Only students registered for testing. Registration (",[399,635,636],{},"POST \u002Fv1\u002Fstudent",") is open, with the same permissions as in production",[372,639,640,643,646],{},[393,641,642],{},"Emails",[393,644,645],{},"Real emails can be sent by the platform",[393,647,648],{},"No emails are sent",[372,650,651,654,657],{},[393,652,653],{},"Payments",[393,655,656],{},"Real cards, real money",[393,658,659,660],{},"Stripe test mode: test cards only, no real money moves. See ",[445,661,663],{"href":662},"#test-payments","Test payments",[372,665,666,668,673],{},[393,667,45],{},[393,669,670,671],{},"See ",[445,672,45],{"href":46},[393,674,675],{},"The same as production",[372,677,678,681,684],{},[393,679,680],{},"\"Try it\" console on the reference pages",[393,682,683],{},"Not available",[393,685,686],{},"Available, with a token you paste",[372,688,689,692,695],{},[393,690,691],{},"Official client libraries",[393,693,694],{},"Supported",[393,696,697],{},"Not supported: call the sandbox over HTTPS directly",[357,699,700,701,704,705,708],{},"A production key does not work in the sandbox, and a sandbox key does not work in production. Mixing them up gives the usual ",[399,702,703],{},"401 unauthorized"," (see ",[445,706,19],{"href":707},"\u002Fapi\u002Fauthentication#the-401-checklist","), so check that your key and your base URL come from the same environment.",[357,710,711],{},"The routes, the request and response formats, the token rules, the permission model and the organization ids are the same in both environments, so code written against the sandbox needs only a new base URL and new credentials to run in production.",[357,713,714],{},"What to know when you test there:",[516,716,717,724,742,764,770,776],{},[519,718,719,723],{},[720,721,722],"strong",{},"Use invented details."," Every student in the sandbox is a test student. Don't enter real people's names or email addresses.",[519,725,726,729,730,733,734,737,738,450],{},[720,727,728],{},"No emails arrive."," Nothing reaches a mailbox, including the 6-digit code the panel uses to confirm a student's email address. So the sandbox's panels don't ask students to confirm their address, and ",[399,731,732],{},"emailConfirmed"," stays ",[399,735,736],{},"false"," for the students you register there. See ",[445,739,741],{"href":740},"\u002Fapi\u002Fguides\u002Fsign-in-links#email-confirmation","Email confirmation",[519,743,744,747,748,751,752,755,756,759,760,763],{},[720,745,746],{},"Sign-in links open the sandbox's panels."," A link you mint in the sandbox opens on ",[399,749,750],{},"authsnd.main-team.org"," and signs the student in to the organization's sandbox panel, never to production's. A sandbox panel is at ",[399,753,754],{},"snd.\u003Cbrand>.org"," where production's is ",[399,757,758],{},"my.\u003Cbrand>.org",", for example ",[399,761,762],{},"snd.stemolympiad.org",". Open it in a separate browser profile from any production session.",[519,765,766,769],{},[720,767,768],{},"The same rate limits."," 100 requests per 60 seconds per account and per operation, as in production, and the same limit per client address in front of the API. Don't load-test the sandbox; ask us if you need to measure throughput.",[519,771,772,775],{},[720,773,774],{},"The data may be reset."," A reset removes the students and applications created since the last one. We tell you in advance.",[519,777,778,781],{},[720,779,780],{},"No availability guarantee."," The sandbox can be briefly unavailable, for example while it is updated.",[783,784,663],"h3",{"id":785},"test-payments",[357,787,788],{},"The API never charges anyone. When an exam has a price, the student pays for the application in the organization's panel, by card. The sandbox's panels take these payments through Stripe in test mode, so no real money moves and no real card is charged.",[357,790,791,792,795],{},"To test a payment, create an application for an exam with a price, send the student to the panel with a ",[445,793,794],{"href":81},"sign-in link",", and pay with one of Stripe's test cards:",[366,797,798,808],{},[369,799,800],{},[372,801,802,805],{},[375,803,804],{},"Card number",[375,806,807],{},"What happens",[388,809,810,820,830],{},[372,811,812,817],{},[393,813,814],{},[399,815,816],{},"4242 4242 4242 4242",[393,818,819],{},"The payment succeeds without authentication",[372,821,822,827],{},[393,823,824],{},[399,825,826],{},"4000 0025 0000 3155",[393,828,829],{},"The payment asks for 3D Secure authentication first",[372,831,832,837],{},[393,833,834],{},[399,835,836],{},"4000 0000 0000 9995",[393,838,839],{},"The payment is declined for insufficient funds",[357,841,842,843,450],{},"With each card, enter any future expiry date, any 3-digit CVC and any postal code. The panel takes payment by card only, on Stripe's checkout page, so a test card is all you need. Stripe lists more test cards, for other declines and authentication cases, at ",[445,844,845],{"href":845,"rel":846},"https:\u002F\u002Fdocs.stripe.com\u002Ftesting",[847],"nofollow",[545,849,850],{"type":547},[357,851,852],{},"Test cards are for the sandbox. In production only real cards work and every payment is real, so never use a test card there.",[783,854,856],{"id":855},"the-try-it-console","The \"Try it\" console",[357,858,859,860,863],{},"The reference pages have an interactive \"Try it\" console. It sends requests ",[720,861,862],{},"only to the sandbox",". It never calls production: the production API accepts no requests from browser pages (see below), and you should never paste production credentials into a web page anyway.",[357,865,866,867,869,870,873,874,877,878,880,881,883],{},"To use it, sign a token with your ",[720,868,537],{}," ",[399,871,872],{},"apiKey"," and ",[399,875,876],{},"apiSecret"," on your own machine (see ",[445,879,19],{"href":20},") and paste the token. Never paste your ",[399,882,876],{},": the console refuses anything that looks like one and sends nothing. The token is kept only in the page's memory, never stored.",[361,885,887],{"id":886},"call-the-api-from-your-servers","Call the API from your servers",[357,889,890],{},"The API is for server-to-server use.",[516,892,893,902,908],{},[519,894,895,898,899,901],{},[720,896,897],{},"No browser calls."," Production sends no CORS headers, so a web page served from another origin cannot call the API. This is on purpose. A browser integration would need your ",[399,900,876],{}," in the page, which hands it to every visitor. The sandbox accepts browser requests from one origin only, these documentation pages, for the \"Try it\" console.",[519,903,904,907],{},[720,905,906],{},"No mobile or desktop apps."," For the same reason, never put credentials in an app you distribute. Anything shipped to users can be extracted.",[519,909,910,913],{},[720,911,912],{},"Put your own backend in between."," Your web or mobile front end talks to your server; your server holds the secret, signs tokens and calls the API.",[357,915,916,917,450],{},"When a student needs to reach their panel, your server mints a sign-in link and redirects the browser to it. The browser never sees your token. See ",[445,918,80],{"href":81},[361,920,922],{"id":921},"https-only","HTTPS only",[357,924,925,926,929,930,933,934,937,938,940],{},"Always use ",[399,927,928],{},"https:\u002F\u002F",", and never send a request to ",[399,931,932],{},"http:\u002F\u002F",". A request sent over plain HTTP has already carried your ",[399,935,936],{},"Authorization"," header across the network unencrypted, whatever the server does next. Put ",[399,939,928],{}," in your base URL and do not let your HTTP client follow redirects to other hosts.",[357,942,943,944,947],{},"Responses carry ",[399,945,946],{},"Strict-Transport-Security",", so browsers and clients that honor it stay on HTTPS for this host.",[361,949,951],{"id":950},"response-headers-to-know","Response headers to know",[366,953,954,967],{},[369,955,956],{},[372,957,958,961,964],{},[375,959,960],{},"Header",[375,962,963],{},"When",[375,965,966],{},"Meaning",[388,968,969,990,1015,1030,1054],{},[372,970,971,976,979],{},[393,972,973],{},[399,974,975],{},"X-Request-Id",[393,977,978],{},"Every response",[393,980,981,982,985,986,989],{},"The id of this request. Send your own (letters, digits and ",[399,983,984],{},"._:;=+\u002F@-",", 1 to 256 characters) to have it reused; a value with any other character, or a longer one, is replaced. Without one, an id is generated for you. Treat it as an opaque string, because the format of a generated id can vary. It also appears as ",[399,987,988],{},"error.request_id"," in error bodies. Log it.",[372,991,992,1004,1010],{},[393,993,994,997,998,997,1001],{},[399,995,996],{},"X-RateLimit-Limit",", ",[399,999,1000],{},"X-RateLimit-Remaining",[399,1002,1003],{},"X-RateLimit-Reset",[393,1005,1006,1007],{},"Every request counted against your rate limit, except a ",[399,1008,1009],{},"429",[393,1011,1012,1013],{},"Your budget on this operation: the limit, what is left, and the seconds until the window resets. See ",[445,1014,45],{"href":46},[372,1016,1017,1022,1027],{},[393,1018,1019],{},[399,1020,1021],{},"Retry-After",[393,1023,1024,1026],{},[399,1025,1009],{}," only",[393,1028,1029],{},"The number of seconds to wait before you send again. A request sent sooner is refused too",[372,1031,1032,1037,1040],{},[393,1033,1034],{},[399,1035,1036],{},"Content-Type",[393,1038,1039],{},"Every response with a body",[393,1041,1042,1045,1046,1049,1050,1053],{},[399,1043,1044],{},"application\u002Fjson; charset=utf-8"," for JSON. Certificate and report downloads carry the file's own type (normally ",[399,1047,1048],{},"application\u002Fpdf","), or ",[399,1051,1052],{},"application\u002Foctet-stream"," when none is recorded",[372,1055,1056,1061,1064],{},[393,1057,1058],{},[399,1059,1060],{},"Content-Disposition",[393,1062,1063],{},"Downloads",[393,1065,1066,1067,1070],{},"The file name. Prefer its ",[399,1068,1069],{},"filename*=UTF-8''…"," form",[357,1072,1073,1074,450],{},"Details on request ids, bodies and envelopes are in ",[445,1075,33],{"href":34},[361,1077,1079],{"id":1078},"monitoring-get-v1health","Monitoring: GET \u002Fv1\u002Fhealth",[357,1081,1082,1085],{},[399,1083,1084],{},"GET \u002Fv1\u002Fhealth"," tells you whether the API is up. It needs no token and does not count against any account's rate limit. The network in front of the API still limits how fast each client address may send requests, with or without a token, so poll at a steady interval, such as once a minute, not in a tight loop.",[455,1087,1089],{"className":457,"code":1088,"language":459,"meta":460,"style":460},"curl -s https:\u002F\u002Fapi.main-team.org\u002Fv1\u002Fhealth\n",[399,1090,1091],{"__ignoreMap":460},[464,1092,1093,1097,1101],{"class":466,"line":467},[464,1094,1096],{"class":1095},"soyes","curl",[464,1098,1100],{"class":1099},"s-5SL"," -s",[464,1102,1103],{"class":485}," https:\u002F\u002Fapi.main-team.org\u002Fv1\u002Fhealth\n",[455,1105,1109],{"className":1106,"code":1107,"language":1108,"meta":460,"style":460},"language-json shiki shiki-themes github-light-high-contrast github-dark-high-contrast","{\n  \"success\": true,\n  \"message\": \"Request completed successfully.\",\n  \"data\": { \"status\": \"ok\" }\n}\n","json",[399,1110,1111,1116,1131,1143,1162],{"__ignoreMap":460},[464,1112,1113],{"class":466,"line":467},[464,1114,1115],{"class":477},"{\n",[464,1117,1118,1122,1125,1128],{"class":466,"line":474},[464,1119,1121],{"class":1120},"sne4z","  \"success\"",[464,1123,1124],{"class":477},": ",[464,1126,1127],{"class":1099},"true",[464,1129,1130],{"class":477},",\n",[464,1132,1133,1136,1138,1141],{"class":466,"line":489},[464,1134,1135],{"class":1120},"  \"message\"",[464,1137,1124],{"class":477},[464,1139,1140],{"class":485},"\"Request completed successfully.\"",[464,1142,1130],{"class":477},[464,1144,1145,1148,1151,1154,1156,1159],{"class":466,"line":495},[464,1146,1147],{"class":1120},"  \"data\"",[464,1149,1150],{"class":477},": { ",[464,1152,1153],{"class":1120},"\"status\"",[464,1155,1124],{"class":477},[464,1157,1158],{"class":485},"\"ok\"",[464,1160,1161],{"class":477}," }\n",[464,1163,1165],{"class":466,"line":1164},5,[464,1166,1167],{"class":477},"}\n",[357,1169,1170],{},"Treat any other status code, or no response within a few seconds, as \"down\".",[357,1172,1173,1176,1177,1180],{},[399,1174,1175],{},"\u002Fv1\u002Fhealth"," only checks that the service is running. It does not check your credentials, your roles or the data behind the routes. To check your integration end to end, also make one authenticated call on a schedule, for example ",[399,1178,1179],{},"GET \u002Fv1\u002Fapi-account\u002Fvalidate-me"," every few minutes:",[366,1182,1183,1193],{},[369,1184,1185],{},[372,1186,1187,1190],{},[375,1188,1189],{},"Check",[375,1191,1192],{},"What a failure means",[388,1194,1195,1208,1225,1243],{},[372,1196,1197,1205],{},[393,1198,1199,1201,1202],{},[399,1200,1084],{}," is not ",[399,1203,1204],{},"200",[393,1206,1207],{},"The API is down or unreachable from your network",[372,1209,1210,1218],{},[393,1211,1212,1214,1215],{},[399,1213,553],{}," is ",[399,1216,1217],{},"401",[393,1219,1220,1221,1224],{},"Your token, secret, clock or account is the problem (see ",[445,1222,1223],{"href":707},"the 401 checklist",")",[372,1226,1227,1234],{},[393,1228,1229,1214,1231],{},[399,1230,553],{},[399,1232,1233],{},"403",[393,1235,1236,1237,1240,1241,1224],{},"Your account lost the ",[399,1238,1239],{},"api\u002F*"," role (see ",[445,1242,25],{"href":26},[372,1244,1245,1257],{},[393,1246,1247,1214,1249,1252,1253,1214,1255],{},[399,1248,553],{},[399,1250,1251],{},"5xx"," while ",[399,1254,1175],{},[399,1256,1204],{},[393,1258,1259,1260,1263],{},"The API is running but has a problem on our side. Retry, and report it with the ",[399,1261,1262],{},"request_id"," if it persists",[357,1265,1266,1268],{},[399,1267,553],{}," counts against your rate limit like any other operation (100 requests per 60 seconds on that operation), which leaves plenty of room for a check every minute.",[361,1270,1272],{"id":1271},"timeouts","Timeouts",[357,1274,1275,1276,1279],{},"Set explicit timeouts on your HTTP client instead of relying on defaults. Reasonable starting values are 5 seconds to connect and 30 seconds to read a JSON response. Allow longer for certificate and report downloads, which stream PDF files. The API closes a connection whose request has not arrived completely within 30 seconds. See ",[445,1277,1278],{"href":49},"Retries and idempotency"," for which requests are safe to retry after a timeout.",[361,1281,1283],{"id":1282},"time-and-dates","Time and dates",[357,1285,1286,1287,997,1290,1293,1294,450],{},"Base your token timestamps (",[399,1288,1289],{},"iat",[399,1291,1292],{},"exp",") on UTC seconds since the Unix epoch, and keep your server clock synchronized with NTP. The API tolerates at most 30 seconds of clock difference. Date formats in request and response bodies are described in ",[445,1295,33],{"href":34},[361,1297,1299],{"id":1298},"versions-and-deprecation","Versions and deprecation",[357,1301,1302,1303,1306,1307,1310],{},"The version of the API these pages describe is shown in the ",[445,1304,1305],{"href":121},"API reference",". What changes, and when, is recorded in the ",[445,1308,1309],{"href":349},"changelog",", with a page for every version.",[516,1312,1313,1327,1330],{},[519,1314,1315,1316,1319,1320,873,1323,1326],{},"Before anything is removed or changed incompatibly, you get ",[720,1317,1318],{},"at least 6 months' notice",", through the changelog and through ",[399,1321,1322],{},"Deprecation",[399,1324,1325],{},"Sunset"," headers on the affected responses.",[519,1328,1329],{},"Removals happen only in a new major version, which gets a new path prefix.",[519,1331,1332,1333,450],{},"Your code should ignore response fields it does not recognize, because new fields can be added within ",[399,1334,428],{},[357,1336,1337,1338,450],{},"The full policy is in ",[445,1339,54],{"href":55},[361,1341,345],{"id":1342},"support",[357,1344,1345,1346,1350,1351,1353,1354,1356,1357,450],{},"Write to ",[720,1347,1348],{},[445,1349,542],{"href":541},". Include the environment, the ",[399,1352,1262],{},", the time in UTC and the operation you called. Never include your ",[399,1355,876],{}," or a token. See ",[445,1358,345],{"href":346},[1360,1361,1362],"style",{},"html pre.shiki code .sLBg1, html code.shiki .sLBg1{--shiki-default:#66707B;--shiki-dark:#BDC4CC}html pre.shiki code .suds8, html code.shiki .suds8{--shiki-default:#0E1116;--shiki-dark:#F0F3F6}html pre.shiki code .sHUrx, html code.shiki .sHUrx{--shiki-default:#A0111F;--shiki-dark:#FF9492}html pre.shiki code .sT6z2, html code.shiki .sT6z2{--shiki-default:#032563;--shiki-dark:#ADDCFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .soyes, html code.shiki .soyes{--shiki-default:#702C00;--shiki-dark:#FFB757}html pre.shiki code .s-5SL, html code.shiki .s-5SL{--shiki-default:#023B95;--shiki-dark:#91CBFF}html pre.shiki code .sne4z, html code.shiki .sne4z{--shiki-default:#024C1A;--shiki-dark:#72F088}",{"title":460,"searchDepth":474,"depth":489,"links":1364},[1365,1366,1367,1371,1372,1373,1374,1375,1376,1377,1378],{"id":363,"depth":474,"text":364},{"id":511,"depth":474,"text":395},{"id":537,"depth":474,"text":412,"children":1368},[1369,1370],{"id":785,"depth":489,"text":663},{"id":855,"depth":489,"text":856},{"id":886,"depth":474,"text":887},{"id":921,"depth":474,"text":922},{"id":950,"depth":474,"text":951},{"id":1078,"depth":474,"text":1079},{"id":1271,"depth":474,"text":1272},{"id":1282,"depth":474,"text":1283},{"id":1298,"depth":474,"text":1299},{"id":1342,"depth":474,"text":345},"Where the API runs, what each environment is for, how to call it safely from your servers, and how to monitor that it is up.","md",{},true,[1384],"getHealth","20",{"title":16,"description":1379},"api\u002Fenvironments","sEhCj6A8SJ5zLDA0fY3-h5C3R_U2hwHBmKUO9d2E7Eo",[1390],{"operationId":1384,"slug":1391,"method":133,"path":1175,"tag":127,"summary":131,"deprecated":134,"public":1382,"permission":1392,"scope":1393,"order":467},"get-health",null,"public",1791554614894]