---
title: "Exchange a scoped token for an access token"
method: POST
path: "/api/v2/auth/tokens/exchange"
tags: ["Auth Endpoints"]
---

# Exchange a scoped token for an access token

`POST /api/v2/auth/tokens/exchange`

## Request

- Base URL: `https://api.opensea.io`
- URL: `https://api.opensea.io/api/v2/auth/tokens/exchange`
- Auth: none required
- TypeScript: <https://skmtc.dev/opensea/apis/opensea-api/docs/api/v2/auth/tokens/exchange/post.ts> (a function with typed inputs; its response is checked against the schema)

Exchanges an opaque scoped token (personal access token) for a short-lived access token that satisfies `WalletAuth` on wallet-scoped endpoints. Send the returned `accessToken` as `Authorization: Bearer <token>`.

This is the credential path for headless callers that hold no signing key: the scoped token in the request body is the only credential, so no session cookie, wallet signature, or API key is required. The alternative is the OAuth 2.1 authorization-code flow described by the `WalletAuth` security scheme.

Failures are deliberately opaque. An unknown, revoked, rotated, or non-scoped subject token and a disabled integration all return the same 403 `Token exchange is not available`, so a 403 is not by itself evidence that the endpoint is unavailable.

## Request body

- TokenExchangeRequest: Scoped-token exchange request
  - `subjectToken` string, required: The opaque scoped token (personal access token) to exchange. A session JWT is not accepted.
  - `subjectTokenType` 'ACCESS_TOKEN': Type of the presented subject token

## Response `200`

Access token minted

- TokenExchangeResponse: Minted access token
  - `accessToken` string, required: Bearer token to send as `Authorization: Bearer <token>`
  - `expiresIn` integer: Token lifetime in seconds, when the issuer reports one
  - `scope` string: Space-delimited scopes on the minted token, when present
  - `tokenScopes` AuthScope[]: Scopes bound to the presented scoped token at mint time. Requests are authorized against these, not the full account scope set.
  - `tokenType` string, required: Token type

## Other responses

- `400`: Request body failed validation, for example a `subjectToken` outside the 10 to 8192 character range
- `403`: Token exchange is not available. Returned for an unknown, revoked, or non-scoped subject token as well as for a disabled integration; the two are not distinguishable by design.
- `422`: Body could not be read: malformed JSON, a missing required field, or an unsupported `subjectTokenType`
- `429`: Rate limit exceeded
- `500`: Exchange failed after the token was minted
- `502`: Upstream auth service error
- `503`: Upstream auth service temporarily unavailable

## Changes

- **2026-11-03** `2c7935d84f90`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/opensea/apis/opensea-api/changes/api/v2/auth/tokens/exchange/post.md)

---

[API](https://skmtc.dev/opensea/apis/opensea-api.md) - [All operations](https://skmtc.dev/opensea/apis/opensea-api/llms.txt) - [OpenAPI document](https://skmtc.dev/opensea/apis/opensea-api/revisions/2c7935d84f90?raw)
