> Markdown version of https://authpi.com/docs/reference/idp-api/token/ — fetch the complete AuthPI docs index at https://authpi.com/llms.txt to discover all available pages.

# Token — AuthPI Identity Provider API

Token endpoints for exchanging authorization codes for tokens and refreshing access tokens. Supports the `authorization_code` and `refresh_token` grant types.

## POST /{issuer_id}/token

**Token Endpoint**

Exchanges grants for access tokens (RFC 6749).

## Authorization Code Exchange (§4.1.3)

```
POST /{issuer_id}/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code={authorization_code}
&redirect_uri={redirect_uri}
&client_id={client_id}
&code_verifier={code_verifier}
```

## Refresh Token Exchange (§6)

```
POST /{issuer_id}/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
&refresh_token={refresh_token}
&client_id={client_id}
```

**Token Rotation:** A new refresh token is issued with each refresh request. The previous refresh token is invalidated.

## Client Credentials (§4.4)

For M2M clients (`c_` prefix) and agents (`agt_` prefix):

```
POST /{issuer_id}/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&client_id={client_id}
&client_secret={client_secret}
&scope={scope}
&resource={audience}
```

Or use HTTP Basic auth with client_id:client_secret. Returns an access token only — no refresh token or ID token.

## Client Authentication

- **Confidential clients** must authenticate using HTTP Basic auth or by including `client_id` and `client_secret` in the request body
- **Public clients** must include `client_id` and use PKCE

**Specifications**: [RFC 6749](https://tools.ietf.org/html/rfc6749), [RFC 8707](https://tools.ietf.org/html/rfc8707)

### Request body

Content type: `application/x-www-form-urlencoded`

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `grant_type` | authorization_code \| refresh_token \| client_credentials | Required | The type of grant being exchanged. Use 'authorization_code' for initial token exchange, 'refresh_token' for token renewal, 'client_credentials' for machine-to-machine auth. |
| `code` | string | Optional | The authorization code received from the authorize endpoint. Required when grant_type is 'authorization_code'. |
| `refresh_token` | string | Optional | The refresh token from a previous token response. Required when grant_type is 'refresh_token'. |
| `client_id` | string | Optional | Your application's client ID. Required for public clients; optional for confidential clients using HTTP Basic auth. |
| `client_secret` | string | Optional | Your application's client secret. Required for confidential clients if not using HTTP Basic auth. |
| `redirect_uri` | string | Optional | Must exactly match the redirect_uri used in the authorization request. Required for authorization_code grant. |
| `scope` | string | Optional | Space-separated list of scopes. For refresh_token grants, must be a subset of the originally granted scopes. |
| `code_verifier` | string | Optional | The PKCE code verifier that corresponds to the code_challenge sent in the authorization request. Required if PKCE was used. |
| `resource` | string | Optional | Resource indicator (RFC 8707). Sets the access token audience. For client_credentials grants. |

### Responses

| Code | Description | Schema |
| --- | --- | --- |
| 200 | **Success** - Tokens issued successfully. | `TokenResponse` |
| 400 | **Bad Request** - The request is malformed or missing required parameters. | `OAuthError` |
| 401 | **Unauthorized** - Authentication is required or has failed. | `OAuthError` |
| 403 | **Forbidden** - The authenticated client or user lacks permission for this operation. | `OAuthError` |
| 404 | **Not Found** - The requested resource does not exist. | `OAuthError` |
| 422 | **Unprocessable Entity** - The request syntax is correct but the data cannot be processed. | `OAuthError` |
| 429 | **Too Many Requests** - Rate limit exceeded. | `OAuthError` |
| 500 | **Internal Server Error** - An unexpected error occurred. | `OAuthError` |
