Get an access token
Exchange the code from your callback for a pos_ access token.
Authorization.
The code works once, for 10 minutes: the exchange spends it. Run the same request twice and the second answers 400 invalid_grant. A wrong secret and an unknown Client ID both answer 401 invalid_client, so the answer does not say which one is wrong.
A client that registered itself with token_endpoint_auth_method: none sends no secret. It sends the PKCE code_verifier and the redirect_uri it used on the consent URL instead.
Send the token on /public/v1 as Authorization: pos_..., with no prefix, even though token_type says bearer. When it stops working is on OAuth apps.Body
Must be authorization_code
authorization_code The authorization code from your callback URL
Your app's Client ID. Leave it out when you send it in a Basic Authorization header
Your app's Client Secret (starts with pcs_). Leave it out with Basic auth, or for a public PKCE client
The PKCE verifier, required when the authorization request carried a code_challenge
Required when the authorization request carried one, and must match it
Response
The access token
The workspace the person approved your app for
The workspace's billing customer id, or null
The token to send in the Authorization header (starts with pos_)
Always bearer. On /public/v1 send the token with no prefix all the same
Granted scopes: mcp:read mcp:write, plus openid email for clients allowed email claims