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

# Access tokens

> Issue a short-lived bearer token, use it, and refresh it by re-issuing.

Protected requests use a short-lived bearer token. You obtain it from the public
token endpoint by exchanging your client credentials.

## Issue a token

`POST /v1/auth/token` is public; it does not require a bearer token, the
`x-zeam-auth` header, or the `x-association-id` header.

<ParamField body="clientId" type="string" required>
  Your application's client ID.
</ParamField>

<ParamField body="clientSecret" type="string" required>
  Your application's client secret.
</ParamField>

```bash cURL theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
curl -sS https://api.zeam.money/gw/v1/auth/token \
  -H "Content-Type: application/json" \
  -d '{
    "clientId": "11111111-1111-1111-1111-111111111111",
    "clientSecret": "$ZEAM_CLIENT_SECRET"
  }'
```

```json Response theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
{
  "accessToken": "eyJ0eXAiOiJKV1Qi...",
  "tokenType": "Bearer",
  "expiresIn": 3599,
  "associationId": "d290f1ee-6c54-4b01-90e6-d701748f0851"
}
```

<ResponseField name="accessToken" type="string">
  The bearer token. Send it as `Authorization: Bearer <accessToken>`.
</ResponseField>

<ResponseField name="tokenType" type="string">
  Always `Bearer`.
</ResponseField>

<ResponseField name="expiresIn" type="integer">
  Seconds until the token expires.
</ResponseField>

<ResponseField name="associationId" type="string">
  The association bound to your application. Send it as the `x-association-id`
  header on every protected request.
</ResponseField>

## Use a token

Send the token with your application secret and association id on every
protected request:

```bash cURL theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
curl -sS https://api.zeam.money/gw/v1/wallets \
  -H "Authorization: Bearer $ZEAM_TOKEN" \
  -H "x-zeam-auth: $ZEAM_APP_SECRET" \
  -H "x-association-id: $ZEAM_ASSOCIATION_ID"
```

## Refresh a token

Tokens are short-lived and there is no refresh token. To refresh, call
`POST /v1/auth/token` again with your client credentials and use the new token.

<Tip>
  Cache the token server-side and reuse it until shortly before `expiresIn`
  elapses, then request a new one. Re-issuing on every request is unnecessary
  and may hit [rate limits](/platform/rate-limits).
</Tip>

## Errors

The token endpoint can return:

* `400`, the request body is malformed.
* `401`, the client credentials are invalid.
* `429`, too many requests; honor the `Retry-After` header.

All errors use the [RFC 7807 problem format](/platform/errors).
