[{"data":1,"prerenderedAt":883},["ShallowReactive",2],{"api-docs-articles":3,"api-docs-nav-articles":72,"api-docs-article-mcp-authorization":85,"api-docs-related-mcp-authorization":880},[4,11,17,23,28,34,40,46,52,57,62,67],{"path":5,"title":6,"description":7,"category":8,"emoji":9,"order":10},"\u002Fdocs\u002Fapi\u002Fauthentication","Authentication","Authenticate Pallyy API requests with an API key, understand scopes for reading and writing, and restrict keys to specific social sets.","getting-started","🔑",1,{"path":12,"title":13,"description":14,"category":8,"emoji":15,"order":16},"\u002Fdocs\u002Fapi\u002Ferrors","Errors","How the Pallyy API reports errors: HTTP status codes, the machine-readable error code in the response body, and validation error details.","⚠️",3,{"path":18,"title":19,"description":20,"category":21,"emoji":22,"order":10},"\u002Fdocs\u002Fapi\u002Fmcp","MCP server","Connect Claude, ChatGPT, Cursor, or any MCP client to your Pallyy account: the server URL, what the tools can do, how consent works, and how to disconnect an app.","mcp","🤖",{"path":24,"title":25,"description":26,"category":21,"emoji":27,"order":16},"\u002Fdocs\u002Fapi\u002Fmcp-authorization","MCP authorization","How MCP clients sign in to Pallyy with OAuth 2.1: discovery documents, client identification, PKCE, scopes, token lifetimes, refresh rotation, and revocation.","🔐",{"path":29,"title":30,"description":31,"category":21,"emoji":32,"order":33},"\u002Fdocs\u002Fapi\u002Fmcp-tools","MCP tools","Reference for the 15 tools the Pallyy MCP server exposes to AI assistants: social sets, post sets, media, media uploads, and calendar notes, with every input.","🧰",2,{"path":35,"title":36,"description":37,"category":38,"emoji":39,"order":16},"\u002Fdocs\u002Fapi\u002Fmedia","Media library","Browse a social set's media library via the Pallyy API, filter by folder, type, or name, and reference items when creating posts.","endpoints","🖼️",{"path":41,"title":42,"description":43,"category":38,"emoji":44,"order":45},"\u002Fdocs\u002Fapi\u002Fmedia-uploads","Media uploads","Import images and videos into a Pallyy media library from a URL via the API, poll the upload's status, and use the result in posts.","⬆️",4,{"path":47,"title":48,"description":49,"category":38,"emoji":50,"order":51},"\u002Fdocs\u002Fapi\u002Fnotes","Notes","Read and create the notes pinned to a social set's calendar via the Pallyy API: reminders, recurring notes, and events imported from Google Calendar.","📝",5,{"path":53,"title":54,"description":55,"category":8,"emoji":56,"order":45},"\u002Fdocs\u002Fapi\u002Fpagination","Pagination and queries","How Pallyy API list endpoints paginate with page and size parameters, and how to pass nested filters and sorting in the query string.","📄",{"path":58,"title":59,"description":60,"category":38,"emoji":61,"order":33},"\u002Fdocs\u002Fapi\u002Fpost-sets","Post sets","Create, schedule, list, and update Pallyy post sets via the API: one scheduled slot holding a post for each social network it targets.","🗓️",{"path":63,"title":64,"description":65,"category":8,"emoji":66,"order":33},"\u002Fdocs\u002Fapi\u002Frate-limits","Rate limits","The Pallyy API allows 5 requests per second per account. Read the rate limit headers on every response and back off on 429s.","⏱️",{"path":68,"title":69,"description":70,"category":38,"emoji":71,"order":10},"\u002Fdocs\u002Fapi\u002Fsocial-sets","Social sets","List your Pallyy social sets and their connected accounts via the API. Almost every other endpoint needs a social set id.","👥",[73,74,75,76,77,78,79,80,81,82,83,84],{"path":5,"title":6,"category":8,"order":10},{"path":12,"title":13,"category":8,"order":16},{"path":18,"title":19,"category":21,"order":10},{"path":24,"title":25,"category":21,"order":16},{"path":29,"title":30,"category":21,"order":33},{"path":35,"title":36,"category":38,"order":16},{"path":41,"title":42,"category":38,"order":45},{"path":47,"title":48,"category":38,"order":51},{"path":53,"title":54,"category":8,"order":45},{"path":58,"title":59,"category":38,"order":33},{"path":63,"title":64,"category":8,"order":33},{"path":68,"title":69,"category":38,"order":10},{"id":86,"title":25,"body":87,"category":21,"datePublished":872,"dateUpdated":873,"description":26,"emoji":27,"extension":874,"meta":875,"navigation":876,"order":16,"path":24,"seo":877,"stem":878,"__hash__":879},"apiDocs\u002Fdocs\u002Fapi\u002Fmcp-authorization.md",{"type":88,"value":89,"toc":862},"minimark",[90,101,106,118,128,131,171,174,217,220,224,243,249,268,294,305,309,312,432,452,455,459,465,535,542,546,553,629,632,640,646,650,692,707,724,727,733,736,755,758,765,856],[91,92,93,94,97,98,100],"p",{},"The Pallyy ",[95,96,19],"a",{"href":18}," is protected by an OAuth 2.1 authorization server that Pallyy runs itself, following the MCP authorization specification. This page is for people building or configuring an MCP client. If you just want to connect Claude, ChatGPT, or Cursor, the ",[95,99,19],{"href":18}," page has the steps, and the consent flow takes care of everything below.",[102,103,105],"h2",{"id":104},"discovery","Discovery",[91,107,108,109,113,114,117],{},"A request to ",[110,111,112],"code",{},"https:\u002F\u002Fapp.pallyy.com\u002Fmcp"," without a bearer token answers ",[110,115,116],{},"401"," with a challenge pointing at the protected resource metadata:",[119,120,125],"pre",{"className":121,"code":123,"language":124},[122],"language-text","WWW-Authenticate: Bearer resource_metadata=\"https:\u002F\u002Fapp.pallyy.com\u002F.well-known\u002Foauth-protected-resource\u002Fmcp\"\n","text",[110,126,123],{"__ignoreMap":127},"",[91,129,130],{},"That document (RFC 9728) names the authorization server, and the server's own metadata (RFC 8414) lists every endpoint:",[132,133,134,147],"table",{},[135,136,137],"thead",{},[138,139,140,144],"tr",{},[141,142,143],"th",{},"Document",[141,145,146],{},"URL",[148,149,150,161],"tbody",{},[138,151,152,156],{},[153,154,155],"td",{},"Protected resource metadata",[153,157,158],{},[110,159,160],{},"https:\u002F\u002Fapp.pallyy.com\u002F.well-known\u002Foauth-protected-resource\u002Fmcp",[138,162,163,166],{},[153,164,165],{},"Authorization server metadata",[153,167,168],{},[110,169,170],{},"https:\u002F\u002Fapp.pallyy.com\u002F.well-known\u002Foauth-authorization-server",[91,172,173],{},"The endpoints it advertises:",[132,175,176,185],{},[135,177,178],{},[138,179,180,183],{},[141,181,182],{},"Endpoint",[141,184,146],{},[148,186,187,197,207],{},[138,188,189,192],{},[153,190,191],{},"Authorization",[153,193,194],{},[110,195,196],{},"https:\u002F\u002Fapp.pallyy.com\u002Foauth\u002Fauthorize",[138,198,199,202],{},[153,200,201],{},"Token",[153,203,204],{},[110,205,206],{},"https:\u002F\u002Fapp.pallyy.com\u002Fapi\u002Foauth\u002Ftoken",[138,208,209,212],{},[153,210,211],{},"Revocation",[153,213,214],{},[110,215,216],{},"https:\u002F\u002Fapp.pallyy.com\u002Fapi\u002Foauth\u002Frevoke",[91,218,219],{},"Both discovery documents and the token and revocation endpoints allow cross-origin requests, so browser-based clients can complete the flow.",[102,221,223],{"id":222},"client-identification","Client identification",[91,225,226,227,230,231,234,235,238,239,242],{},"Pallyy does not offer dynamic client registration. Clients identify themselves with a Client ID Metadata Document: the ",[110,228,229],{},"client_id"," is the ",[110,232,233],{},"https"," URL of a JSON document describing the client (its ",[110,236,237],{},"client_name",", ",[110,240,241],{},"redirect_uris",", and so on, in RFC 7591 format), and Pallyy fetches, validates, and caches that document the first time it sees the URL.",[91,244,245,246,248],{},"The metadata document, and every ",[110,247,233],{}," redirect URI it lists, must be hosted on one of the supported platforms, including their subdomains:",[250,251,252,258,263],"ul",{},[253,254,255],"li",{},[110,256,257],{},"claude.ai",[253,259,260],{},[110,261,262],{},"chatgpt.com",[253,264,265],{},[110,266,267],{},"cursor.com",[91,269,270,271,238,274,277,278,281,282,284,285,288,289,293],{},"Native apps such as Claude Code may instead redirect to a loopback address (",[110,272,273],{},"http:\u002F\u002Flocalhost",[110,275,276],{},"http:\u002F\u002F127.0.0.1",", or ",[110,279,280],{},"http:\u002F\u002F[::1]",") on any port, as RFC 8252 allows. A ",[110,283,229],{}," on any other host is rejected with ",[110,286,287],{},"invalid_client",", which is why other MCP clients connect with an ",[95,290,292],{"href":291},"\u002Fdocs\u002Fapi\u002Fmcp#connect-any-other-client-with-an-api-key","API key"," instead.",[91,295,296,297,300,301,304],{},"Every client is a public client. The only supported ",[110,298,299],{},"token_endpoint_auth_method"," is ",[110,302,303],{},"none",", and PKCE is required.",[102,306,308],{"id":307},"authorization-request","Authorization request",[91,310,311],{},"The client sends the user to the authorization endpoint with these parameters:",[132,313,314,327],{},[135,315,316],{},[138,317,318,321,324],{},[141,319,320],{},"Parameter",[141,322,323],{},"Required",[141,325,326],{},"Meaning",[148,328,329,341,353,366,378,392,405,417],{},[138,330,331,335,338],{},[153,332,333],{},[110,334,229],{},[153,336,337],{},"Yes",[153,339,340],{},"The URL of the client's metadata document",[138,342,343,348,350],{},[153,344,345],{},[110,346,347],{},"redirect_uri",[153,349,337],{},[153,351,352],{},"One of the URIs registered in the document",[138,354,355,360,362],{},[153,356,357],{},[110,358,359],{},"response_type",[153,361,337],{},[153,363,364],{},[110,365,110],{},[138,367,368,373,375],{},[153,369,370],{},[110,371,372],{},"code_challenge",[153,374,337],{},[153,376,377],{},"PKCE challenge, S256 only",[138,379,380,385,387],{},[153,381,382],{},[110,383,384],{},"code_challenge_method",[153,386,337],{},[153,388,389],{},[110,390,391],{},"S256",[138,393,394,399,402],{},[153,395,396],{},[110,397,398],{},"scope",[153,400,401],{},"No",[153,403,404],{},"Space-separated scopes, see below",[138,406,407,412,414],{},[153,408,409],{},[110,410,411],{},"state",[153,413,401],{},[153,415,416],{},"Returned unchanged on the redirect",[138,418,419,424,426],{},[153,420,421],{},[110,422,423],{},"resource",[153,425,401],{},[153,427,428,429,431],{},"Must be ",[110,430,112],{}," when present (RFC 8707)",[91,433,434,435,437,438,440,441,443,444,447,448,451],{},"The user signs in to Pallyy if needed, reviews what the client asked for, optionally limits it to specific social sets, and approves or cancels. Approval redirects to ",[110,436,347],{}," with a single-use ",[110,439,110],{}," that expires after 10 minutes, plus ",[110,442,411],{}," and an ",[110,445,446],{},"iss"," parameter naming the issuer (RFC 9207). Cancelling redirects with ",[110,449,450],{},"error=access_denied",".",[91,453,454],{},"Consent must come from the account owner in person: an administrator viewing an account on a user's behalf cannot approve a connection.",[102,456,458],{"id":457},"scopes","Scopes",[91,460,461,462,464],{},"The scopes are the same ones API keys use. Every token can read, so a request with no ",[110,463,398],{}," produces a read-only connection.",[132,466,467,477],{},[135,468,469],{},[138,470,471,474],{},[141,472,473],{},"Scope",[141,475,476],{},"Grants",[148,478,479,489,505,515,525],{},[138,480,481,486],{},[153,482,483],{},[110,484,485],{},"post-sets:write",[153,487,488],{},"Create and update draft post sets",[138,490,491,496],{},[153,492,493],{},[110,494,495],{},"post-sets:publish",[153,497,498,499,501,502],{},"Required on top of ",[110,500,485],{}," to create or update post sets with status ",[110,503,504],{},"SCHEDULED",[138,506,507,512],{},[153,508,509],{},[110,510,511],{},"media:write",[153,513,514],{},"Create media uploads",[138,516,517,522],{},[153,518,519],{},[110,520,521],{},"notes:write",[153,523,524],{},"Create and update calendar notes",[138,526,527,532],{},[153,528,529],{},[110,530,531],{},"offline_access",[153,533,534],{},"Not a permission: asks for a refresh token so the connection outlives the access token",[91,536,537,538,541],{},"An unknown scope fails the request with ",[110,539,540],{},"invalid_scope",". The consent page shows the user every scope requested, and the grant records exactly those.",[102,543,545],{"id":544},"token-exchange","Token exchange",[91,547,548,549,552],{},"The client exchanges the code at the token endpoint with a form-encoded or JSON ",[110,550,551],{},"POST",":",[132,554,555,563],{},[135,556,557],{},[138,558,559,561],{},[141,560,320],{},[141,562,326],{},[148,564,565,577,586,598,608,620],{},[138,566,567,572],{},[153,568,569],{},[110,570,571],{},"grant_type",[153,573,574],{},[110,575,576],{},"authorization_code",[138,578,579,583],{},[153,580,581],{},[110,582,110],{},[153,584,585],{},"The code from the redirect",[138,587,588,592],{},[153,589,590],{},[110,591,229],{},[153,593,594,595,597],{},"The same ",[110,596,229],{}," as the authorization request",[138,599,600,604],{},[153,601,602],{},[110,603,347],{},[153,605,594,606,597],{},[110,607,347],{},[138,609,610,615],{},[153,611,612],{},[110,613,614],{},"code_verifier",[153,616,617,618],{},"The PKCE verifier matching ",[110,619,372],{},[138,621,622,626],{},[153,623,624],{},[110,625,423],{},[153,627,628],{},"Optional, must match the authorization request when present",[91,630,631],{},"A successful exchange returns the tokens:",[119,633,638],{"className":634,"code":636,"language":637,"meta":127},[635],"language-json","{\n  \"access_token\": \"pallyy_oat_...\",\n  \"token_type\": \"Bearer\",\n  \"expires_in\": 3600,\n  \"refresh_token\": \"pallyy_ort_...\",\n  \"scope\": \"post-sets:write post-sets:publish offline_access\"\n}\n","json",[110,639,636],{"__ignoreMap":127},[91,641,642,643,451],{},"A code is consumed on first use, so a failed exchange burns it and the client has to start over. The code is bound to the client, redirect URI, PKCE challenge, and resource it was issued for, and any mismatch fails with ",[110,644,645],{},"invalid_grant",[102,647,649],{"id":648},"token-lifetimes","Token lifetimes",[132,651,652,664],{},[135,653,654],{},[138,655,656,658,661],{},[141,657,201],{},[141,659,660],{},"Prefix",[141,662,663],{},"Lifetime",[148,665,666,679],{},[138,667,668,671,676],{},[153,669,670],{},"Access token",[153,672,673],{},[110,674,675],{},"pallyy_oat_",[153,677,678],{},"1 hour",[138,680,681,684,689],{},[153,682,683],{},"Refresh token",[153,685,686],{},[110,687,688],{},"pallyy_ort_",[153,690,691],{},"30 days from issue, capped at 365 days after the first token of the connection",[91,693,694,695,698,699,702,703,706],{},"Access tokens are sent as ",[110,696,697],{},"Authorization: Bearer pallyy_oat_..."," to ",[110,700,701],{},"\u002Fmcp",". They are also accepted by the REST API directly, with the grant's scopes and social set restriction, so a client that already holds a token can call ",[110,704,705],{},"https:\u002F\u002Fapp.pallyy.com\u002Fapi\u002Fv1"," with it.",[91,708,709,710,712,713,716,717,720,721,723],{},"A refresh token is only issued when the user approved ",[110,711,531],{},". Refreshing uses ",[110,714,715],{},"grant_type=refresh_token"," with ",[110,718,719],{},"refresh_token"," and ",[110,722,229],{},", returns a new access token, and rotates the refresh token: the old one stops working and the new one gets a fresh 30-day lifetime, until the connection reaches its 365-day cap and the user has to approve it again.",[91,725,726],{},"Presenting a refresh token that has already been rotated is treated as a leak: every token issued from that authorization is revoked and the client has to send the user through consent again. Clients must store the rotated token as soon as the refresh response arrives.",[91,728,729,730,732],{},"Scopes and the social set restriction are read from the grant on every request rather than baked into the token. Re-approving a client updates its outstanding tokens immediately, and a grant that drops ",[110,731,531],{}," ends its refresh chain at the next rotation.",[102,734,211],{"id":735},"revocation",[91,737,738,739,720,742,744,745,754],{},"Clients revoke a token by posting it to the revocation endpoint (RFC 7009) with ",[110,740,741],{},"token",[110,743,229],{},". Users revoke a whole connection from ",[746,747,748],"strong",{},[95,749,753],{"href":750,"rel":751},"https:\u002F\u002Fapp.pallyy.com\u002Fsettings\u002Fconnected-apps",[752],"nofollow","Settings > Connected Apps",", which invalidates every token the client holds.",[102,756,13],{"id":757},"errors",[91,759,760,761,764],{},"OAuth endpoints answer with the standard ",[110,762,763],{},"{ \"error\", \"error_description\" }"," body. The codes you are most likely to meet:",[132,766,767,776],{},[135,768,769],{},[138,770,771,774],{},[141,772,773],{},"Code",[141,775,326],{},[148,777,778,790,802,812,823,837,846],{},[138,779,780,784],{},[153,781,782],{},[110,783,287],{},[153,785,786,787,789],{},"The ",[110,788,229],{}," is not a metadata document URL on a supported host, or the document could not be fetched or is invalid",[138,791,792,797],{},[153,793,794],{},[110,795,796],{},"invalid_redirect_uri",[153,798,786,799,801],{},[110,800,347],{}," is not registered in the client's metadata document",[138,803,804,809],{},[153,805,806],{},[110,807,808],{},"invalid_request",[153,810,811],{},"A required parameter is missing, or PKCE is missing or not S256",[138,813,814,818],{},[153,815,816],{},[110,817,540],{},[153,819,786,820,822],{},[110,821,398],{}," names something other than the scopes above",[138,824,825,830],{},[153,826,827],{},[110,828,829],{},"invalid_target",[153,831,786,832,834,835],{},[110,833,423],{}," is not ",[110,836,112],{},[138,838,839,843],{},[153,840,841],{},[110,842,645],{},[153,844,845],{},"The code or refresh token is expired, used, revoked, or does not match the request",[138,847,848,853],{},[153,849,850],{},[110,851,852],{},"access_denied",[153,854,855],{},"The user cancelled on the consent page",[91,857,858,859,451],{},"Once a token is issued, the MCP server and the REST API report problems with the API's own ",[95,860,861],{"href":12},"error format",{"title":127,"searchDepth":33,"depth":16,"links":863},[864,865,866,867,868,869,870,871],{"id":104,"depth":33,"text":105},{"id":222,"depth":33,"text":223},{"id":307,"depth":33,"text":308},{"id":457,"depth":33,"text":458},{"id":544,"depth":33,"text":545},{"id":648,"depth":33,"text":649},{"id":735,"depth":33,"text":211},{"id":757,"depth":33,"text":13},"2026-09-04","2026-09-07","md",{},true,{"title":25,"description":26},"docs\u002Fapi\u002Fmcp-authorization","ss0yN_gluJ7ylP-C8rgiqR3LOgpY6CAEFxc0SMlT4Vs",[881,882],{"path":18,"title":19,"emoji":22,"order":10},{"path":29,"title":30,"emoji":32,"order":33},1790227250403]