[{"data":1,"prerenderedAt":1039},["ShallowReactive",2],{"navigation_docs":3,"-oauth-authorization-code":224,"-oauth-authorization-code-surround":1034},[4,157,184],{"title":5,"path":6,"stem":7,"children":8,"page":156},"Interface","\u002Finterface","1.interface",[9,53,61,68,75,82,90,97,104,111,132,139,145],{"title":10,"path":11,"stem":12,"children":13,"icon":15},"Courts","\u002Finterface\u002Fcourts","1.interface\u002F01.courts\u002F1.index",[14,16],{"title":10,"path":11,"stem":12,"icon":15},"sporty-court-sport",{"title":17,"path":18,"stem":19,"children":20,"icon":22},"Access control and lights","\u002Finterface\u002Fcourts\u002Fintegrations","1.interface\u002F01.courts\u002F5.integrations\u002F1.index",[21,23,28,33],{"title":17,"path":18,"stem":19,"icon":22},"sporty-toggle-large-on",{"title":24,"path":25,"stem":26,"icon":27},"Weblock","\u002Finterface\u002Fcourts\u002Fintegrations\u002Fweblock","1.interface\u002F01.courts\u002F5.integrations\u002F2.weblock","sporty-door-open",{"title":29,"path":30,"stem":31,"icon":32},"Shelly","\u002Finterface\u002Fcourts\u002Fintegrations\u002Fshelly","1.interface\u002F01.courts\u002F5.integrations\u002F3.shelly","sporty-bolt",{"title":34,"path":35,"stem":36,"children":37,"icon":27},"UniFi Access","\u002Finterface\u002Fcourts\u002Fintegrations\u002Funifi-access","1.interface\u002F01.courts\u002F5.integrations\u002F4.unifi-access\u002F1.index",[38,40,44,49],{"title":39,"path":35,"stem":36,"icon":27},"Overview",{"title":41,"path":42,"stem":43,"icon":22},"Connect the VPN","\u002Finterface\u002Fcourts\u002Fintegrations\u002Funifi-access\u002Fvpn","1.interface\u002F01.courts\u002F5.integrations\u002F4.unifi-access\u002F2.vpn",{"title":45,"path":46,"stem":47,"icon":48},"Create an API token","\u002Finterface\u002Fcourts\u002Fintegrations\u002Funifi-access\u002Fapi-token","1.interface\u002F01.courts\u002F5.integrations\u002F4.unifi-access\u002F3.api-token","sporty-gear",{"title":50,"path":51,"stem":52,"icon":15},"Set it up in Club Admin","\u002Finterface\u002Fcourts\u002Fintegrations\u002Funifi-access\u002Fclub-admin","1.interface\u002F01.courts\u002F5.integrations\u002F4.unifi-access\u002F4.club-admin",{"title":54,"path":55,"stem":56,"children":57,"icon":60},"Members","\u002Finterface\u002Fmembers","1.interface\u002F02.members\u002F1.index",[58],{"title":59,"path":55,"stem":56,"icon":60},"Member management","sporty-user-group",{"title":62,"path":63,"stem":64,"children":65,"icon":67},"Memberships","\u002Finterface\u002Fmemberships","1.interface\u002F03.memberships\u002F1.index",[66],{"title":62,"path":63,"stem":64,"icon":67},"sporty-id-card",{"title":69,"path":70,"stem":71,"children":72,"icon":74},"Leagues","\u002Finterface\u002Fleagues","1.interface\u002F04.leagues\u002F1.index",[73],{"title":69,"path":70,"stem":71,"icon":74},"sporty-ranking-star",{"title":76,"path":77,"stem":78,"children":79,"icon":81},"Tournaments","\u002Finterface\u002Ftournaments","1.interface\u002F05.tournaments\u002F1.index",[80],{"title":76,"path":77,"stem":78,"icon":81},"sporty-trophy",{"title":83,"path":84,"stem":85,"children":86,"icon":89},"Payments and subscriptions","\u002Finterface\u002Fpayments","1.interface\u002F06.payments\u002F1.index",[87],{"title":88,"path":84,"stem":85,"icon":89},"Payments","sporty-credit-card",{"title":91,"path":92,"stem":93,"children":94,"icon":96},"Shop","\u002Finterface\u002Fshop","1.interface\u002F07.shop\u002F1.index",[95],{"title":91,"path":92,"stem":93,"icon":96},"sporty-bag-shopping",{"title":98,"path":99,"stem":100,"children":101,"icon":103},"Schools and coaches","\u002Finterface\u002Fschools","1.interface\u002F08.schools\u002F1.index",[102],{"title":98,"path":99,"stem":100,"icon":103},"sporty-graduation-cap",{"title":105,"path":106,"stem":107,"children":108,"icon":110},"Emails","\u002Finterface\u002Femails","1.interface\u002F09.emails\u002F1.index",[109],{"title":105,"path":106,"stem":107,"icon":110},"sporty-envelope",{"title":112,"path":113,"stem":114,"children":115,"icon":117},"Video and cameras","\u002Finterface\u002Fvideo","1.interface\u002F10.video\u002F1.index",[116,118,122,127],{"title":112,"path":113,"stem":114,"icon":117},"sporty-camera-cctv",{"title":119,"path":120,"stem":121,"icon":117},"Dahua cameras","\u002Finterface\u002Fvideo\u002Fdahua","1.interface\u002F10.video\u002F2.dahua",{"title":123,"path":124,"stem":125,"icon":126},"Other RTMP cameras","\u002Finterface\u002Fvideo\u002Frtmp","1.interface\u002F10.video\u002F3.rtmp","sporty-video",{"title":128,"path":129,"stem":130,"icon":131},"Match analytics","\u002Finterface\u002Fvideo\u002Fanalytics","1.interface\u002F10.video\u002F4.analytics","sporty-chart-simple",{"title":133,"path":134,"stem":135,"children":136,"icon":138},"Reports","\u002Finterface\u002Freports","1.interface\u002F11.reports\u002F1.index",[137],{"title":133,"path":134,"stem":135,"icon":138},"sporty-chart-mixed",{"title":140,"path":141,"stem":142,"children":143,"icon":48},"Settings","\u002Finterface\u002Fsettings","1.interface\u002F12.settings\u002F1.index",[144],{"title":140,"path":141,"stem":142,"icon":48},{"title":146,"path":147,"stem":148,"children":149,"icon":151},"Social publishing","\u002Finterface\u002Fsocial","1.interface\u002F13.social\u002F1.index",[150,152],{"title":146,"path":147,"stem":148,"icon":151},"sporty-newspaper",{"title":153,"path":154,"stem":155,"icon":22},"Connecting channels","\u002Finterface\u002Fsocial\u002Fchannels","1.interface\u002F13.social\u002F2.channels",false,{"title":158,"path":159,"stem":160,"children":161,"icon":164},"Website","\u002Fwebsite","2.website\u002F1.index",[162,165,170,174,179],{"title":163,"path":159,"stem":160,"icon":164},"Website builder","sporty-browser",{"title":166,"path":167,"stem":168,"icon":169},"Pages, hero and footer","\u002Fwebsite\u002Fpages","2.website\u002F2.pages","sporty-file-lines",{"title":171,"path":172,"stem":173,"icon":151},"News and events","\u002Fwebsite\u002Fnews-and-events","2.website\u002F3.news-and-events",{"title":175,"path":176,"stem":177,"icon":178},"Coaches and gallery","\u002Fwebsite\u002Fcoaches-and-gallery","2.website\u002F4.coaches-and-gallery","sporty-images",{"title":180,"path":181,"stem":182,"icon":183},"FAQ and sponsors","\u002Fwebsite\u002Ffaq-and-sponsors","2.website\u002F5.faq-and-sponsors","sporty-circle-question",{"title":185,"path":186,"stem":187,"children":188,"icon":190},"OAuth & Sign in with Sporty","\u002Foauth","4.oauth\u002F1.index",[189,191,195,199,203,207,211,215,219],{"title":185,"path":186,"stem":187,"icon":190},"sporty-brackets-curly",{"title":192,"path":193,"stem":194,"icon":190},"Registering an application","\u002Foauth\u002Fclients","4.oauth\u002F2.clients",{"title":196,"path":197,"stem":198,"icon":190},"The authorization code flow","\u002Foauth\u002Fauthorization-code","4.oauth\u002F3.authorization-code",{"title":200,"path":201,"stem":202,"icon":190},"Scopes","\u002Foauth\u002Fscopes","4.oauth\u002F4.scopes",{"title":204,"path":205,"stem":206,"icon":190},"Sign in with Sporty","\u002Foauth\u002Fsign-in-with-sporty","4.oauth\u002F5.sign-in-with-sporty",{"title":208,"path":209,"stem":210,"icon":190},"The partner API","\u002Foauth\u002Fpartner-api","4.oauth\u002F6.partner-api",{"title":212,"path":213,"stem":214,"icon":190},"Syncing bookings","\u002Foauth\u002Fbooking-sync","4.oauth\u002F7.booking-sync",{"title":216,"path":217,"stem":218,"icon":190},"MCP and AI clients","\u002Foauth\u002Fmcp-and-ai-clients","4.oauth\u002F8.mcp-and-ai-clients",{"title":220,"path":221,"stem":222,"icon":223},"Agent checkout","\u002Foauth\u002Fagent-checkout","4.oauth\u002F9.agent-checkout","sporty-cart-shopping",{"id":225,"title":196,"body":226,"description":1025,"extension":1026,"links":1027,"meta":1028,"navigation":1029,"path":197,"seo":1030,"stem":198,"__hash__":1033},"docs\u002F4.oauth\u002F3.authorization-code.md",{"type":227,"value":228,"toc":1015},"minimark",[229,233,238,255,403,406,410,418,472,479,483,489,492,498,504,508,511,612,619,733,746,750,778,782,785,846,850,891,905,913,920,924,1004,1011],[230,231,232],"p",{},"Authorization code with PKCE, which is the flow for any application acting on behalf of a\nperson. Every example below is a real request.",[234,235,237],"h2",{"id":236},"_1-make-a-pkce-verifier-and-challenge","1. Make a PKCE verifier and challenge",[230,239,240,241,245,246,250,251,254],{},"PKCE is ",[242,243,244],"strong",{},"required",", for confidential clients too, and only ",[247,248,249],"code",{},"S256"," is accepted — ",[247,252,253],{},"plain"," is\nrefused.",[256,257,262],"pre",{"className":258,"code":259,"language":260,"meta":261,"style":261},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","VERIFIER=$(openssl rand -base64 60 | tr -d '\\n=+\u002F' | cut -c1-64)\nCHALLENGE=$(printf '%s' \"$VERIFIER\" | openssl dgst -sha256 -binary | openssl base64 | tr '+\u002F' '-_' | tr -d '=')\n","bash","",[247,263,264,321],{"__ignoreMap":261},[265,266,269,273,277,281,285,288,292,295,298,301,304,307,310,312,315,318],"span",{"class":267,"line":268},"line",1,[265,270,272],{"class":271},"sTEyZ","VERIFIER",[265,274,276],{"class":275},"sMK4o","=$(",[265,278,280],{"class":279},"sBMFI","openssl",[265,282,284],{"class":283},"sfazB"," rand",[265,286,287],{"class":283}," -base64",[265,289,291],{"class":290},"sbssI"," 60",[265,293,294],{"class":275}," |",[265,296,297],{"class":279}," tr",[265,299,300],{"class":283}," -d",[265,302,303],{"class":275}," '",[265,305,306],{"class":283},"\\n=+\u002F",[265,308,309],{"class":275},"'",[265,311,294],{"class":275},[265,313,314],{"class":279}," cut",[265,316,317],{"class":283}," -c1-64",[265,319,320],{"class":275},")\n",[265,322,324,327,329,333,335,338,340,343,346,349,351,354,357,360,363,365,367,370,372,374,376,379,381,383,386,388,390,392,394,396,399,401],{"class":267,"line":323},2,[265,325,326],{"class":271},"CHALLENGE",[265,328,276],{"class":275},[265,330,332],{"class":331},"s2Zo4","printf",[265,334,303],{"class":275},[265,336,337],{"class":283},"%s",[265,339,309],{"class":275},[265,341,342],{"class":275}," \"",[265,344,345],{"class":271},"$VERIFIER",[265,347,348],{"class":275},"\"",[265,350,294],{"class":275},[265,352,353],{"class":279}," openssl",[265,355,356],{"class":283}," dgst",[265,358,359],{"class":283}," -sha256",[265,361,362],{"class":283}," -binary",[265,364,294],{"class":275},[265,366,353],{"class":279},[265,368,369],{"class":283}," base64",[265,371,294],{"class":275},[265,373,297],{"class":279},[265,375,303],{"class":275},[265,377,378],{"class":283},"+\u002F",[265,380,309],{"class":275},[265,382,303],{"class":275},[265,384,385],{"class":283},"-_",[265,387,309],{"class":275},[265,389,294],{"class":275},[265,391,297],{"class":279},[265,393,300],{"class":283},[265,395,303],{"class":275},[265,397,398],{"class":283},"=",[265,400,309],{"class":275},[265,402,320],{"class":275},[230,404,405],{},"Keep the verifier; you need it in step 4.",[234,407,409],{"id":408},"_2-send-the-member-to-sporty","2. Send the member to Sporty",[256,411,416],{"className":412,"code":414,"language":415},[413],"language-text","https:\u002F\u002Fapi.sporty.plus\u002Foauth2\u002Fauthorize\n  ?response_type=code\n  &client_id=YOUR_CLIENT_ID\n  &redirect_uri=https:\u002F\u002Fyourapp.example\u002Fcallback\n  &scope=openid%20profile%20email%20club.courts.read\n  &state=RANDOM_PER_REQUEST\n  &code_challenge=CHALLENGE\n  &code_challenge_method=S256\n","text",[247,417,414],{"__ignoreMap":261},[419,420,421,434],"table",{},[422,423,424],"thead",{},[425,426,427,431],"tr",{},[428,429,430],"th",{},"Parameter",[428,432,433],{},"Notes",[435,436,437,448,462],"tbody",{},[425,438,439,445],{},[440,441,442],"td",{},[247,443,444],{},"state",[440,446,447],{},"Random, unguessable, per request. Check it on the way back — that is what makes the callback yours.",[425,449,450,455],{},[440,451,452],{},[247,453,454],{},"nonce",[440,456,457,458,461],{},"Optional. If you send it, it comes back in the ",[247,459,460],{},"id_token",". Use it if you want one.",[425,463,464,469],{},[440,465,466],{},[247,467,468],{},"club_id",[440,470,471],{},"Optional. Only meaningful for a client granted access to several clubs, to say which one this is about.",[230,473,474,475,478],{},"The member sees a consent screen on ",[247,476,477],{},"my.sporty.plus"," listing, in plain language, exactly what\nyou asked for. They can approve less than you asked for; grant requests are never widened.",[234,480,482],{"id":481},"_3-they-come-back-to-your-redirect-uri","3. They come back to your redirect URI",[256,484,487],{"className":485,"code":486,"language":415},[413],"https:\u002F\u002Fyourapp.example\u002Fcallback?code=...&state=...\n",[247,488,486],{"__ignoreMap":261},[230,490,491],{},"If they declined, or something was wrong:",[256,493,496],{"className":494,"code":495,"language":415},[413],"https:\u002F\u002Fyourapp.example\u002Fcallback?error=access_denied&error_description=...&state=...\n",[247,497,495],{"__ignoreMap":261},[230,499,500,501,503],{},"Compare ",[247,502,444],{}," with what you sent before doing anything else.",[234,505,507],{"id":506},"_4-exchange-the-code","4. Exchange the code",[230,509,510],{},"Within a few minutes, and once only. A code is single use.",[256,512,514],{"className":258,"code":513,"language":260,"meta":261,"style":261},"curl -X POST https:\u002F\u002Fapi.sporty.plus\u002Foauth2\u002Ftoken \\\n  -H 'Accept: application\u002Fjson' \\\n  -d grant_type=authorization_code \\\n  -d client_id=YOUR_CLIENT_ID \\\n  -d client_secret=YOUR_SECRET \\\n  -d redirect_uri=https:\u002F\u002Fyourapp.example\u002Fcallback \\\n  -d code_verifier=\"$VERIFIER\" \\\n  -d code=THE_CODE\n",[247,515,516,533,547,558,568,578,588,604],{"__ignoreMap":261},[265,517,518,521,524,527,530],{"class":267,"line":268},[265,519,520],{"class":279},"curl",[265,522,523],{"class":283}," -X",[265,525,526],{"class":283}," POST",[265,528,529],{"class":283}," https:\u002F\u002Fapi.sporty.plus\u002Foauth2\u002Ftoken",[265,531,532],{"class":271}," \\\n",[265,534,535,538,540,543,545],{"class":267,"line":323},[265,536,537],{"class":283},"  -H",[265,539,303],{"class":275},[265,541,542],{"class":283},"Accept: application\u002Fjson",[265,544,309],{"class":275},[265,546,532],{"class":271},[265,548,550,553,556],{"class":267,"line":549},3,[265,551,552],{"class":283},"  -d",[265,554,555],{"class":283}," grant_type=authorization_code",[265,557,532],{"class":271},[265,559,561,563,566],{"class":267,"line":560},4,[265,562,552],{"class":283},[265,564,565],{"class":283}," client_id=YOUR_CLIENT_ID",[265,567,532],{"class":271},[265,569,571,573,576],{"class":267,"line":570},5,[265,572,552],{"class":283},[265,574,575],{"class":283}," client_secret=YOUR_SECRET",[265,577,532],{"class":271},[265,579,581,583,586],{"class":267,"line":580},6,[265,582,552],{"class":283},[265,584,585],{"class":283}," redirect_uri=https:\u002F\u002Fyourapp.example\u002Fcallback",[265,587,532],{"class":271},[265,589,591,593,596,598,600,602],{"class":267,"line":590},7,[265,592,552],{"class":283},[265,594,595],{"class":283}," code_verifier=",[265,597,348],{"class":275},[265,599,345],{"class":271},[265,601,348],{"class":275},[265,603,532],{"class":271},[265,605,607,609],{"class":267,"line":606},8,[265,608,552],{"class":283},[265,610,611],{"class":283}," code=THE_CODE\n",[230,613,614,615,618],{},"Omit ",[247,616,617],{},"client_secret"," for a public client.",[256,620,624],{"className":621,"code":622,"language":623,"meta":261,"style":261},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"token_type\": \"Bearer\",\n  \"expires_in\": 3600,\n  \"access_token\": \"eyJ0eXAiOiJKV1Qi...\",\n  \"refresh_token\": \"def5020089ab...\",\n  \"id_token\": \"eyJ0eXAiOiJKV1Qi...\"\n}\n","json",[247,625,626,631,655,671,691,711,728],{"__ignoreMap":261},[265,627,628],{"class":267,"line":268},[265,629,630],{"class":275},"{\n",[265,632,633,636,640,642,645,647,650,652],{"class":267,"line":323},[265,634,635],{"class":275},"  \"",[265,637,639],{"class":638},"spNyl","token_type",[265,641,348],{"class":275},[265,643,644],{"class":275},":",[265,646,342],{"class":275},[265,648,649],{"class":283},"Bearer",[265,651,348],{"class":275},[265,653,654],{"class":275},",\n",[265,656,657,659,662,664,666,669],{"class":267,"line":549},[265,658,635],{"class":275},[265,660,661],{"class":638},"expires_in",[265,663,348],{"class":275},[265,665,644],{"class":275},[265,667,668],{"class":290}," 3600",[265,670,654],{"class":275},[265,672,673,675,678,680,682,684,687,689],{"class":267,"line":560},[265,674,635],{"class":275},[265,676,677],{"class":638},"access_token",[265,679,348],{"class":275},[265,681,644],{"class":275},[265,683,342],{"class":275},[265,685,686],{"class":283},"eyJ0eXAiOiJKV1Qi...",[265,688,348],{"class":275},[265,690,654],{"class":275},[265,692,693,695,698,700,702,704,707,709],{"class":267,"line":570},[265,694,635],{"class":275},[265,696,697],{"class":638},"refresh_token",[265,699,348],{"class":275},[265,701,644],{"class":275},[265,703,342],{"class":275},[265,705,706],{"class":283},"def5020089ab...",[265,708,348],{"class":275},[265,710,654],{"class":275},[265,712,713,715,717,719,721,723,725],{"class":267,"line":580},[265,714,635],{"class":275},[265,716,460],{"class":638},[265,718,348],{"class":275},[265,720,644],{"class":275},[265,722,342],{"class":275},[265,724,686],{"class":283},[265,726,727],{"class":275},"\"\n",[265,729,730],{"class":267,"line":590},[265,731,732],{"class":275},"}\n",[230,734,735,737,738,741,742,745],{},[247,736,460],{}," is present only when you asked for ",[247,739,740],{},"openid",". See\n",[743,744,204],"a",{"href":205},".",[234,747,749],{"id":748},"_5-use-it","5. Use it",[256,751,753],{"className":258,"code":752,"language":260,"meta":261,"style":261},"curl https:\u002F\u002Fapi.sporty.plus\u002Fapi\u002Fpartner\u002Fv1\u002Fclubs\u002Fme \\\n  -H \"Authorization: Bearer $ACCESS_TOKEN\"\n",[247,754,755,764],{"__ignoreMap":261},[265,756,757,759,762],{"class":267,"line":268},[265,758,520],{"class":279},[265,760,761],{"class":283}," https:\u002F\u002Fapi.sporty.plus\u002Fapi\u002Fpartner\u002Fv1\u002Fclubs\u002Fme",[265,763,532],{"class":271},[265,765,766,768,770,773,776],{"class":267,"line":323},[265,767,537],{"class":283},[265,769,342],{"class":275},[265,771,772],{"class":283},"Authorization: Bearer ",[265,774,775],{"class":271},"$ACCESS_TOKEN",[265,777,727],{"class":275},[234,779,781],{"id":780},"_6-refresh","6. Refresh",[230,783,784],{},"Access tokens last an hour; refresh tokens thirty days (a day for a self-registered client).",[256,786,788],{"className":258,"code":787,"language":260,"meta":261,"style":261},"curl -X POST https:\u002F\u002Fapi.sporty.plus\u002Foauth2\u002Ftoken \\\n  -H 'Accept: application\u002Fjson' \\\n  -d grant_type=refresh_token \\\n  -d client_id=YOUR_CLIENT_ID \\\n  -d client_secret=YOUR_SECRET \\\n  -d refresh_token=THE_REFRESH_TOKEN\n",[247,789,790,802,814,823,831,839],{"__ignoreMap":261},[265,791,792,794,796,798,800],{"class":267,"line":268},[265,793,520],{"class":279},[265,795,523],{"class":283},[265,797,526],{"class":283},[265,799,529],{"class":283},[265,801,532],{"class":271},[265,803,804,806,808,810,812],{"class":267,"line":323},[265,805,537],{"class":283},[265,807,303],{"class":275},[265,809,542],{"class":283},[265,811,309],{"class":275},[265,813,532],{"class":271},[265,815,816,818,821],{"class":267,"line":549},[265,817,552],{"class":283},[265,819,820],{"class":283}," grant_type=refresh_token",[265,822,532],{"class":271},[265,824,825,827,829],{"class":267,"line":560},[265,826,552],{"class":283},[265,828,565],{"class":283},[265,830,532],{"class":271},[265,832,833,835,837],{"class":267,"line":570},[265,834,552],{"class":283},[265,836,575],{"class":283},[265,838,532],{"class":271},[265,840,841,843],{"class":267,"line":580},[265,842,552],{"class":283},[265,844,845],{"class":283}," refresh_token=THE_REFRESH_TOKEN\n",[234,847,849],{"id":848},"_7-revoke-when-you-are-done","7. Revoke, when you are done",[256,851,853],{"className":258,"code":852,"language":260,"meta":261,"style":261},"curl -X POST https:\u002F\u002Fapi.sporty.plus\u002Foauth2\u002Ftoken\u002Frevoke \\\n  -d client_id=YOUR_CLIENT_ID \\\n  -d client_secret=YOUR_SECRET \\\n  -d token=THE_ACCESS_TOKEN\n",[247,854,855,868,876,884],{"__ignoreMap":261},[265,856,857,859,861,863,866],{"class":267,"line":268},[265,858,520],{"class":279},[265,860,523],{"class":283},[265,862,526],{"class":283},[265,864,865],{"class":283}," https:\u002F\u002Fapi.sporty.plus\u002Foauth2\u002Ftoken\u002Frevoke",[265,867,532],{"class":271},[265,869,870,872,874],{"class":267,"line":323},[265,871,552],{"class":283},[265,873,565],{"class":283},[265,875,532],{"class":271},[265,877,878,880,882],{"class":267,"line":549},[265,879,552],{"class":283},[265,881,575],{"class":283},[265,883,532],{"class":271},[265,885,886,888],{"class":267,"line":560},[265,887,552],{"class":283},[265,889,890],{"class":283}," token=THE_ACCESS_TOKEN\n",[230,892,893,894,897,898,904],{},"This always answers ",[247,895,896],{},"200",", whatever you send — that is what\n",[743,899,903],{"href":900,"rel":901},"https:\u002F\u002Fwww.rfc-editor.org\u002Frfc\u002Frfc7009",[902],"nofollow","RFC 7009"," requires, so the endpoint cannot be used to\nfind out whether a token is valid.",[906,907,909,912],"callout",{"icon":908},"i-heroicons-exclamation-triangle",[242,910,911],{},"Name the access token, not the refresh token."," Revoking an access token also revokes the\nrefresh tokens issued with it, which is what \"end this session\" means in practice. A refresh\ntoken on its own cannot currently be named here.",[230,914,915,916,919],{},"A member can also revoke you at any moment, from ",[242,917,918],{},"Authorised applications"," in their profile.\nWhen that happens every token you hold stops working immediately, and you should send them\nthrough the flow again rather than retrying.",[234,921,923],{"id":922},"errors-you-should-expect","Errors you should expect",[419,925,926,936],{},[422,927,928],{},[425,929,930,933],{},[428,931,932],{},"Error",[428,934,935],{},"What happened",[435,937,938,955,965,979,989],{},[425,939,940,945],{},[440,941,942],{},[247,943,944],{},"invalid_request",[440,946,947,948,950,951,954],{},"Usually a missing or ",[247,949,253],{}," ",[247,952,953],{},"code_challenge",". PKCE with S256 is required.",[425,956,957,962],{},[440,958,959],{},[247,960,961],{},"invalid_scope",[440,963,964],{},"A scope that does not exist, or one this kind of client may not ask for.",[425,966,967,972],{},[440,968,969],{},[247,970,971],{},"invalid_grant",[440,973,974,975,978],{},"The code was already spent, expired, or the ",[247,976,977],{},"code_verifier"," does not match.",[425,980,981,986],{},[440,982,983],{},[247,984,985],{},"access_denied",[440,987,988],{},"The member said no, or the application is suspended.",[425,990,991,997],{},[440,992,993,996],{},[247,994,995],{},"insufficient_scope"," (403)",[440,998,999,1000,1003],{},"The token is valid but was not granted this scope. The ",[247,1001,1002],{},"WWW-Authenticate"," header names what is needed.",[230,1005,1006,1007,1010],{},"An unregistered ",[247,1008,1009],{},"redirect_uri"," is never redirected to. You will see the error on Sporty\ninstead — which is the point.",[1012,1013,1014],"style",{},"html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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 .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}",{"title":261,"searchDepth":323,"depth":323,"links":1016},[1017,1018,1019,1020,1021,1022,1023,1024],{"id":236,"depth":323,"text":237},{"id":408,"depth":323,"text":409},{"id":481,"depth":323,"text":482},{"id":506,"depth":323,"text":507},{"id":748,"depth":323,"text":749},{"id":780,"depth":323,"text":781},{"id":848,"depth":323,"text":849},{"id":922,"depth":323,"text":923},"The whole flow with real requests, from sending someone to Sporty to refreshing a token.","md",null,{},{"icon":190},{"title":1031,"description":1032},"Sporty OAuth authorization code flow with PKCE","A step-by-step walkthrough with curl, including PKCE, refresh and revocation.","_JQKC3lyI6DfSFeETHLnibe4b40TTRTsAGwA7nre2OM",[1035,1037],{"title":192,"path":193,"stem":194,"description":1036,"icon":190,"children":-1},"How to get a client id, what a redirect URI may look like, and what \"pending review\" means.",{"title":200,"path":201,"stem":202,"description":1038,"icon":190,"children":-1},"Every scope, what the member is told it means, and which kinds of client may ask for it.",1790691909306]