Skip to main content
POST
/
auth
/
token-exchange
Exchange API key for tokens
curl --request POST \
  --url https://api.getmetacognition.com/auth/token-exchange \
  --header 'Content-Type: application/json' \
  --data '
{
  "api_key": "<string>"
}
'
{
  "access_token": "<string>",
  "refresh_token": "<string>",
  "token_type": "<string>",
  "expires_in": 123
}
Exchange your API key for an access token and refresh token. This is the HTTP version of what the SDK does on first use. See Authentication for the full flow. Call this directly only when you are not using the Python SDK, or when another service brokers tokens for your app.

Body

{
  "api_key": "tex_live_..."
}
api_key
string
required
Your API key.

Response — 200

access_token
string
RS256-signed JWT. Send as Authorization: Bearer <access_token> on subsequent calls. Lifetime: 24h.
refresh_token
string
Refresh JWT. Use to obtain a new access token without re-exchanging the API key. Lifetime: 7d.
token_type
string
Always "bearer".
expires_in
number
Access-token lifetime in seconds.

Example

curl -X POST https://api.getmetacognition.com/auth/token-exchange \
  -H 'content-type: application/json' \
  -d '{"api_key":"tex_live_..."}'
Response
{
  "access_token": "eyJhbGciOiJSUzI1NiIs...",
  "refresh_token": "eyJhbGciOiJSUzI1NiIs...",
  "token_type": "bearer",
  "expires_in": 86400
}

JWT contents

Decode the access token if you want to inspect its claims. If you need to trust those claims, verify the token with the JWKS endpoint.
{
  "org_id": "org_79d0fHwDRhoZ8Ww7",
  "user_id": "apikey_a1247653",
  "roles": ["*"],
  "exp": 1778147808,
  "iat": 1778061408,
  "type": "access"
}
The org_id and user_id claims are what server-side scoping reads. They cannot be overridden by request bodies.