[{"data":1,"prerenderedAt":3091},["ShallowReactive",2],{"api-nav":3,"api-guide:\u002Fapi\u002Fguides\u002Fpasswords":351,"api-spec:guide:\u002Fapi\u002Fguides\u002Fpasswords":3081},[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":353,"body":354,"description":3071,"extension":3072,"meta":3073,"navTitle":68,"navigation":1732,"operations":3074,"order":3077,"path":69,"section":58,"seo":3078,"status":14,"stem":3079,"__hash__":3080},"apiGuides\u002Fapi\u002Fguides\u002Fpasswords.md","Student passwords",{"type":355,"value":356,"toc":3054},"minimark",[357,366,371,374,463,469,473,509,524,539,543,546,634,637,641,644,707,714,719,722,804,808,825,920,926,930,945,1081,1092,1136,1139,1143,1148,1194,1448,1458,1462,1542,1545,1549,1619,1635,1638,1698,1701,1704,2172,2740,2752,2755,3020,3023,3027,3050],[358,359,360,361,365],"p",{},"A student you registered can reach the panel in one of two ways: through a\n",[362,363,364],"a",{"href":81},"sign-in link"," you create when they need one, or with a password. This page\ncovers passwords: where you can set one, the permission that takes, the rules a password must meet,\nand why the API stops letting you set one once the student has confirmed their email address.",[367,368,370],"h2",{"id":369},"links-or-passwords","Links or passwords?",[358,372,373],{},"Prefer sign-in links. A password is a standing way in as the student, which is exactly why the API is\ncareful about who may set one.",[375,376,377,392],"table",{},[378,379,380],"thead",{},[381,382,383,386,389],"tr",{},[384,385],"th",{},[384,387,388],{},"Sign-in link",[384,390,391],{},"Password you set",[393,394,395,407,418,438,452],"tbody",{},[381,396,397,401,404],{},[398,399,400],"td",{},"Lifetime",[398,402,403],{},"120 seconds, single use",[398,405,406],{},"Until someone changes it",[381,408,409,412,415],{},[398,410,411],{},"Who knows it",[398,413,414],{},"Only the browser you redirect",[398,416,417],{},"You, the student, and every system the password passed through",[381,419,420,423,430],{},[398,421,422],{},"Permission",[398,424,425,429],{},[426,427,428],"code",{},"auth\u002Fsignin"," on the organization in the path",[398,431,432,434,435],{},[426,433,428],{}," on ",[426,436,437],{},"mto",[381,439,440,443,446],{},[398,441,442],{},"Works for a student who confirmed their email",[398,444,445],{},"Yes",[398,447,448,449],{},"No, the route answers ",[426,450,451],{},"409",[381,453,454,457,460],{},[398,455,456],{},"Needs anything delivered to the student",[398,458,459],{},"No, you redirect them",[398,461,462],{},"Yes, you have to get the password to them",[358,464,465,466,468],{},"Set passwords when the student really needs one: for example, a student who will sign in from a\ndevice your integration does not control. Otherwise, create a link each time they click \"Open\npanel\" in your product (see ",[362,467,103],{"href":104},").",[367,470,472],{"id":471},"the-permission","The permission",[358,474,475,476,478,479,485,486,488,489,492,493,492,496,492,499,502,503,505,506,508],{},"Setting a password takes the same permission a sign-in link takes, ",[426,477,428],{},", and it has to be\ngranted ",[480,481,482,483],"strong",{},"on ",[426,484,437],{},": a role with action ",[426,487,428],{}," (or ",[426,490,491],{},"auth\u002F*",", ",[426,494,495],{},"*\u002Fsignin",[426,497,498],{},"*\u002F*",[426,500,501],{},"*",") and\ntarget ",[426,504,437],{}," or ",[426,507,501],{},".",[358,510,511,512,515,516,519,520,523],{},"The reason: whoever knows a student's password can sign in as that student, with no expiry. That is at\nleast as strong as a sign-in link, so it cannot need less. Roles that manage students do ",[480,513,514],{},"not"," grant\nit. An account holding ",[426,517,518],{},"student\u002F*"," can register and update students, but gets ",[426,521,522],{},"403"," on the password\nroute.",[525,526,528],"callout",{"type":527},"note",[358,529,530,532,533,536,537,508],{},[426,531,428],{}," on one organization only, for example target ",[426,534,535],{},"stem",", lets you create sign-in links for\nstem but not set passwords. A password belongs to the core record, so it needs the permission on\n",[426,538,437],{},[367,540,542],{"id":541},"where-a-password-can-be-set","Where a password can be set",[358,544,545],{},"A student has one password, stored on the core record. The student signs in against that record, so\nthere is no per-organization password, and the same password works wherever they are entered.",[375,547,548,563],{},[378,549,550],{},[381,551,552,555,560],{},[384,553,554],{},"Route",[384,556,557],{},[426,558,559],{},"password",[384,561,562],{},"What happens",[393,564,565,585,601,619],{},[381,566,567,572,575],{},[398,568,569],{},[426,570,571],{},"POST \u002Fv1\u002Fstudent",[398,573,574],{},"optional",[398,576,577,578,434,580,582,583,508],{},"Sets the password when the student is created. Without ",[426,579,428],{},[426,581,437],{},": ",[426,584,522],{},[381,586,587,592,595],{},[398,588,589],{},[426,590,591],{},"PUT \u002Fv1\u002Fstudent\u002F\u003CstudentId>\u002Fpassword",[398,593,594],{},"required, and the only field",[398,596,597,598,600],{},"Replaces the password. ",[426,599,451],{}," once the student has confirmed their email.",[381,602,603,608,611],{},[398,604,605],{},[426,606,607],{},"PUT \u002Fv1\u002Fstudent\u002F\u003CstudentId>",[398,609,610],{},"not accepted",[398,612,613,492,616],{},[426,614,615],{},"400",[426,617,618],{},"property password should not exist",[381,620,621,626,628],{},[398,622,623],{},[426,624,625],{},"PUT \u002Fv1\u002F\u003CorganizationId>\u002Fstudent\u002F\u003CstudentId>",[398,627,610],{},[398,629,630,492,632],{},[426,631,615],{},[426,633,618],{},[358,635,636],{},"The API stores a password only as a hash. No route ever returns it, not even the one that just set it,\nand there is no route that checks a password or reads one back.",[367,638,640],{"id":639},"the-rules-a-password-must-meet","The rules a password must meet",[358,642,643],{},"The rules are the platform's own, so any password a student could choose for themselves in the panel\nis one you can set for them. The API adds one rule of its own, about the student's personal details.",[375,645,646,656],{},[378,647,648],{},[381,649,650,653],{},[384,651,652],{},"Rule",[384,654,655],{},"Detail",[393,657,658,669,681,692],{},[381,659,660,663],{},[398,661,662],{},"A string",[398,664,665,666,508],{},"A number, array, object or boolean is refused: ",[426,667,668],{},"password must be a string",[381,670,671,674],{},[398,672,673],{},"At least 5 characters",[398,675,676,677,680],{},"Counted in characters. ",[426,678,679],{},"12345"," is accepted.",[381,682,683,686],{},[398,684,685],{},"At most 72 bytes",[398,687,688,689,508],{},"Counted in UTF-8 bytes, not characters: ",[426,690,691],{},"password must be at most 72 bytes long, because bcrypt ignores anything past that",[381,693,694,697],{},[398,695,696],{},"Not built from the student's own details",[398,698,699,700,703,704,508],{},"It must not contain the student's first name, last name, username, email address, or the part of the email before the ",[426,701,702],{},"@",". The comparison ignores case, and a detail shorter than 4 characters is ignored. Message: ",[426,705,706],{},"password must not contain the student's own name, username or email address",[358,708,709,710,468],{},"Nothing else is checked. There is no requirement for upper case, digits or symbols, and spaces are\nallowed. Common passwords are not refused either. That keeps the API no stricter than the platform,\nso you can pass on a password a student chose themselves. When you choose one, generate it at random\n(see ",[362,711,713],{"href":712},"#generate-a-password","Generate a password",[715,716,718],"h3",{"id":717},"why-bytes-not-characters","Why bytes, not characters",[358,720,721],{},"The hash reads at most 72 bytes of a password and silently ignores the rest. A longer password would\npromise strength the stored hash does not have, so it is refused instead. Letters outside ASCII take\nmore than one byte:",[375,723,724,740],{},[378,725,726],{},[381,727,728,731,734,737],{},[384,729,730],{},"Password",[384,732,733],{},"Characters",[384,735,736],{},"Bytes",[384,738,739],{},"Accepted",[393,741,742,757,773,789],{},[381,743,744,749,752,754],{},[398,745,746],{},[426,747,748],{},"grapefruit lantern quarry",[398,750,751],{},"25",[398,753,751],{},[398,755,756],{},"yes",[381,758,759,765,768,770],{},[398,760,761,764],{},[426,762,763],{},"q"," repeated 73 times",[398,766,767],{},"73",[398,769,767],{},[398,771,772],{},"no",[381,774,775,781,784,787],{},[398,776,777,780],{},[426,778,779],{},"ş"," repeated 40 times",[398,782,783],{},"40",[398,785,786],{},"80",[398,788,772],{},[381,790,791,796,799,802],{},[398,792,793,795],{},[426,794,779],{}," repeated 36 times",[398,797,798],{},"36",[398,800,801],{},"72",[398,803,756],{},[715,805,807],{"id":806},"the-personal-details-rule-by-example","The personal-details rule, by example",[358,809,810,811,492,814,817,818,821,822,508],{},"Take a student registered as ",[426,812,813],{},"firstName: \"Katherine\"",[426,815,816],{},"lastName: \"Lovelace\"",",\n",[426,819,820],{},"email: \"k.pioneer@example.org\"",", whose minted username is ",[426,823,824],{},"XXB1045",[375,826,827,839],{},[378,828,829],{},[381,830,831,833,836],{},[384,832,730],{},[384,834,835],{},"Result",[384,837,838],{},"Why",[393,840,841,854,866,880,893,909],{},[381,842,843,848,851],{},[398,844,845],{},[426,846,847],{},"Katherine-2026",[398,849,850],{},"refused",[398,852,853],{},"contains the first name",[381,855,856,861,863],{},[398,857,858],{},[426,859,860],{},"river LOVELACE 9",[398,862,850],{},[398,864,865],{},"contains the last name, ignoring case",[381,867,868,873,875],{},[398,869,870],{},[426,871,872],{},"k.pioneer!42",[398,874,850],{},[398,876,877,878],{},"contains the part of the email before ",[426,879,702],{},[381,881,882,887,890],{},[398,883,884],{},[426,885,886],{},"xxb1045-summer",[398,888,889],{},"refused on the password route",[398,891,892],{},"contains the username",[381,894,895,900,903],{},[398,896,897],{},[426,898,899],{},"Kat-river-2026",[398,901,902],{},"accepted",[398,904,905,908],{},[426,906,907],{},"Kat"," is not the whole first name",[381,910,911,915,917],{},[398,912,913],{},[426,914,748],{},[398,916,902],{},[398,918,919],{},"shares nothing with the student",[358,921,922,923,925],{},"At registration the username does not exist yet, because registration is what creates it. So\nthe check against the username only happens on ",[426,924,591],{},", which reads the\nstored record first. This rule exists because an integration that sets every student's password to\ntheir username sets thousands of passwords anyone can guess. Usernames are what students and support\nuse to refer to an account.",[367,927,929],{"id":928},"set-a-password-at-registration","Set a password at registration",[358,931,932,933,935,936,939,940,942,943,508],{},"Add ",[426,934,559],{}," to the registration body. The account needs ",[426,937,938],{},"student\u002Fcreate"," and ",[426,941,428],{}," on\n",[426,944,437],{},[946,947,952],"pre",{"className":948,"code":949,"language":950,"meta":951,"style":951},"language-bash shiki shiki-themes github-light-high-contrast github-dark-high-contrast","curl -X POST \"https:\u002F\u002Fapi.main-team.org\u002Fv1\u002Fstudent\" \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"firstName\": \"Katherine\",\n    \"lastName\": \"Lovelace\",\n    \"email\": \"k.pioneer@example.org\",\n    \"birth\": \"14\u002F05\u002F2010\",\n    \"sex\": \"f\",\n    \"country\": \"630e0182c53dc79a6836e67e\",\n    \"grade\": \"9\",\n    \"city\": \"Berlin\",\n    \"school\": \"Berlin International School\",\n    \"password\": \"grapefruit lantern quarry\"\n  }'\n","bash","",[426,953,954,978,996,1006,1015,1021,1027,1033,1039,1045,1051,1057,1063,1069,1075],{"__ignoreMap":951},[955,956,959,963,967,971,974],"span",{"class":957,"line":958},"line",1,[955,960,962],{"class":961},"soyes","curl",[955,964,966],{"class":965},"s-5SL"," -X",[955,968,970],{"class":969},"sT6z2"," POST",[955,972,973],{"class":969}," \"https:\u002F\u002Fapi.main-team.org\u002Fv1\u002Fstudent\"",[955,975,977],{"class":976},"sHUrx"," \\\n",[955,979,981,984,987,991,994],{"class":957,"line":980},2,[955,982,983],{"class":965},"  -H",[955,985,986],{"class":969}," \"Authorization: Bearer ",[955,988,990],{"class":989},"suds8","$TOKEN",[955,992,993],{"class":969},"\"",[955,995,977],{"class":976},[955,997,999,1001,1004],{"class":957,"line":998},3,[955,1000,983],{"class":965},[955,1002,1003],{"class":969}," \"Content-Type: application\u002Fjson\"",[955,1005,977],{"class":976},[955,1007,1009,1012],{"class":957,"line":1008},4,[955,1010,1011],{"class":965},"  -d",[955,1013,1014],{"class":969}," '{\n",[955,1016,1018],{"class":957,"line":1017},5,[955,1019,1020],{"class":969},"    \"firstName\": \"Katherine\",\n",[955,1022,1024],{"class":957,"line":1023},6,[955,1025,1026],{"class":969},"    \"lastName\": \"Lovelace\",\n",[955,1028,1030],{"class":957,"line":1029},7,[955,1031,1032],{"class":969},"    \"email\": \"k.pioneer@example.org\",\n",[955,1034,1036],{"class":957,"line":1035},8,[955,1037,1038],{"class":969},"    \"birth\": \"14\u002F05\u002F2010\",\n",[955,1040,1042],{"class":957,"line":1041},9,[955,1043,1044],{"class":969},"    \"sex\": \"f\",\n",[955,1046,1048],{"class":957,"line":1047},10,[955,1049,1050],{"class":969},"    \"country\": \"630e0182c53dc79a6836e67e\",\n",[955,1052,1054],{"class":957,"line":1053},11,[955,1055,1056],{"class":969},"    \"grade\": \"9\",\n",[955,1058,1060],{"class":957,"line":1059},12,[955,1061,1062],{"class":969},"    \"city\": \"Berlin\",\n",[955,1064,1066],{"class":957,"line":1065},13,[955,1067,1068],{"class":969},"    \"school\": \"Berlin International School\",\n",[955,1070,1072],{"class":957,"line":1071},14,[955,1073,1074],{"class":969},"    \"password\": \"grapefruit lantern quarry\"\n",[955,1076,1078],{"class":957,"line":1077},15,[955,1079,1080],{"class":969},"  }'\n",[358,1082,1083,1084,1087,1088,1091],{},"The response is the usual registration response, ",[426,1085,1086],{},"201"," with the new student\n(",[362,1089,62],{"href":1090},"\u002Fapi\u002Fguides\u002Fstudents#register-a-student"," shows it in full). It never contains the password.",[1093,1094,1095,1108,1128],"ul",{},[1096,1097,1098,1103,1104,1107],"li",{},[480,1099,1100,1101],{},"Omit ",[426,1102,559],{},", or send ",[426,1105,1106],{},"null",", and the student is created without one. That needs no extra\npermission. The student can still reach the panel through a sign-in link.",[1096,1109,1110,1113,1114,1116,1117,1123,1124,1127],{},[480,1111,1112],{},"Send one without the permission"," and the whole registration is refused, before anything is\nwritten: ",[426,1115,522],{},", code ",[362,1118,1120],{"href":1119},"\u002Fapi\u002Ferrors#forbidden",[426,1121,1122],{},"forbidden",", message\n",[426,1125,1126],{},"Setting a student's password needs the auth\u002Fsignin permission on mto, the same grant a sign-in link needs.","\nResend without the field, or ask for the permission.",[1096,1129,1130,1133,1134,508],{},[480,1131,1132],{},"An empty string is not \"no password\"."," It fails the 5-character rule with ",[426,1135,615],{},[358,1137,1138],{},"Hashing is deliberately slow, so a request that sets a password takes noticeably longer than one that\ndoes not, often more than a second. Allow for it in your timeouts, especially when you register in\nbulk.",[367,1140,1142],{"id":1141},"change-a-password-later","Change a password later",[358,1144,1145,1147],{},[426,1146,591],{}," replaces the password of one of your students. The body has\nexactly one field.",[946,1149,1151],{"className":948,"code":1150,"language":950,"meta":951,"style":951},"curl -X PUT \"https:\u002F\u002Fapi.main-team.org\u002Fv1\u002Fstudent\u002F6650f1a2b3c4d5e6f7a8b9c0\u002Fpassword\" \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{ \"password\": \"grapefruit lantern quarry\" }'\n",[426,1152,1153,1167,1179,1187],{"__ignoreMap":951},[955,1154,1155,1157,1159,1162,1165],{"class":957,"line":958},[955,1156,962],{"class":961},[955,1158,966],{"class":965},[955,1160,1161],{"class":969}," PUT",[955,1163,1164],{"class":969}," \"https:\u002F\u002Fapi.main-team.org\u002Fv1\u002Fstudent\u002F6650f1a2b3c4d5e6f7a8b9c0\u002Fpassword\"",[955,1166,977],{"class":976},[955,1168,1169,1171,1173,1175,1177],{"class":957,"line":980},[955,1170,983],{"class":965},[955,1172,986],{"class":969},[955,1174,990],{"class":989},[955,1176,993],{"class":969},[955,1178,977],{"class":976},[955,1180,1181,1183,1185],{"class":957,"line":998},[955,1182,983],{"class":965},[955,1184,1003],{"class":969},[955,1186,977],{"class":976},[955,1188,1189,1191],{"class":957,"line":1008},[955,1190,1011],{"class":965},[955,1192,1193],{"class":969}," '{ \"password\": \"grapefruit lantern quarry\" }'\n",[946,1195,1199],{"className":1196,"code":1197,"language":1198,"meta":951,"style":951},"language-json shiki shiki-themes github-light-high-contrast github-dark-high-contrast","{\n  \"success\": true,\n  \"message\": \"Password set.\",\n  \"data\": {\n    \"_id\": \"6650f1a2b3c4d5e6f7a8b9c0\",\n    \"username\": \"XXB1045\",\n    \"firstName\": \"Katherine\",\n    \"lastName\": \"Lovelace\",\n    \"fullName\": \"Katherine Lovelace\",\n    \"email\": \"k.pioneer@example.org\",\n    \"emailConfirmed\": false,\n    \"birth\": \"14\u002F05\u002F2010\",\n    \"sex\": \"f\",\n    \"country\": \"630e0182c53dc79a6836e67e\",\n    \"city\": \"6650e0a1b2c3d4e5f6a7b801\",\n    \"school\": \"6650e0a1b2c3d4e5f6a7b8c2\",\n    \"grade\": \"630e01826836e67ec53dc7a5\",\n    \"activatedPlatformsThisSeason\": [\"common\"],\n    \"createdAt\": \"2026-09-01T09:12:44.512Z\",\n    \"updatedAt\": \"2026-09-15T10:03:18.090Z\"\n  }\n}\n","json",[426,1200,1201,1206,1219,1231,1239,1251,1263,1275,1287,1299,1311,1323,1335,1347,1359,1371,1384,1397,1412,1425,1436,1442],{"__ignoreMap":951},[955,1202,1203],{"class":957,"line":958},[955,1204,1205],{"class":989},"{\n",[955,1207,1208,1212,1214,1217],{"class":957,"line":980},[955,1209,1211],{"class":1210},"sne4z","  \"success\"",[955,1213,582],{"class":989},[955,1215,1216],{"class":965},"true",[955,1218,817],{"class":989},[955,1220,1221,1224,1226,1229],{"class":957,"line":998},[955,1222,1223],{"class":1210},"  \"message\"",[955,1225,582],{"class":989},[955,1227,1228],{"class":969},"\"Password set.\"",[955,1230,817],{"class":989},[955,1232,1233,1236],{"class":957,"line":1008},[955,1234,1235],{"class":1210},"  \"data\"",[955,1237,1238],{"class":989},": {\n",[955,1240,1241,1244,1246,1249],{"class":957,"line":1017},[955,1242,1243],{"class":1210},"    \"_id\"",[955,1245,582],{"class":989},[955,1247,1248],{"class":969},"\"6650f1a2b3c4d5e6f7a8b9c0\"",[955,1250,817],{"class":989},[955,1252,1253,1256,1258,1261],{"class":957,"line":1023},[955,1254,1255],{"class":1210},"    \"username\"",[955,1257,582],{"class":989},[955,1259,1260],{"class":969},"\"XXB1045\"",[955,1262,817],{"class":989},[955,1264,1265,1268,1270,1273],{"class":957,"line":1029},[955,1266,1267],{"class":1210},"    \"firstName\"",[955,1269,582],{"class":989},[955,1271,1272],{"class":969},"\"Katherine\"",[955,1274,817],{"class":989},[955,1276,1277,1280,1282,1285],{"class":957,"line":1035},[955,1278,1279],{"class":1210},"    \"lastName\"",[955,1281,582],{"class":989},[955,1283,1284],{"class":969},"\"Lovelace\"",[955,1286,817],{"class":989},[955,1288,1289,1292,1294,1297],{"class":957,"line":1041},[955,1290,1291],{"class":1210},"    \"fullName\"",[955,1293,582],{"class":989},[955,1295,1296],{"class":969},"\"Katherine Lovelace\"",[955,1298,817],{"class":989},[955,1300,1301,1304,1306,1309],{"class":957,"line":1047},[955,1302,1303],{"class":1210},"    \"email\"",[955,1305,582],{"class":989},[955,1307,1308],{"class":969},"\"k.pioneer@example.org\"",[955,1310,817],{"class":989},[955,1312,1313,1316,1318,1321],{"class":957,"line":1053},[955,1314,1315],{"class":1210},"    \"emailConfirmed\"",[955,1317,582],{"class":989},[955,1319,1320],{"class":965},"false",[955,1322,817],{"class":989},[955,1324,1325,1328,1330,1333],{"class":957,"line":1059},[955,1326,1327],{"class":1210},"    \"birth\"",[955,1329,582],{"class":989},[955,1331,1332],{"class":969},"\"14\u002F05\u002F2010\"",[955,1334,817],{"class":989},[955,1336,1337,1340,1342,1345],{"class":957,"line":1065},[955,1338,1339],{"class":1210},"    \"sex\"",[955,1341,582],{"class":989},[955,1343,1344],{"class":969},"\"f\"",[955,1346,817],{"class":989},[955,1348,1349,1352,1354,1357],{"class":957,"line":1071},[955,1350,1351],{"class":1210},"    \"country\"",[955,1353,582],{"class":989},[955,1355,1356],{"class":969},"\"630e0182c53dc79a6836e67e\"",[955,1358,817],{"class":989},[955,1360,1361,1364,1366,1369],{"class":957,"line":1077},[955,1362,1363],{"class":1210},"    \"city\"",[955,1365,582],{"class":989},[955,1367,1368],{"class":969},"\"6650e0a1b2c3d4e5f6a7b801\"",[955,1370,817],{"class":989},[955,1372,1374,1377,1379,1382],{"class":957,"line":1373},16,[955,1375,1376],{"class":1210},"    \"school\"",[955,1378,582],{"class":989},[955,1380,1381],{"class":969},"\"6650e0a1b2c3d4e5f6a7b8c2\"",[955,1383,817],{"class":989},[955,1385,1387,1390,1392,1395],{"class":957,"line":1386},17,[955,1388,1389],{"class":1210},"    \"grade\"",[955,1391,582],{"class":989},[955,1393,1394],{"class":969},"\"630e01826836e67ec53dc7a5\"",[955,1396,817],{"class":989},[955,1398,1400,1403,1406,1409],{"class":957,"line":1399},18,[955,1401,1402],{"class":1210},"    \"activatedPlatformsThisSeason\"",[955,1404,1405],{"class":989},": [",[955,1407,1408],{"class":969},"\"common\"",[955,1410,1411],{"class":989},"],\n",[955,1413,1415,1418,1420,1423],{"class":957,"line":1414},19,[955,1416,1417],{"class":1210},"    \"createdAt\"",[955,1419,582],{"class":989},[955,1421,1422],{"class":969},"\"2026-09-01T09:12:44.512Z\"",[955,1424,817],{"class":989},[955,1426,1428,1431,1433],{"class":957,"line":1427},20,[955,1429,1430],{"class":1210},"    \"updatedAt\"",[955,1432,582],{"class":989},[955,1434,1435],{"class":969},"\"2026-09-15T10:03:18.090Z\"\n",[955,1437,1439],{"class":957,"line":1438},21,[955,1440,1441],{"class":989},"  }\n",[955,1443,1445],{"class":957,"line":1444},22,[955,1446,1447],{"class":989},"}\n",[358,1449,1450,1453,1454,1457],{},[426,1451,1452],{},"\u003CstudentId>"," is the ",[426,1455,1456],{},"_id"," you got when you registered the student.",[715,1459,1461],{"id":1460},"what-is-checked-in-order","What is checked, in order",[1463,1464,1465,1486,1506,1524,1532],"ol",{},[1096,1466,1467,1470,1471,1474,1475,1477,1478,1481,1482,434,1484,508],{},[480,1468,1469],{},"Your token and permission."," ",[426,1472,1473],{},"401"," if the token is refused. ",[426,1476,522],{}," with\n",[426,1479,1480],{},"Insufficient role permissions"," if the account lacks ",[426,1483,428],{},[426,1485,437],{},[1096,1487,1488,1470,1491,1493,1494,1496,1497,1500,1501,1503,1504,508],{},[480,1489,1490],{},"The body.",[426,1492,615],{}," if ",[426,1495,559],{}," is missing, not a string, shorter than 5 characters or longer than\n72 bytes, or if the body carries any other field (",[426,1498,1499],{},"property \u003Cname> should not exist","). A\n",[426,1502,1452],{}," that is not 24 hex characters is also ",[426,1505,615],{},[1096,1507,1508,1470,1511,1116,1514,492,1520,1523],{},[480,1509,1510],{},"The student.",[426,1512,1513],{},"404",[362,1515,1517],{"href":1516},"\u002Fapi\u002Ferrors#not_found",[426,1518,1519],{},"not_found",[426,1521,1522],{},"Student not found!"," when no\nstudent with that id belongs to your account. A student registered by another account gets exactly\nthe same answer.",[1096,1525,1526,1470,1529,1531],{},[480,1527,1528],{},"Email confirmation.",[426,1530,451],{}," once the student has confirmed their email address (next section).",[1096,1533,1534,1537,1538,492,1540,508],{},[480,1535,1536],{},"The personal-details rule",", checked against the student as stored, username included:\n",[426,1539,615],{},[426,1541,706],{},[358,1543,1544],{},"Nothing is written unless every step passes.",[367,1546,1548],{"id":1547},"once-the-student-confirms-their-email-the-password-is-theirs","Once the student confirms their email, the password is theirs",[946,1550,1552],{"className":1196,"code":1551,"language":1198,"meta":951,"style":951},"{\n  \"error\": {\n    \"code\": \"conflict\",\n    \"message\": \"This student has confirmed their email address, so the password is theirs to change. Send them a sign-in link with POST \u002Fv1\u002F:organizationId\u002Fauth\u002Fsignin.\",\n    \"documentation_url\": \"https:\u002F\u002Fhub.main-team.org\u002Fapi\u002Ferrors#conflict\",\n    \"request_id\": \"8b1f0c2d-3e4a-4b5c-9d6e-7f8a9b0c1d2e\"\n  }\n}\n",[426,1553,1554,1558,1565,1577,1589,1601,1611,1615],{"__ignoreMap":951},[955,1555,1556],{"class":957,"line":958},[955,1557,1205],{"class":989},[955,1559,1560,1563],{"class":957,"line":980},[955,1561,1562],{"class":1210},"  \"error\"",[955,1564,1238],{"class":989},[955,1566,1567,1570,1572,1575],{"class":957,"line":998},[955,1568,1569],{"class":1210},"    \"code\"",[955,1571,582],{"class":989},[955,1573,1574],{"class":969},"\"conflict\"",[955,1576,817],{"class":989},[955,1578,1579,1582,1584,1587],{"class":957,"line":1008},[955,1580,1581],{"class":1210},"    \"message\"",[955,1583,582],{"class":989},[955,1585,1586],{"class":969},"\"This student has confirmed their email address, so the password is theirs to change. Send them a sign-in link with POST \u002Fv1\u002F:organizationId\u002Fauth\u002Fsignin.\"",[955,1588,817],{"class":989},[955,1590,1591,1594,1596,1599],{"class":957,"line":1017},[955,1592,1593],{"class":1210},"    \"documentation_url\"",[955,1595,582],{"class":989},[955,1597,1598],{"class":969},"\"https:\u002F\u002Fhub.main-team.org\u002Fapi\u002Ferrors#conflict\"",[955,1600,817],{"class":989},[955,1602,1603,1606,1608],{"class":957,"line":1023},[955,1604,1605],{"class":1210},"    \"request_id\"",[955,1607,582],{"class":989},[955,1609,1610],{"class":969},"\"8b1f0c2d-3e4a-4b5c-9d6e-7f8a9b0c1d2e\"\n",[955,1612,1613],{"class":957,"line":1029},[955,1614,1441],{"class":989},[955,1616,1617],{"class":957,"line":1035},[955,1618,1447],{"class":989},[358,1620,1621,1622,1116,1624,1630,1631,1634],{},"A confirmed address means the student has proved that the email on the account reaches them. From\nthen on the account is theirs. A password set over theirs would lock them out of their own account,\nso the route refuses with ",[426,1623,451],{},[362,1625,1627],{"href":1626},"\u002Fapi\u002Ferrors#conflict",[426,1628,1629],{},"conflict",". You can still create\n",[362,1632,1633],{"href":81},"sign-in links"," for them: a link does not replace their password.",[358,1636,1637],{},"What you need to know about confirmation:",[1093,1639,1640,1646,1652,1665,1681],{},[1096,1641,1642,1645],{},[480,1643,1644],{},"Every student you register starts unconfirmed."," The API never marks an address as confirmed.",[1096,1647,1648,1651],{},[480,1649,1650],{},"The student confirms it themselves",", by proving they can read that mailbox: for example, by\nentering a code the platform emails to them, or by signing in with a Google account at that address.",[1096,1653,1654,1661,1662,1664],{},[480,1655,1656,1657,1660],{},"Read ",[426,1658,1659],{},"emailConfirmed"," before you call."," It is on every student the API returns. When it is ",[426,1663,1216],{},",\nskip the password route and use a sign-in link.",[1096,1666,1667,1670,1671,1674,1675,1677,1678,1680],{},[480,1668,1669],{},"Confirmation belongs to an address."," If you change the student's ",[426,1672,1673],{},"email",", the new address has\nnot been proved, so ",[426,1676,1659],{}," goes back to ",[426,1679,1320],{},". Sending the address the student already\nhas, in any letter case, changes nothing.",[1096,1682,1683,1686,1687,1689,1690,1692,1693,1695,1696,508],{},[480,1684,1685],{},"A student who confirms at the same moment you set a password wins."," If confirmation lands\nbetween the check and the write, nothing is written and you get ",[426,1688,1513],{}," with ",[426,1691,1522],{},".\nRead the student again: ",[426,1694,1659],{}," will be ",[426,1697,1216],{},[367,1699,713],{"id":1700},"generate-a-password",[358,1702,1703],{},"When you set a password, generate it: one per student, at random, never derived from the student's\ndetails. The examples below give 16 characters from a URL-safe alphabet: well inside the limits, with\nabout 96 bits of randomness.",[946,1705,1709],{"className":1706,"code":1707,"filename":308,"language":1708,"meta":951,"style":951},"language-js shiki shiki-themes github-light-high-contrast github-dark-high-contrast","import { randomBytes } from 'node:crypto';\n\nconst BASE = 'https:\u002F\u002Fapi.main-team.org\u002Fv1';\n\nexport function generatePassword() {\n  return randomBytes(12).toString('base64url'); \u002F\u002F 16 ASCII characters = 16 bytes\n}\n\nexport async function setPassword(token, studentId) {\n  for (let attempt = 0; attempt \u003C 3; attempt++) {\n    const password = generatePassword();\n    const res = await fetch(`${BASE}\u002Fstudent\u002F${studentId}\u002Fpassword`, {\n      method: 'PUT',\n      headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application\u002Fjson' },\n      body: JSON.stringify({ password }),\n    });\n    if (res.ok) return password; \u002F\u002F deliver it to the student; never log it\n\n    const { error } = await res.json();\n    if (res.status === 409) return null; \u002F\u002F confirmed student: use a sign-in link instead\n    \u002F\u002F A random password colliding with the student's details is very unlikely, but retry once more.\n    if (res.status === 400 && error.message.includes(\"student's own\")) continue;\n    throw new Error(`${res.status} ${error.code}: ${error.message} (request ${error.request_id})`);\n  }\n  throw new Error('Could not generate an acceptable password');\n}\n","js",[426,1710,1711,1728,1734,1750,1754,1769,1800,1804,1808,1833,1870,1885,1919,1929,1955,1971,1976,1993,1997,2021,2048,2053,2086,2145,2150,2167],{"__ignoreMap":951},[955,1712,1713,1716,1719,1722,1725],{"class":957,"line":958},[955,1714,1715],{"class":976},"import",[955,1717,1718],{"class":989}," { randomBytes } ",[955,1720,1721],{"class":976},"from",[955,1723,1724],{"class":969}," 'node:crypto'",[955,1726,1727],{"class":989},";\n",[955,1729,1730],{"class":957,"line":980},[955,1731,1733],{"emptyLinePlaceholder":1732},true,"\n",[955,1735,1736,1739,1742,1745,1748],{"class":957,"line":998},[955,1737,1738],{"class":976},"const",[955,1740,1741],{"class":965}," BASE",[955,1743,1744],{"class":976}," =",[955,1746,1747],{"class":969}," 'https:\u002F\u002Fapi.main-team.org\u002Fv1'",[955,1749,1727],{"class":989},[955,1751,1752],{"class":957,"line":1008},[955,1753,1733],{"emptyLinePlaceholder":1732},[955,1755,1756,1759,1762,1766],{"class":957,"line":1017},[955,1757,1758],{"class":976},"export",[955,1760,1761],{"class":976}," function",[955,1763,1765],{"class":1764},"sKwhi"," generatePassword",[955,1767,1768],{"class":989},"() {\n",[955,1770,1771,1774,1777,1780,1783,1785,1788,1790,1793,1796],{"class":957,"line":1023},[955,1772,1773],{"class":976},"  return",[955,1775,1776],{"class":1764}," randomBytes",[955,1778,1779],{"class":989},"(",[955,1781,1782],{"class":965},"12",[955,1784,468],{"class":989},[955,1786,1787],{"class":1764},"toString",[955,1789,1779],{"class":989},[955,1791,1792],{"class":969},"'base64url'",[955,1794,1795],{"class":989},"); ",[955,1797,1799],{"class":1798},"sLBg1","\u002F\u002F 16 ASCII characters = 16 bytes\n",[955,1801,1802],{"class":957,"line":1029},[955,1803,1447],{"class":989},[955,1805,1806],{"class":957,"line":1035},[955,1807,1733],{"emptyLinePlaceholder":1732},[955,1809,1810,1812,1815,1817,1820,1822,1825,1827,1830],{"class":957,"line":1041},[955,1811,1758],{"class":976},[955,1813,1814],{"class":976}," async",[955,1816,1761],{"class":976},[955,1818,1819],{"class":1764}," setPassword",[955,1821,1779],{"class":989},[955,1823,1824],{"class":961},"token",[955,1826,492],{"class":989},[955,1828,1829],{"class":961},"studentId",[955,1831,1832],{"class":989},") {\n",[955,1834,1835,1838,1841,1844,1847,1850,1853,1856,1859,1862,1865,1868],{"class":957,"line":1047},[955,1836,1837],{"class":976},"  for",[955,1839,1840],{"class":989}," (",[955,1842,1843],{"class":976},"let",[955,1845,1846],{"class":989}," attempt ",[955,1848,1849],{"class":976},"=",[955,1851,1852],{"class":965}," 0",[955,1854,1855],{"class":989},"; attempt ",[955,1857,1858],{"class":976},"\u003C",[955,1860,1861],{"class":965}," 3",[955,1863,1864],{"class":989},"; attempt",[955,1866,1867],{"class":976},"++",[955,1869,1832],{"class":989},[955,1871,1872,1875,1878,1880,1882],{"class":957,"line":1053},[955,1873,1874],{"class":976},"    const",[955,1876,1877],{"class":965}," password",[955,1879,1744],{"class":976},[955,1881,1765],{"class":1764},[955,1883,1884],{"class":989},"();\n",[955,1886,1887,1889,1892,1894,1897,1900,1902,1905,1908,1911,1913,1916],{"class":957,"line":1059},[955,1888,1874],{"class":976},[955,1890,1891],{"class":965}," res",[955,1893,1744],{"class":976},[955,1895,1896],{"class":976}," await",[955,1898,1899],{"class":1764}," fetch",[955,1901,1779],{"class":989},[955,1903,1904],{"class":969},"`${",[955,1906,1907],{"class":965},"BASE",[955,1909,1910],{"class":969},"}\u002Fstudent\u002F${",[955,1912,1829],{"class":989},[955,1914,1915],{"class":969},"}\u002Fpassword`",[955,1917,1918],{"class":989},", {\n",[955,1920,1921,1924,1927],{"class":957,"line":1065},[955,1922,1923],{"class":989},"      method: ",[955,1925,1926],{"class":969},"'PUT'",[955,1928,817],{"class":989},[955,1930,1931,1934,1937,1939,1942,1944,1947,1949,1952],{"class":957,"line":1071},[955,1932,1933],{"class":989},"      headers: { Authorization: ",[955,1935,1936],{"class":969},"`Bearer ${",[955,1938,1824],{"class":989},[955,1940,1941],{"class":969},"}`",[955,1943,492],{"class":989},[955,1945,1946],{"class":969},"'Content-Type'",[955,1948,582],{"class":989},[955,1950,1951],{"class":969},"'application\u002Fjson'",[955,1953,1954],{"class":989}," },\n",[955,1956,1957,1960,1963,1965,1968],{"class":957,"line":1077},[955,1958,1959],{"class":989},"      body: ",[955,1961,1962],{"class":965},"JSON",[955,1964,508],{"class":989},[955,1966,1967],{"class":1764},"stringify",[955,1969,1970],{"class":989},"({ password }),\n",[955,1972,1973],{"class":957,"line":1373},[955,1974,1975],{"class":989},"    });\n",[955,1977,1978,1981,1984,1987,1990],{"class":957,"line":1386},[955,1979,1980],{"class":976},"    if",[955,1982,1983],{"class":989}," (res.ok) ",[955,1985,1986],{"class":976},"return",[955,1988,1989],{"class":989}," password; ",[955,1991,1992],{"class":1798},"\u002F\u002F deliver it to the student; never log it\n",[955,1994,1995],{"class":957,"line":1399},[955,1996,1733],{"emptyLinePlaceholder":1732},[955,1998,1999,2001,2004,2007,2010,2012,2014,2017,2019],{"class":957,"line":1414},[955,2000,1874],{"class":976},[955,2002,2003],{"class":989}," { ",[955,2005,2006],{"class":965},"error",[955,2008,2009],{"class":989}," } ",[955,2011,1849],{"class":976},[955,2013,1896],{"class":976},[955,2015,2016],{"class":989}," res.",[955,2018,1198],{"class":1764},[955,2020,1884],{"class":989},[955,2022,2023,2025,2028,2031,2034,2037,2039,2042,2045],{"class":957,"line":1427},[955,2024,1980],{"class":976},[955,2026,2027],{"class":989}," (res.status ",[955,2029,2030],{"class":976},"===",[955,2032,2033],{"class":965}," 409",[955,2035,2036],{"class":989},") ",[955,2038,1986],{"class":976},[955,2040,2041],{"class":965}," null",[955,2043,2044],{"class":989},"; ",[955,2046,2047],{"class":1798},"\u002F\u002F confirmed student: use a sign-in link instead\n",[955,2049,2050],{"class":957,"line":1438},[955,2051,2052],{"class":1798},"    \u002F\u002F A random password colliding with the student's details is very unlikely, but retry once more.\n",[955,2054,2055,2057,2059,2061,2064,2067,2070,2073,2075,2078,2081,2084],{"class":957,"line":1444},[955,2056,1980],{"class":976},[955,2058,2027],{"class":989},[955,2060,2030],{"class":976},[955,2062,2063],{"class":965}," 400",[955,2065,2066],{"class":976}," &&",[955,2068,2069],{"class":989}," error.message.",[955,2071,2072],{"class":1764},"includes",[955,2074,1779],{"class":989},[955,2076,2077],{"class":969},"\"student's own\"",[955,2079,2080],{"class":989},")) ",[955,2082,2083],{"class":976},"continue",[955,2085,1727],{"class":989},[955,2087,2089,2092,2095,2098,2100,2102,2105,2107,2110,2113,2115,2117,2119,2122,2124,2126,2129,2132,2134,2136,2139,2142],{"class":957,"line":2088},23,[955,2090,2091],{"class":976},"    throw",[955,2093,2094],{"class":976}," new",[955,2096,2097],{"class":1764}," Error",[955,2099,1779],{"class":989},[955,2101,1904],{"class":969},[955,2103,2104],{"class":989},"res",[955,2106,508],{"class":969},[955,2108,2109],{"class":989},"status",[955,2111,2112],{"class":969},"} ${",[955,2114,2006],{"class":989},[955,2116,508],{"class":969},[955,2118,426],{"class":989},[955,2120,2121],{"class":969},"}: ${",[955,2123,2006],{"class":989},[955,2125,508],{"class":969},[955,2127,2128],{"class":989},"message",[955,2130,2131],{"class":969},"} (request ${",[955,2133,2006],{"class":989},[955,2135,508],{"class":969},[955,2137,2138],{"class":989},"request_id",[955,2140,2141],{"class":969},"})`",[955,2143,2144],{"class":989},");\n",[955,2146,2148],{"class":957,"line":2147},24,[955,2149,1441],{"class":989},[955,2151,2153,2156,2158,2160,2162,2165],{"class":957,"line":2152},25,[955,2154,2155],{"class":976},"  throw",[955,2157,2094],{"class":976},[955,2159,2097],{"class":1764},[955,2161,1779],{"class":989},[955,2163,2164],{"class":969},"'Could not generate an acceptable password'",[955,2166,2144],{"class":989},[955,2168,2170],{"class":957,"line":2169},26,[955,2171,1447],{"class":989},[946,2173,2177],{"className":2174,"code":2175,"filename":311,"language":2176,"meta":951,"style":951},"language-php shiki shiki-themes github-light-high-contrast github-dark-high-contrast","\u003C?php\nconst MT_BASE = 'https:\u002F\u002Fapi.main-team.org\u002Fv1';\n\nfunction mt_generate_password(): string\n{\n    \u002F\u002F 12 random bytes -> 16 URL-safe characters\n    return rtrim(strtr(base64_encode(random_bytes(12)), '+\u002F', '-_'), '=');\n}\n\nfunction mt_set_password(string $token, string $studentId): ?string\n{\n    for ($attempt = 0; $attempt \u003C 3; $attempt++) {\n        $password = mt_generate_password();\n        $ch = curl_init(MT_BASE . '\u002Fstudent\u002F' . rawurlencode($studentId) . '\u002Fpassword');\n        curl_setopt_array($ch, [\n            CURLOPT_CUSTOMREQUEST => 'PUT',\n            CURLOPT_RETURNTRANSFER => true,\n            CURLOPT_HTTPHEADER => [\n                'Authorization: Bearer ' . $token,\n                'Content-Type: application\u002Fjson',\n            ],\n            CURLOPT_POSTFIELDS => json_encode(['password' => $password]),\n            CURLOPT_TIMEOUT => 30,\n        ]);\n        $raw = curl_exec($ch);\n        $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);\n        curl_close($ch);\n\n        if ($status === 200) {\n            return $password; \u002F\u002F deliver it to the student; never log it\n        }\n        $error = json_decode($raw, true)['error'] ?? [];\n        if ($status === 409) {\n            return null; \u002F\u002F confirmed student: use a sign-in link instead\n        }\n        if ($status === 400 && str_contains($error['message'] ?? '', \"student's own\")) {\n            continue;\n        }\n        throw new RuntimeException(\"$status {$error['code']}: {$error['message']} (request {$error['request_id']})\");\n    }\n    throw new RuntimeException('Could not generate an acceptable password');\n}\n","php",[426,2178,2179,2187,2200,2204,2221,2225,2230,2276,2280,2284,2309,2313,2339,2350,2386,2394,2407,2419,2429,2439,2446,2451,2472,2484,2489,2502,2520,2528,2533,2549,2560,2566,2597,2610,2621,2626,2662,2670,2675,2714,2720,2735],{"__ignoreMap":951},[955,2180,2181,2184],{"class":957,"line":958},[955,2182,2183],{"class":976},"\u003C?",[955,2185,2186],{"class":965},"php\n",[955,2188,2189,2191,2194,2196,2198],{"class":957,"line":980},[955,2190,1738],{"class":976},[955,2192,2193],{"class":965}," MT_BASE",[955,2195,1744],{"class":976},[955,2197,1747],{"class":969},[955,2199,1727],{"class":989},[955,2201,2202],{"class":957,"line":998},[955,2203,1733],{"emptyLinePlaceholder":1732},[955,2205,2206,2209,2212,2215,2218],{"class":957,"line":1008},[955,2207,2208],{"class":976},"function",[955,2210,2211],{"class":1764}," mt_generate_password",[955,2213,2214],{"class":989},"()",[955,2216,2217],{"class":976},":",[955,2219,2220],{"class":976}," string\n",[955,2222,2223],{"class":957,"line":1017},[955,2224,1205],{"class":989},[955,2226,2227],{"class":957,"line":1023},[955,2228,2229],{"class":1798},"    \u002F\u002F 12 random bytes -> 16 URL-safe characters\n",[955,2231,2232,2235,2238,2240,2243,2245,2248,2250,2253,2255,2257,2260,2263,2265,2268,2271,2274],{"class":957,"line":1029},[955,2233,2234],{"class":976},"    return",[955,2236,2237],{"class":965}," rtrim",[955,2239,1779],{"class":989},[955,2241,2242],{"class":965},"strtr",[955,2244,1779],{"class":989},[955,2246,2247],{"class":965},"base64_encode",[955,2249,1779],{"class":989},[955,2251,2252],{"class":1764},"random_bytes",[955,2254,1779],{"class":989},[955,2256,1782],{"class":965},[955,2258,2259],{"class":989},")), ",[955,2261,2262],{"class":969},"'+\u002F'",[955,2264,492],{"class":989},[955,2266,2267],{"class":969},"'-_'",[955,2269,2270],{"class":989},"), ",[955,2272,2273],{"class":969},"'='",[955,2275,2144],{"class":989},[955,2277,2278],{"class":957,"line":1035},[955,2279,1447],{"class":989},[955,2281,2282],{"class":957,"line":1041},[955,2283,1733],{"emptyLinePlaceholder":1732},[955,2285,2286,2288,2291,2293,2296,2299,2301,2304,2306],{"class":957,"line":1047},[955,2287,2208],{"class":976},[955,2289,2290],{"class":1764}," mt_set_password",[955,2292,1779],{"class":989},[955,2294,2295],{"class":976},"string",[955,2297,2298],{"class":989}," $token, ",[955,2300,2295],{"class":976},[955,2302,2303],{"class":989}," $studentId)",[955,2305,2217],{"class":976},[955,2307,2308],{"class":976}," ?string\n",[955,2310,2311],{"class":957,"line":1053},[955,2312,1205],{"class":989},[955,2314,2315,2318,2321,2323,2325,2328,2330,2332,2335,2337],{"class":957,"line":1059},[955,2316,2317],{"class":976},"    for",[955,2319,2320],{"class":989}," ($attempt ",[955,2322,1849],{"class":976},[955,2324,1852],{"class":965},[955,2326,2327],{"class":989},"; $attempt ",[955,2329,1858],{"class":976},[955,2331,1861],{"class":965},[955,2333,2334],{"class":989},"; $attempt",[955,2336,1867],{"class":976},[955,2338,1832],{"class":989},[955,2340,2341,2344,2346,2348],{"class":957,"line":1065},[955,2342,2343],{"class":989},"        $password ",[955,2345,1849],{"class":976},[955,2347,2211],{"class":1764},[955,2349,1884],{"class":989},[955,2351,2352,2355,2357,2360,2362,2365,2368,2371,2373,2376,2379,2381,2384],{"class":957,"line":1071},[955,2353,2354],{"class":989},"        $ch ",[955,2356,1849],{"class":976},[955,2358,2359],{"class":965}," curl_init",[955,2361,1779],{"class":989},[955,2363,2364],{"class":965},"MT_BASE",[955,2366,2367],{"class":976}," .",[955,2369,2370],{"class":969}," '\u002Fstudent\u002F'",[955,2372,2367],{"class":976},[955,2374,2375],{"class":965}," rawurlencode",[955,2377,2378],{"class":989},"($studentId) ",[955,2380,508],{"class":976},[955,2382,2383],{"class":969}," '\u002Fpassword'",[955,2385,2144],{"class":989},[955,2387,2388,2391],{"class":957,"line":1077},[955,2389,2390],{"class":965},"        curl_setopt_array",[955,2392,2393],{"class":989},"($ch, [\n",[955,2395,2396,2399,2402,2405],{"class":957,"line":1373},[955,2397,2398],{"class":965},"            CURLOPT_CUSTOMREQUEST",[955,2400,2401],{"class":976}," =>",[955,2403,2404],{"class":969}," 'PUT'",[955,2406,817],{"class":989},[955,2408,2409,2412,2414,2417],{"class":957,"line":1386},[955,2410,2411],{"class":965},"            CURLOPT_RETURNTRANSFER",[955,2413,2401],{"class":976},[955,2415,2416],{"class":965}," true",[955,2418,817],{"class":989},[955,2420,2421,2424,2426],{"class":957,"line":1399},[955,2422,2423],{"class":965},"            CURLOPT_HTTPHEADER",[955,2425,2401],{"class":976},[955,2427,2428],{"class":989}," [\n",[955,2430,2431,2434,2436],{"class":957,"line":1414},[955,2432,2433],{"class":969},"                'Authorization: Bearer '",[955,2435,2367],{"class":976},[955,2437,2438],{"class":989}," $token,\n",[955,2440,2441,2444],{"class":957,"line":1427},[955,2442,2443],{"class":969},"                'Content-Type: application\u002Fjson'",[955,2445,817],{"class":989},[955,2447,2448],{"class":957,"line":1438},[955,2449,2450],{"class":989},"            ],\n",[955,2452,2453,2456,2458,2461,2464,2467,2469],{"class":957,"line":1444},[955,2454,2455],{"class":965},"            CURLOPT_POSTFIELDS",[955,2457,2401],{"class":976},[955,2459,2460],{"class":965}," json_encode",[955,2462,2463],{"class":989},"([",[955,2465,2466],{"class":969},"'password'",[955,2468,2401],{"class":976},[955,2470,2471],{"class":989}," $password]),\n",[955,2473,2474,2477,2479,2482],{"class":957,"line":2088},[955,2475,2476],{"class":965},"            CURLOPT_TIMEOUT",[955,2478,2401],{"class":976},[955,2480,2481],{"class":965}," 30",[955,2483,817],{"class":989},[955,2485,2486],{"class":957,"line":2147},[955,2487,2488],{"class":989},"        ]);\n",[955,2490,2491,2494,2496,2499],{"class":957,"line":2152},[955,2492,2493],{"class":989},"        $raw ",[955,2495,1849],{"class":976},[955,2497,2498],{"class":965}," curl_exec",[955,2500,2501],{"class":989},"($ch);\n",[955,2503,2504,2507,2509,2512,2515,2518],{"class":957,"line":2169},[955,2505,2506],{"class":989},"        $status ",[955,2508,1849],{"class":976},[955,2510,2511],{"class":965}," curl_getinfo",[955,2513,2514],{"class":989},"($ch, ",[955,2516,2517],{"class":965},"CURLINFO_RESPONSE_CODE",[955,2519,2144],{"class":989},[955,2521,2523,2526],{"class":957,"line":2522},27,[955,2524,2525],{"class":965},"        curl_close",[955,2527,2501],{"class":989},[955,2529,2531],{"class":957,"line":2530},28,[955,2532,1733],{"emptyLinePlaceholder":1732},[955,2534,2536,2539,2542,2544,2547],{"class":957,"line":2535},29,[955,2537,2538],{"class":976},"        if",[955,2540,2541],{"class":989}," ($status ",[955,2543,2030],{"class":976},[955,2545,2546],{"class":965}," 200",[955,2548,1832],{"class":989},[955,2550,2552,2555,2558],{"class":957,"line":2551},30,[955,2553,2554],{"class":976},"            return",[955,2556,2557],{"class":989}," $password; ",[955,2559,1992],{"class":1798},[955,2561,2563],{"class":957,"line":2562},31,[955,2564,2565],{"class":989},"        }\n",[955,2567,2569,2572,2574,2577,2580,2582,2585,2588,2591,2594],{"class":957,"line":2568},32,[955,2570,2571],{"class":989},"        $error ",[955,2573,1849],{"class":976},[955,2575,2576],{"class":965}," json_decode",[955,2578,2579],{"class":989},"($raw, ",[955,2581,1216],{"class":965},[955,2583,2584],{"class":989},")[",[955,2586,2587],{"class":969},"'error'",[955,2589,2590],{"class":989},"] ",[955,2592,2593],{"class":976},"??",[955,2595,2596],{"class":989}," [];\n",[955,2598,2600,2602,2604,2606,2608],{"class":957,"line":2599},33,[955,2601,2538],{"class":976},[955,2603,2541],{"class":989},[955,2605,2030],{"class":976},[955,2607,2033],{"class":965},[955,2609,1832],{"class":989},[955,2611,2613,2615,2617,2619],{"class":957,"line":2612},34,[955,2614,2554],{"class":976},[955,2616,2041],{"class":965},[955,2618,2044],{"class":989},[955,2620,2047],{"class":1798},[955,2622,2624],{"class":957,"line":2623},35,[955,2625,2565],{"class":989},[955,2627,2629,2631,2633,2635,2637,2639,2642,2645,2648,2650,2652,2655,2657,2659],{"class":957,"line":2628},36,[955,2630,2538],{"class":976},[955,2632,2541],{"class":989},[955,2634,2030],{"class":976},[955,2636,2063],{"class":965},[955,2638,2066],{"class":976},[955,2640,2641],{"class":965}," str_contains",[955,2643,2644],{"class":989},"($error[",[955,2646,2647],{"class":969},"'message'",[955,2649,2590],{"class":989},[955,2651,2593],{"class":976},[955,2653,2654],{"class":969}," ''",[955,2656,492],{"class":989},[955,2658,2077],{"class":969},[955,2660,2661],{"class":989},")) {\n",[955,2663,2665,2668],{"class":957,"line":2664},37,[955,2666,2667],{"class":976},"            continue",[955,2669,1727],{"class":989},[955,2671,2673],{"class":957,"line":2672},38,[955,2674,2565],{"class":989},[955,2676,2678,2681,2683,2686,2688,2690,2693,2696,2699,2702,2704,2707,2709,2712],{"class":957,"line":2677},39,[955,2679,2680],{"class":976},"        throw",[955,2682,2094],{"class":976},[955,2684,2685],{"class":965}," RuntimeException",[955,2687,1779],{"class":989},[955,2689,993],{"class":969},[955,2691,2692],{"class":989},"$status",[955,2694,2695],{"class":969}," {",[955,2697,2698],{"class":989},"$error",[955,2700,2701],{"class":969},"['code']}: {",[955,2703,2698],{"class":989},[955,2705,2706],{"class":969},"['message']} (request {",[955,2708,2698],{"class":989},[955,2710,2711],{"class":969},"['request_id']})\"",[955,2713,2144],{"class":989},[955,2715,2717],{"class":957,"line":2716},40,[955,2718,2719],{"class":989},"    }\n",[955,2721,2723,2725,2727,2729,2731,2733],{"class":957,"line":2722},41,[955,2724,2091],{"class":976},[955,2726,2094],{"class":976},[955,2728,2685],{"class":965},[955,2730,1779],{"class":989},[955,2732,2164],{"class":969},[955,2734,2144],{"class":989},[955,2736,2738],{"class":957,"line":2737},42,[955,2739,1447],{"class":989},[525,2741,2743],{"type":2742},"security",[358,2744,2745,2748,2749,2751],{},[480,2746,2747],{},"Treat a password like a secret from the moment you generate it."," Keep it out of logs, analytics and\nerror reports. Get it to the student over a channel you already trust, and do not keep it after it\nhas been delivered. The API cannot show it again, and neither should your system. Redact request\nbodies of this route in any HTTP logging you run. ",[362,2750,51],{"href":52}," has more on handling\nstudent credentials.",[367,2753,42],{"id":2754},"errors",[375,2756,2757,2776],{},[378,2758,2759],{},[381,2760,2761,2764,2767,2770,2773],{},[384,2762,2763],{},"Status",[384,2765,2766],{},"Code",[384,2768,2769],{},"Message",[384,2771,2772],{},"Cause",[384,2774,2775],{},"Fix",[393,2777,2778,2804,2825,2847,2869,2895,2920,2947,2975,2997],{},[381,2779,2780,2784,2792,2796,2801],{},[398,2781,2782],{},[426,2783,615],{},[398,2785,2786],{},[362,2787,2789],{"href":2788},"\u002Fapi\u002Ferrors#bad_request",[426,2790,2791],{},"bad_request",[398,2793,2794],{},[426,2795,668],{},[398,2797,2798,2800],{},[426,2799,559],{}," is not a string.",[398,2802,2803],{},"Send a string.",[381,2805,2806,2810,2816,2819,2822],{},[398,2807,2808],{},[426,2809,615],{},[398,2811,2812],{},[362,2813,2814],{"href":2788},[426,2815,2791],{},[398,2817,2818],{},"a message naming the 5-character minimum",[398,2820,2821],{},"Shorter than 5 characters, or empty.",[398,2823,2824],{},"Send a longer password.",[381,2826,2827,2831,2837,2841,2844],{},[398,2828,2829],{},[426,2830,615],{},[398,2832,2833],{},[362,2834,2835],{"href":2788},[426,2836,2791],{},[398,2838,2839],{},[426,2840,691],{},[398,2842,2843],{},"Over 72 UTF-8 bytes.",[398,2845,2846],{},"Shorten it; count bytes, not characters.",[381,2848,2849,2853,2859,2863,2866],{},[398,2850,2851],{},[426,2852,615],{},[398,2854,2855],{},[362,2856,2857],{"href":2788},[426,2858,2791],{},[398,2860,2861],{},[426,2862,706],{},[398,2864,2865],{},"Built from the student's details.",[398,2867,2868],{},"Generate a random password.",[381,2870,2871,2875,2881,2885,2890],{},[398,2872,2873],{},[426,2874,615],{},[398,2876,2877],{},[362,2878,2879],{"href":2788},[426,2880,2791],{},[398,2882,2883],{},[426,2884,618],{},[398,2886,2887,2889],{},[426,2888,559],{}," sent to a student update route.",[398,2891,2892,2893,508],{},"Use ",[426,2894,591],{},[381,2896,2897,2901,2907,2911,2914],{},[398,2898,2899],{},[426,2900,615],{},[398,2902,2903],{},[362,2904,2905],{"href":2788},[426,2906,2791],{},[398,2908,2909],{},[426,2910,1499],{},[398,2912,2913],{},"Another field in the password route's body.",[398,2915,2916,2917,2919],{},"Send ",[426,2918,559],{}," only.",[381,2921,2922,2926,2932,2936,2944],{},[398,2923,2924],{},[426,2925,522],{},[398,2927,2928],{},[362,2929,2930],{"href":1119},[426,2931,1122],{},[398,2933,2934],{},[426,2935,1480],{},[398,2937,2938,2939,434,2941,2943],{},"No ",[426,2940,428],{},[426,2942,437],{}," for the password route.",[398,2945,2946],{},"Ask the operator for the permission.",[381,2948,2949,2953,2959,2963,2969],{},[398,2950,2951],{},[426,2952,522],{},[398,2954,2955],{},[362,2956,2957],{"href":1119},[426,2958,1122],{},[398,2960,2961],{},[426,2962,1126],{},[398,2964,2965,2966,2968],{},"A registration with ",[426,2967,559],{}," from an account without the permission.",[398,2970,2971,2972,2974],{},"Register without ",[426,2973,559],{},", or get the permission.",[381,2976,2977,2981,2987,2991,2994],{},[398,2978,2979],{},[426,2980,1513],{},[398,2982,2983],{},[362,2984,2985],{"href":1516},[426,2986,1519],{},[398,2988,2989],{},[426,2990,1522],{},[398,2992,2993],{},"No such student on your account, or the student confirmed their email at that very moment.",[398,2995,2996],{},"Check the id; read the student again.",[381,2998,2999,3003,3009,3014,3017],{},[398,3000,3001],{},[426,3002,451],{},[398,3004,3005],{},[362,3006,3007],{"href":1626},[426,3008,1629],{},[398,3010,3011],{},[426,3012,3013],{},"This student has confirmed their email address, …",[398,3015,3016],{},"The account belongs to the student now.",[398,3018,3019],{},"Send a sign-in link instead.",[358,3021,3022],{},"When a request breaks several rules at once, the message names one of them. Fix it and send again.",[367,3024,3026],{"id":3025},"related","Related",[1093,3028,3029,3034,3042],{},[1096,3030,3031,3033],{},[362,3032,80],{"href":81},": the single-use alternative, and what the student sees.",[1096,3035,3036,3038,3039,3041],{},[362,3037,62],{"href":63},": registration, ",[426,3040,1659],{},", and changing a student's email.",[1096,3043,3044,3046,3047,3049],{},[362,3045,25],{"href":26},": how ",[426,3048,428],{}," and its target are matched.",[3051,3052,3053],"style",{},"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 .sT6z2, html code.shiki .sT6z2{--shiki-default:#032563;--shiki-dark:#ADDCFF}html pre.shiki code .sHUrx, html code.shiki .sHUrx{--shiki-default:#A0111F;--shiki-dark:#FF9492}html pre.shiki code .suds8, html code.shiki .suds8{--shiki-default:#0E1116;--shiki-dark:#F0F3F6}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 .sne4z, html code.shiki .sne4z{--shiki-default:#024C1A;--shiki-dark:#72F088}html pre.shiki code .sKwhi, html code.shiki .sKwhi{--shiki-default:#622CBC;--shiki-dark:#DBB7FF}html pre.shiki code .sLBg1, html code.shiki .sLBg1{--shiki-default:#66707B;--shiki-dark:#BDC4CC}",{"title":951,"searchDepth":980,"depth":998,"links":3055},[3056,3057,3058,3059,3063,3064,3067,3068,3069,3070],{"id":369,"depth":980,"text":370},{"id":471,"depth":980,"text":472},{"id":541,"depth":980,"text":542},{"id":639,"depth":980,"text":640,"children":3060},[3061,3062],{"id":717,"depth":998,"text":718},{"id":806,"depth":998,"text":807},{"id":928,"depth":980,"text":929},{"id":1141,"depth":980,"text":1142,"children":3065},[3066],{"id":1460,"depth":998,"text":1461},{"id":1547,"depth":980,"text":1548},{"id":1700,"depth":980,"text":713},{"id":2754,"depth":980,"text":42},{"id":3025,"depth":980,"text":3026},"Set a student's sign-in password at registration or later, with the permission it needs, the rules it must meet, and when it is refused.","md",{},[3075,3076],"setStudentPassword","registerStudent","20",{"title":353,"description":3071},"api\u002Fguides\u002Fpasswords","eiH3lkhdsrmQ5MpfggDmiT-CLb3V9PCOJUeuriXLcbo",[3082,3087],{"operationId":3075,"slug":3083,"method":190,"path":3084,"tag":62,"summary":192,"deprecated":134,"public":134,"permission":3085,"scope":3086,"order":1386},"set-student-password","\u002Fv1\u002Fstudent\u002F{studentId}\u002Fpassword","auth\u002Fsignin:$org:$ID","flat",{"operationId":3076,"slug":3088,"method":141,"path":3089,"tag":62,"summary":173,"deprecated":134,"public":134,"permission":3090,"scope":3086,"order":1053},"register-student","\u002Fv1\u002Fstudent","student\u002Fcreate:$org:$ID",1791554615065]