# Exchange OAuth authorization code, device code, or refresh token.

Exchange OAuth authorization code, device code, or refresh token.

Canonical: https://commentary.dev/docs/reference/api/exchange-oauth-token

`POST /oauth/token`

Exchange OAuth authorization code, device code, or refresh token.

## Access

This operation does not declare a credential requirement in the released API contract.

Provider access, workspace membership, and agent grants are enforced separately. A token does not expand access to a repository or resource. [Set up developer access](/docs/build/developer-access).

## Request body

Required. Supported content types: `application/json`, `application/x-www-form-urlencoded`.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `grant_type` | `"authorization_code"` · `"refresh_token"` · `"urn:ietf:params:oauth:grant-type:device_code"` | Yes |  |
| `code` | string | No |  |
| `redirect_uri` | string | No | Format: uri. |
| `client_id` | string | No |  |
| `code_verifier` | string | No |  |
| `refresh_token` | string | No |  |
| `device_code` | string | No |  |
| `resource` | string | No |  |

## Call the endpoint

Replace path placeholders and your credential. For body operations, create `request.json` using the required fields above; this command does not invent resource identifiers or consent.

```bash
curl --request POST \
  'https://commentary.dev/oauth/token' \
  --header 'Content-Type: application/json' \
  --data-binary @request.json
```

## Responses

| Status | Meaning | Payload |
| --- | --- | --- |
| `200` | Successful response. | [OAuthToken](/docs/reference/schemas/oauth-token) |
| `400` | OAuth request error. | [OAuthError](/docs/reference/schemas/oauth-error) |
| `401` | OAuth token exchange was rejected. | [OAuthError](/docs/reference/schemas/oauth-error) |
| `429` | The request was rate limited. | [OAuthError](/docs/reference/schemas/oauth-error) |

### Successful response fields

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `access_token` | string | Yes |  |
| `refresh_token` | string | Yes |  |
| `token_type` | `"Bearer"` | Yes |  |
| `expires_in` | integer | Yes |  |
| `scope` | string | Yes | Space-delimited scopes actually granted to this token. Registered OAuth clients may receive a subset of requested scopes. |

## Recover from errors

Use the returned status and error body. Correct invalid fields before retrying; reconnect or narrow the target for authentication and permission errors. For conditional writes, reload the latest version before preparing a new request. Respect rate-limit headers and retry only when the operation’s idempotency contract permits it.

## Contract and related guidance

Operation ID: `exchangeOAuthToken`. [Download the OpenAPI contract](/docs/reference/openapi.json) for complete constraints and code generation. [Browse endpoints](/docs/reference/api-operations).
