---
title: "Exchange grant for access token"
method: POST
path: "/api/oauth/v2/token"
tags: ["Client Auth"]
---

# Exchange grant for access token

`POST /api/oauth/v2/token`

OAuth 2.0 token endpoint supporting three grant types: `authorization_code` (standard OAuth flow with Basic auth), `urn:ietf:params:oauth:grant-type:device_code` (RFC 8628 device authorization for CLI clients), and `refresh_token` (rotate refresh token and obtain a new access token). The `device_code` and `refresh_token` grants authenticate via the `privy-app-id` header.

## Headers

- `privy-app-id` string — ID of your Privy app.

## Request body

- union — Request body for the OAuth token endpoint, discriminated by grant_type.
  - object — Request body for the authorization_code grant type.
    - `client_id` string — The client ID. Alternative to Basic auth header.
    - `client_secret` string — The client secret. Alternative to Basic auth header.
    - `code` string, required — The authorization code received from the authorization endpoint.
    - `grant_type` 'authorization_code', required
    - `redirect_uri` string — The redirect URI used in the authorization request.
  - object — Request body for the urn:ietf:params:oauth:grant-type:device_code grant type (RFC 8628). Used by CLI clients to poll for authorization.
    - `device_code` string, required — The device code received from the device authorization endpoint.
    - `grant_type` 'urn:ietf:params:oauth:grant-type:device_code', required
  - object — Request body for the refresh_token grant type. Rotates the refresh token and issues a new access token.
    - `grant_type` 'refresh_token', required
    - `refresh_token` string, required — The refresh token to exchange for a new access token.

## Response `200`

Token issued successfully.

- OAuthTokenSuccessResponse — Successful token response per RFC 6749 Section 5.1.
  - `access_token` string, required — The issued access token.
  - `expires_in` number — The lifetime in seconds of the access token.
  - `refresh_token` string — A refresh token for obtaining new access tokens. Issued for device_code and refresh_token grants.
  - `token_type` 'Bearer', required — The type of token issued.

## Other responses

- `400` — The device authorization is still pending, the client is polling too fast, the authorization was denied, or the device code has expired.
- `401` — Invalid credentials, expired refresh token, or invalid grant.

---

[API](https://skmtc.net/privy-io/apis/privy-api.md) · [All operations](https://skmtc.net/privy-io/apis/privy-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/privy-io/privy-api/revisions/bb2eb34156cc/schema)
