[{"data":1,"prerenderedAt":1074},["ShallowReactive",2],{"navigation":3,"\u002Fguides\u002Femail-code":250,"\u002Fguides\u002Femail-code-surround":1069},[4,43,120,143,219],{"title":5,"path":6,"stem":7,"children":8,"icon":42},"Get started","\u002Fgetting-started","1.getting-started\u002F1.index",[9,12,17,22,27,32,37],{"title":10,"path":6,"stem":7,"icon":11},"Introduction","i-lucide-house",{"title":13,"path":14,"stem":15,"icon":16},"Install AuthEndpoints","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":18,"path":19,"stem":20,"icon":21},"Quick start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F3.quick-start","i-lucide-play",{"title":23,"path":24,"stem":25,"icon":26},"Pick your setup","\u002Fgetting-started\u002Fchoose-a-sign-in-stack","1.getting-started\u002F4.choose-a-sign-in-stack","i-lucide-signpost",{"title":28,"path":29,"stem":30,"icon":31},"Use the AuthEndpoints skill with coding agents","\u002Fgetting-started\u002Fai-agents","1.getting-started\u002F5.ai-agents","i-lucide-bot",{"title":33,"path":34,"stem":35,"icon":36},"Password auth","\u002Fgetting-started\u002Fpassword-auth","1.getting-started\u002F6.password-auth","i-lucide-key-round",{"title":38,"path":39,"stem":40,"icon":41},"3.x facade","\u002Fgetting-started\u002Fcompatibility-facade","1.getting-started\u002F7.compatibility-facade","i-lucide-archive","i-lucide-rocket",{"title":44,"path":45,"stem":46,"children":47,"icon":119},"Guides","\u002Fguides","2.guides\u002F01.index",[48,50,55,60,65,70,74,79,84,89,94,99,104,109,114],{"title":44,"path":45,"stem":46,"icon":49},"i-lucide-list-checks",{"title":51,"path":52,"stem":53,"icon":54},"Register users","\u002Fguides\u002Fregistration","2.guides\u002F02.registration","i-lucide-user-plus",{"title":56,"path":57,"stem":58,"icon":59},"Sign users in","\u002Fguides\u002Fsign-in","2.guides\u002F03.sign-in","i-lucide-log-in",{"title":61,"path":62,"stem":63,"icon":64},"Sign users out","\u002Fguides\u002Fsign-out","2.guides\u002F04.sign-out","i-lucide-log-out",{"title":66,"path":67,"stem":68,"icon":69},"Turn on two-factor authentication","\u002Fguides\u002Ftwo-factor","2.guides\u002F05.two-factor","i-lucide-smartphone",{"title":71,"path":72,"stem":73,"icon":36},"Reset a forgotten password","\u002Fguides\u002Freset-password","2.guides\u002F06.reset-password",{"title":75,"path":76,"stem":77,"icon":78},"Change a user's email or password","\u002Fguides\u002Fmanage-account","2.guides\u002F07.manage-account","i-lucide-user-cog",{"title":80,"path":81,"stem":82,"icon":83},"Add, rename, and remove passkeys","\u002Fguides\u002Fmanage-passkeys","2.guides\u002F08.manage-passkeys","i-lucide-scan-face",{"title":85,"path":86,"stem":87,"icon":88},"Link and unlink GitHub or Google accounts","\u002Fguides\u002Flink-external-accounts","2.guides\u002F09.link-external-accounts","i-lucide-link",{"title":90,"path":91,"stem":92,"icon":93},"Require step-up before sensitive actions","\u002Fguides\u002Fstep-up","2.guides\u002F10.step-up","i-lucide-shield-check",{"title":95,"path":96,"stem":97,"icon":98},"Call the API from a browser","\u002Fguides\u002Fbrowser-clients","2.guides\u002F11.browser-clients","i-lucide-globe",{"title":100,"path":101,"stem":102,"icon":103},"Prepare for production","\u002Fguides\u002Fproduction","2.guides\u002F12.production","i-lucide-factory",{"title":105,"path":106,"stem":107,"icon":108},"Sign in with an emailed code","\u002Fguides\u002Femail-code","2.guides\u002F13.email-code","i-lucide-mail",{"title":110,"path":111,"stem":112,"icon":113},"Upgrade to 4.0","\u002Fguides\u002Fupgrading-to-4","2.guides\u002F14.upgrading-to-4","i-lucide-arrow-up-right",{"title":115,"path":116,"stem":117,"icon":118},"Run an app with no public sign-up","\u002Fguides\u002Finternal-app","2.guides\u002F15.internal-app","i-lucide-building-2","i-lucide-waypoints",{"title":121,"path":122,"stem":123,"children":124,"icon":142},"Composable endpoints","\u002Fcomposables","3.composables\u002F1.index",[125,128,132,137],{"title":126,"path":122,"stem":123,"icon":127},"How composition works","i-lucide-layout-grid",{"title":129,"path":130,"stem":131,"icon":49},"Composition requirements","\u002Fcomposables\u002Frequirements","3.composables\u002F2.requirements",{"title":133,"path":134,"stem":135,"icon":136},"Compose a custom auth stack","\u002Fcomposables\u002Frecipes","3.composables\u002F3.recipes","i-lucide-book-marked",{"title":138,"path":139,"stem":140,"icon":141},"Composition","\u002Fcomposables\u002Fcomposition","3.composables\u002F4.composition","i-lucide-table","i-lucide-blocks",{"title":144,"icon":145,"path":146,"stem":147,"children":148,"page":218},"Reference","i-lucide-book-open","\u002Fmodules","4.modules",[149,154,158,163,168,173,177,182,186,191,195,200,205,209,213],{"title":150,"path":151,"stem":152,"icon":153},"Endpoint reference","\u002Fmodules\u002Fendpoints","4.modules\u002F01.endpoints","i-lucide-route",{"title":155,"path":156,"stem":157,"icon":78},"Identity management module","\u002Fmodules\u002Fidentity-management","4.modules\u002F02.identity-management",{"title":159,"path":160,"stem":161,"icon":162},"Cookie sign-in module","\u002Fmodules\u002Fcookie-auth","4.modules\u002F03.cookie-auth","i-lucide-cookie",{"title":164,"path":165,"stem":166,"icon":167},"Identity bearer sign-in module","\u002Fmodules\u002Fbearer-auth","4.modules\u002F04.bearer-auth","i-lucide-key",{"title":169,"path":170,"stem":171,"icon":172},"JWT module","\u002Fmodules\u002Fjwt","4.modules\u002F05.jwt","i-lucide-fingerprint",{"title":174,"path":175,"stem":176,"icon":83},"Passkeys module","\u002Fmodules\u002Fpasskeys","4.modules\u002F06.passkeys",{"title":178,"path":179,"stem":180,"icon":181},"ReAuth module","\u002Fmodules\u002Freauth","4.modules\u002F07.reauth","i-lucide-shield-alert",{"title":183,"path":184,"stem":185,"icon":59},"External OAuth packages","\u002Fmodules\u002Fexternal-oauth","4.modules\u002F08.external-oauth",{"title":187,"path":188,"stem":189,"icon":190},"Configuration options","\u002Fmodules\u002Fconfiguration","4.modules\u002F09.configuration","i-lucide-settings",{"title":192,"path":193,"stem":194,"icon":93},"Antiforgery (CSRF) rules","\u002Fmodules\u002Fcsrf","4.modules\u002F10.csrf",{"title":196,"path":197,"stem":198,"icon":199},"Responses and errors","\u002Fmodules\u002Ferrors","4.modules\u002F11.errors","i-lucide-circle-alert",{"title":201,"path":202,"stem":203,"icon":204},"Rate-limit policies","\u002Fmodules\u002Frate-limits","4.modules\u002F12.rate-limits","i-lucide-gauge",{"title":206,"path":207,"stem":208,"icon":108},"Email-code module","\u002Fmodules\u002Femail-code","4.modules\u002F13.email-code",{"title":210,"path":211,"stem":212,"icon":59},"Sign-in completer","\u002Fmodules\u002Fsign-in-completer","4.modules\u002F14.sign-in-completer",{"title":214,"path":215,"stem":216,"icon":217},"Enumeration-safe responses","\u002Fmodules\u002Fenumeration","4.modules\u002F15.enumeration","i-lucide-eye-off",false,{"title":220,"icon":221,"path":222,"stem":223,"children":224,"page":218},"Concepts","i-lucide-lightbulb","\u002Fconcepts","5.concepts",[225,230,235,240,245],{"title":226,"path":227,"stem":228,"icon":229},"AuthEndpoints compared with other options","\u002Fconcepts\u002Fcompare","5.concepts\u002F1.compare","i-lucide-git-compare",{"title":231,"path":232,"stem":233,"icon":234},"Stock Identity endpoints vs AuthEndpoints","\u002Fconcepts\u002Fstock-identity-vs-authendpoints","5.concepts\u002F2.stock-identity-vs-authendpoints","i-lucide-columns-2",{"title":236,"path":237,"stem":238,"icon":239},"MapIdentityApi alternative","\u002Fconcepts\u002Fmapidentityapi-alternative","5.concepts\u002F3.mapidentityapi-alternative","i-lucide-arrow-left-right",{"title":241,"path":242,"stem":243,"icon":244},"Security model","\u002Fconcepts\u002Fsecurity-model","5.concepts\u002F4.security-model","i-lucide-shield",{"title":246,"path":247,"stem":248,"icon":249},"FAQ","\u002Fconcepts\u002Ffaq","5.concepts\u002F5.faq","i-lucide-circle-help",{"id":251,"title":105,"body":252,"description":1062,"extension":1063,"faq":218,"links":1064,"meta":1065,"navigation":1066,"path":106,"seo":1067,"stem":107,"__hash__":1068},"docs\u002F2.guides\u002F13.email-code.md",{"type":253,"value":254,"toc":1054},"minimark",[255,268,276,281,743,767,771,789,798,818,822,837,858,867,884,888,909,915,928,932,952,959,991,1010,1015,1019,1050],[256,257,258,259,263,264,267],"p",{},"Email-code sign-in stays off until you map it. ",[260,261,262],"code",{},"AddPasswordAuth"," does not map these routes. ",[260,265,266],{},"AllowSignUp"," and the magic link default to off.",[256,269,270,271,275],{},"Request bodies, status codes, and option defaults are in the ",[272,273,206],"a",{"href":274},"\u002Fmodules\u002Femail-code\u002F",".",[277,278,280],"h2",{"id":279},"turn-it-on","Turn it on",[282,283,284,399,420,661],"ol",{},[285,286,287,288,291,292,295,296,299,300,388,391,392,395,396,275],"li",{},"Map the entity and add a migration. ",[260,289,290],{},"MapEmailCodeEndpoints"," throws ",[260,293,294],{},"NotSupportedException"," if ",[260,297,298],{},"UseEmailCodes()"," was not called.",[301,302,307],"pre",{"className":303,"code":304,"language":305,"meta":306,"style":306},"language-cs shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","protected override void OnModelCreating(ModelBuilder builder)\n{\n    base.OnModelCreating(builder);\n    builder.UseEmailCodes();\n}\n","cs","",[260,308,309,342,348,368,382],{"__ignoreMap":306},[310,311,314,318,321,325,329,332,336,339],"span",{"class":312,"line":313},"line",1,[310,315,317],{"class":316},"spNyl","protected",[310,319,320],{"class":316}," override",[310,322,324],{"class":323},"sMK4o"," void",[310,326,328],{"class":327},"s2Zo4"," OnModelCreating",[310,330,331],{"class":323},"(",[310,333,335],{"class":334},"sBMFI","ModelBuilder",[310,337,338],{"class":334}," builder",[310,340,341],{"class":323},")\n",[310,343,345],{"class":312,"line":344},2,[310,346,347],{"class":323},"{\n",[310,349,351,355,357,360,362,365],{"class":312,"line":350},3,[310,352,354],{"class":353},"sTEyZ","    base",[310,356,275],{"class":323},[310,358,359],{"class":327},"OnModelCreating",[310,361,331],{"class":323},[310,363,364],{"class":353},"builder",[310,366,367],{"class":323},");\n",[310,369,371,374,376,379],{"class":312,"line":370},4,[310,372,373],{"class":353},"    builder",[310,375,275],{"class":323},[310,377,378],{"class":327},"UseEmailCodes",[310,380,381],{"class":323},"();\n",[310,383,385],{"class":312,"line":384},5,[310,386,387],{"class":323},"}\n",[389,390],"br",{},"4.0 adds a ",[260,393,394],{},"Purpose"," column. Generate that migration before you deploy. See ",[272,397,110],{"href":398},"\u002Fguides\u002Fupgrading-to-4\u002F#email-code-table-gains-purpose",[285,400,401,402,405,406,409,410,412,413,416,417,275],{},"Register ",[260,403,404],{},"IEmailCodeSender\u003CTUser>",". In Development, if you register none, AuthEndpoints logs the raw code with ",[260,407,408],{},"DevelopmentEmailCodeSender\u003CTUser>",". Outside Development, register your own sender. Startup fails when the sender is ",[260,411,408],{},", or when no sender is registered, unless ",[260,414,415],{},"RequireSenderOutsideDevelopment"," is ",[260,418,419],{},"false",[285,421,422,423,291,426,429,430,433,653,655,656,660],{},"Register email-code services and map send and verify on one group. Pass the session that verify should finish in. A missing ",[260,424,425],{},"AddEmailCodeEndpoints",[260,427,428],{},"InvalidOperationException"," with the message ",[260,431,432],{},"Call AddEmailCodeEndpoints before MapEmailCodeEndpoints.",[301,434,436],{"className":303,"code":435,"language":305,"meta":306,"style":306},"builder.Services.AddAuthEndpointsIdentity\u003CAppUser, AppDbContext>();\nbuilder.Services.AddCookieSessionEndpoints();\nbuilder.Services.AddAccountManagementEndpoints();\nbuilder.Services.AddEmailCodeEndpoints\u003CAppUser, AppDbContext>();\n\nvar app = builder.Build();\napp.UseAuthEndpoints();\n\nvar identity = app.MapGroup(\"\u002Fidentity\");\nidentity.MapEmailCodeEndpoints\u003CAppUser>(AuthEndpointsSession.Cookie);\nidentity.MapCookieSessionEndpoints\u003CAppUser>();\nidentity.MapAccountManagementEndpoints\u003CAppUser>();\n",[260,437,438,467,482,497,519,525,546,559,564,594,621,637],{"__ignoreMap":306},[310,439,440,442,444,447,449,452,455,458,461,464],{"class":312,"line":313},[310,441,364],{"class":353},[310,443,275],{"class":323},[310,445,446],{"class":353},"Services",[310,448,275],{"class":323},[310,450,451],{"class":327},"AddAuthEndpointsIdentity",[310,453,454],{"class":323},"\u003C",[310,456,457],{"class":334},"AppUser",[310,459,460],{"class":323},",",[310,462,463],{"class":334}," AppDbContext",[310,465,466],{"class":323},">();\n",[310,468,469,471,473,475,477,480],{"class":312,"line":344},[310,470,364],{"class":353},[310,472,275],{"class":323},[310,474,446],{"class":353},[310,476,275],{"class":323},[310,478,479],{"class":327},"AddCookieSessionEndpoints",[310,481,381],{"class":323},[310,483,484,486,488,490,492,495],{"class":312,"line":350},[310,485,364],{"class":353},[310,487,275],{"class":323},[310,489,446],{"class":353},[310,491,275],{"class":323},[310,493,494],{"class":327},"AddAccountManagementEndpoints",[310,496,381],{"class":323},[310,498,499,501,503,505,507,509,511,513,515,517],{"class":312,"line":370},[310,500,364],{"class":353},[310,502,275],{"class":323},[310,504,446],{"class":353},[310,506,275],{"class":323},[310,508,425],{"class":327},[310,510,454],{"class":323},[310,512,457],{"class":334},[310,514,460],{"class":323},[310,516,463],{"class":334},[310,518,466],{"class":323},[310,520,521],{"class":312,"line":384},[310,522,524],{"emptyLinePlaceholder":523},true,"\n",[310,526,528,531,534,537,539,541,544],{"class":312,"line":527},6,[310,529,530],{"class":334},"var",[310,532,533],{"class":334}," app",[310,535,536],{"class":323}," =",[310,538,338],{"class":353},[310,540,275],{"class":323},[310,542,543],{"class":327},"Build",[310,545,381],{"class":323},[310,547,549,552,554,557],{"class":312,"line":548},7,[310,550,551],{"class":353},"app",[310,553,275],{"class":323},[310,555,556],{"class":327},"UseAuthEndpoints",[310,558,381],{"class":323},[310,560,562],{"class":312,"line":561},8,[310,563,524],{"emptyLinePlaceholder":523},[310,565,567,569,572,574,576,578,581,583,586,590,592],{"class":312,"line":566},9,[310,568,530],{"class":334},[310,570,571],{"class":334}," identity",[310,573,536],{"class":323},[310,575,533],{"class":353},[310,577,275],{"class":323},[310,579,580],{"class":327},"MapGroup",[310,582,331],{"class":323},[310,584,585],{"class":323},"\"",[310,587,589],{"class":588},"sfazB","\u002Fidentity",[310,591,585],{"class":323},[310,593,367],{"class":323},[310,595,597,600,602,604,606,608,611,614,616,619],{"class":312,"line":596},10,[310,598,599],{"class":353},"identity",[310,601,275],{"class":323},[310,603,290],{"class":327},[310,605,454],{"class":323},[310,607,457],{"class":334},[310,609,610],{"class":323},">(",[310,612,613],{"class":353},"AuthEndpointsSession",[310,615,275],{"class":323},[310,617,618],{"class":353},"Cookie",[310,620,367],{"class":323},[310,622,624,626,628,631,633,635],{"class":312,"line":623},11,[310,625,599],{"class":353},[310,627,275],{"class":323},[310,629,630],{"class":327},"MapCookieSessionEndpoints",[310,632,454],{"class":323},[310,634,457],{"class":334},[310,636,466],{"class":323},[310,638,640,642,644,647,649,651],{"class":312,"line":639},12,[310,641,599],{"class":353},[310,643,275],{"class":323},[310,645,646],{"class":327},"MapAccountManagementEndpoints",[310,648,454],{"class":323},[310,650,457],{"class":334},[310,652,466],{"class":323},[389,654],{},"A host that skips password register and login is ",[272,657,659],{"href":658},"\u002Fcomposables\u002Frecipes\u002F#email-code-only","Email-code only",". That sample also turns the magic link on.",[285,662,663,664,667,668,671,672,275,675],{},"On the 3.x facade, set ",[260,665,666],{},"EmailCode.Enabled"," to ",[260,669,670],{},"true"," instead of mapping the group yourself. That map keeps Identity bearer verify. It ignores ",[260,673,674],{},"SignInCompletionOptions.Default",[301,676,678],{"className":303,"code":677,"language":305,"meta":306,"style":306},"builder.Services.AddAuthEndpoints\u003CAppUser, AppDbContext>(o =>\n{\n    o.EmailCode.Enabled = true;\n});\n",[260,679,680,709,713,738],{"__ignoreMap":306},[310,681,682,684,686,688,690,693,695,697,699,701,703,706],{"class":312,"line":313},[310,683,364],{"class":353},[310,685,275],{"class":323},[310,687,446],{"class":353},[310,689,275],{"class":323},[310,691,692],{"class":327},"AddAuthEndpoints",[310,694,454],{"class":323},[310,696,457],{"class":334},[310,698,460],{"class":323},[310,700,463],{"class":334},[310,702,610],{"class":323},[310,704,705],{"class":334},"o",[310,707,708],{"class":323}," =>\n",[310,710,711],{"class":312,"line":344},[310,712,347],{"class":323},[310,714,715,718,720,723,725,728,731,735],{"class":312,"line":350},[310,716,717],{"class":353},"    o",[310,719,275],{"class":323},[310,721,722],{"class":353},"EmailCode",[310,724,275],{"class":323},[310,726,727],{"class":353},"Enabled ",[310,729,730],{"class":323},"=",[310,732,734],{"class":733},"sfNiH"," true",[310,736,737],{"class":323},";\n",[310,739,740],{"class":312,"line":370},[310,741,742],{"class":323},"});\n",[256,744,745,746,749,750,667,753,755,756,759,760,763,764,275],{},"To issue a JWT, call ",[260,747,748],{},"AddJwtEndpoints",", then pass ",[260,751,752],{},"AuthEndpointsSession.Jwt",[260,754,290],{},". ",[260,757,758],{},"Jwt.Enabled"," on the 3.x facade does not change this session. The obsolete completer types are in ",[272,761,110],{"href":762},"\u002Fguides\u002Fupgrading-to-4\u002F",". Session results are in ",[272,765,210],{"href":766},"\u002Fmodules\u002Fsign-in-completer\u002F",[277,768,770],{"id":769},"send-a-code","Send a code",[256,772,773,774,777,778,781,782,777,785,788],{},"Send ",[260,775,776],{},"POST \u002Fidentity\u002FemailCode\u002Fsend"," with ",[260,779,780],{},"{ \"email\" }",". A valid address returns ",[260,783,784],{},"200",[260,786,787],{},"{ \"expiresInSeconds\", \"resendAfterSeconds\" }",". The defaults are 10 minutes and 60 seconds.",[256,790,791,792,794,795,275],{},"The same ",[260,793,784],{}," is returned for an unknown address, a locked account, and several other cases. The list is in the ",[272,796,206],{"href":797},"\u002Fmodules\u002Femail-code\u002F#send",[256,799,800,803,804,806,807,755,810,813,814,817],{},[260,801,802],{},"Code"," is not HTML-encoded. Do not log ",[260,805,802],{}," or ",[260,808,809],{},"LinkUrl",[260,811,812],{},"POST \u002FemailCode\u002Fsend"," awaits ",[260,815,816],{},"SendSignInCodeAsync",". Queue the message and return. A sender that waits on SMTP makes a known address slower than an unknown one.",[277,819,821],{"id":820},"verify-a-code","Verify a code",[256,823,773,824,777,827,755,830,832,833,836],{},[260,825,826],{},"POST \u002Fidentity\u002FemailCode\u002Fverify",[260,828,829],{},"{ \"email\", \"code\" }",[260,831,260],{}," is exactly ",[260,834,835],{},"CodeLength"," digits. The default length is 6.",[256,838,839,840,843,844,847,848,851,852,854,855,275],{},"For the cookie session in the sample, add ",[260,841,842],{},"?useSessionCookies=true"," for a session cookie, or ",[260,845,846],{},"?useSessionCookies=false"," for a persistent cookie. ",[260,849,850],{},"useCookies"," is ignored. The ",[260,853,784],{}," body is empty. Identity bearer and JWT flags are in the ",[272,856,206],{"href":857},"\u002Fmodules\u002Femail-code\u002F#verify",[256,859,860,861,863,864,275],{},"A correct code for an eligible confirmed user returns ",[260,862,784],{},". Then call ",[260,865,866],{},"GET \u002Fidentity\u002Fmanage\u002Finfo",[256,868,869,870,873,874,877,878,880,881,275],{},"Wrong codes, a required second factor, and ",[260,871,872],{},"405"," on ",[260,875,876],{},"GET \u002FemailCode\u002Fverify"," are in the ",[272,879,206],{"href":857}," and ",[272,882,196],{"href":883},"\u002Fmodules\u002Ferrors\u002F",[277,885,887],{"id":886},"create-an-account-from-the-code","Create an account from the code",[256,889,890,891,667,893,873,895,897,898,901,902,905,906,908],{},"Set ",[260,892,266],{},[260,894,670],{},[260,896,425],{},". On the 3.x facade, set it inside ",[260,899,900],{},"EmailCode.Configure",". An unknown address is then mailed with purpose ",[260,903,904],{},"SignUp",". The ",[260,907,784],{}," send body does not change.",[256,910,911,912,275],{},"A correct code creates one user and signs that user in. The user fields, and what happens to an unconfirmed account, are in the ",[272,913,206],{"href":914},"\u002Fmodules\u002Femail-code\u002F#sign-up-and-unconfirmed-accounts",[256,916,917,918,920,921,923,924,927],{},"With ",[260,919,266],{}," left at ",[260,922,419],{},", a correct code for an unknown address returns ",[260,925,926],{},"401"," and creates no user.",[277,929,931],{"id":930},"use-a-magic-link","Use a magic link",[256,933,934,935,667,938,940,941,944,945,948,949,275],{},"The magic link is off until you set ",[260,936,937],{},"MagicLink.Enabled",[260,939,670],{},". Set ",[260,942,943],{},"LinkUri",", and in Production set ",[260,946,947],{},"AllowedOrigins",". The URI rules are in the ",[272,950,206],{"href":951},"\u002Fmodules\u002Femail-code\u002F#options",[256,953,954,955,958],{},"The default link puts the token in the fragment. The fragment is not sent to your server. Read ",[260,956,957],{},"token"," in the client and post only that field:",[301,960,964],{"className":961,"code":962,"language":963,"meta":306,"style":306},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{ \"token\": \"…\" }\n","json",[260,965,966],{"__ignoreMap":306},[310,967,968,971,974,976,978,981,983,986,988],{"class":312,"line":313},[310,969,970],{"class":323},"{",[310,972,973],{"class":323}," \"",[310,975,957],{"class":316},[310,977,585],{"class":323},[310,979,980],{"class":323},":",[310,982,973],{"class":323},[310,984,985],{"class":588},"…",[310,987,585],{"class":323},[310,989,990],{"class":323}," }\n",[256,992,993,994,996,997,806,1000,1002,1003,1006,1007,1009],{},"A body that includes ",[260,995,957],{}," together with ",[260,998,999],{},"email",[260,1001,260],{}," returns ",[260,1004,1005],{},"400",". A token-only body is ",[260,1008,1005],{}," while the magic link is off, and the row is not consumed.",[256,1011,1012,1013,275],{},"One successful verify consumes the row. A second verify of the same code or token returns ",[260,1014,926],{},[277,1016,1018],{"id":1017},"related","Related",[1020,1021,1022,1026,1031,1036,1040,1045],"ul",{},[285,1023,1024],{},[272,1025,206],{"href":274},[285,1027,1028],{},[272,1029,56],{"href":1030},"\u002Fguides\u002Fsign-in\u002F",[285,1032,1033],{},[272,1034,51],{"href":1035},"\u002Fguides\u002Fregistration\u002F",[285,1037,1038],{},[272,1039,133],{"href":658},[285,1041,1042],{},[272,1043,100],{"href":1044},"\u002Fguides\u002Fproduction\u002F",[285,1046,1047],{},[272,1048,241],{"href":1049},"\u002Fconcepts\u002Fsecurity-model\u002F",[1051,1052,1053],"style",{},"html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":306,"searchDepth":313,"depth":344,"links":1055},[1056,1057,1058,1059,1060,1061],{"id":279,"depth":344,"text":280},{"id":769,"depth":344,"text":770},{"id":820,"depth":344,"text":821},{"id":886,"depth":344,"text":887},{"id":930,"depth":344,"text":931},{"id":1017,"depth":344,"text":1018},"Send a one-time code, verify it, and optionally create an account or accept a magic-link token.","md",null,{},{"icon":108},{"title":105,"description":1062},"RMoHJ10atcXeFfhn2_z69TVVPR38TXAC2iIDtJp4ywQ",[1070,1072],{"title":100,"path":101,"stem":102,"description":1071,"icon":103,"children":-1},"Checklist for running AuthEndpoints safely in Production.",{"title":110,"path":111,"stem":112,"description":1073,"icon":113,"children":-1},"Breaking changes from AuthEndpoints 3.x to 4.0, starting with the unified sign-in completer.",1792054256475]