> ## Documentation Index
> Fetch the complete documentation index at: https://metacognition-fdc534de-master.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Exchange API key for tokens

> Exchange an API key for short-lived access and refresh JWTs.

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](/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

```json theme={null}
{
  "api_key": "tex_live_..."
}
```

<ParamField body="api_key" type="string" required>
  Your API key.
</ParamField>

## Response — `200`

<ResponseField name="access_token" type="string">
  RS256-signed JWT. Send as `Authorization: Bearer <access_token>` on subsequent calls. Lifetime: 24h.
</ResponseField>

<ResponseField name="refresh_token" type="string">
  Refresh JWT. Use to obtain a new access token without re-exchanging the API key. Lifetime: 7d.
</ResponseField>

<ResponseField name="token_type" type="string">
  Always `"bearer"`.
</ResponseField>

<ResponseField name="expires_in" type="number">
  Access-token lifetime in seconds.
</ResponseField>

## Example

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.getmetacognition.com/auth/token-exchange \
    -H 'content-type: application/json' \
    -d '{"api_key":"tex_live_..."}'
  ```

  ```python Python theme={null}
  import httpx

  resp = httpx.post(
      "https://api.getmetacognition.com/auth/token-exchange",
      json={"api_key": "tex_live_..."},
  )
  tokens = resp.json()
  access = tokens["access_token"]
  ```

  ```js JavaScript theme={null}
  const resp = await fetch(
    "https://api.getmetacognition.com/auth/token-exchange",
    {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ api_key: "tex_live_..." }),
    }
  );
  const tokens = await resp.json();
  ```
</CodeGroup>

```json Response theme={null}
{
  "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](https://api.getmetacognition.com/.well-known/jwks.json).

```json theme={null}
{
  "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.
