> ## Documentation Index
> Fetch the complete documentation index at: https://learn.nexudus.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Refresh a bearer token

> Use an existing refresh token to obtain a new access token and refresh token without requiring the customer to re-enter their password.

# Refresh a bearer token

Uses a refresh token to obtain a new access token and refresh token without requiring the customer to re-enter their password. This is useful when the access token has expired but you want to maintain the customer's session.

<Note>
  Unlike most Nexudus API endpoints, this request must be encoded as `application/x-www-form-urlencoded`, **not** `application/json`. Sending a JSON
  body will result in an `unsupported_grant_type` error.
</Note>

## Authentication

No authentication required. This endpoint uses the refresh token itself as the credential.

## Request Body

<ParamField body="grant_type" type="string" required>
  Must be `refresh_token` to use the refresh token grant flow.
</ParamField>

<ParamField body="refresh_token" type="string" required>
  The refresh token previously received from the sign-in endpoint.
</ParamField>

## Headers

<ParamField header="client_id" type="string" required>
  The client identifier that was used when obtaining the bearer token. If the `client_id` was provided during sign-in, use that value. If `client_id` was omitted during sign-in, use the customer's email address (which defaults to the `client_id` automatically).
</ParamField>

## Response

<ResponseField name="access_token" type="string">
  New bearer token to include in the `Authorization` header of all subsequent authenticated requests.
</ResponseField>

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

<ResponseField name="expires_in" type="number">
  Lifetime of the new access token in seconds.
</ResponseField>

<ResponseField name="refresh_token" type="string">
  New refresh token to use for subsequent refresh operations. The previous refresh token is invalidated.
</ResponseField>

## Examples

### Successful token refresh

```http theme={null}
POST /api/token
Content-Type: application/x-www-form-urlencoded
client_id: jane.doe@example.com

grant_type=refresh_token&refresh_token=8xLOxBtZp8
```

```json theme={null}
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer",
  "expires_in": 86400,
  "refresh_token": "9yMPyCuQr9"
}
```

## TypeScript Integration

```typescript theme={null}
import { type AxiosResponse } from 'axios'
import qs from 'qs'
import { type AuthToken } from '@/states/useAuthContext'

const data = {
  grant_type: 'refresh_token',
  refresh_token: session.refreshToken,
}

const res: AxiosResponse<AuthToken> = await httpClient.post('/api/token', qs.stringify(data), {
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'client_id': session.clientId, // or email if client_id was omitted during sign-in
  },
})

if (res.data.access_token) {
  saveSession({ tokenResponse: res.data, remember: values.rememberMe })
}
```

## Error Responses

<ResponseField name="400 Bad Request — unsupported_grant_type" type="error">
  The `grant_type` field is missing or the body was not encoded as `application/x-www-form-urlencoded`.
</ResponseField>

<ResponseField name="400 Bad Request — invalid_grant" type="error">
  The refresh token is invalid, expired, or has already been used. The `error_description` field contains a human-readable reason.
</ResponseField>

## Related Endpoints

| Method | Endpoint                       | Description                                               |
| ------ | ------------------------------ | --------------------------------------------------------- |
| `POST` | `/api/token`                   | *(this endpoint)* Exchange credentials for a bearer token |
| `POST` | `/api/sys/users/token/refresh` | Get a short-lived server-side JWT for authenticated links |
