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

# Authentication

> Generate a Bearer access token with your Client ID and Client Secret, and use it to call the Perform.AI Public API.

Every Perform.AI Public API endpoint requires a Bearer access token. You generate the token with the OAuth 2.0 client credentials flow, using the API credentials from your account, and send it in the `Authorization` header of each request.

## Prerequisites

* A Perform.AI account with API access.
* Your **Client ID** and **Client Secret**: log in and go to **Integrations > API**. If no credentials have been generated yet, select **Request Credentials**.

<Warning>
  Treat your Client Secret like a password. Never expose it in client-side code, mobile apps, or public repositories — token generation belongs on your server.
</Warning>

## Generate a token

<Steps>
  <Step title="Build the Basic authentication header">
    Combine your credentials as `client_id:client_secret` and Base64-encode the result:

    ```bash theme={null}
    echo -n "your_client_id:your_client_secret" | base64
    ```

    The `Authorization` header value is `Basic` followed by the encoded string.
  </Step>

  <Step title="Send the token request">
    Send a `POST` request to `/auth/oauth/token/` with a form-encoded body. Note the request format: `application/x-www-form-urlencoded`, not JSON.

    ```bash theme={null}
    curl --request POST \
      --url https://api.perform.ai/auth/oauth/token/ \
      --header 'Authorization: Basic eW91cl9jbGllbnRfaWQ6eW91cl9jbGllbnRfc2VjcmV0' \
      --header 'Content-Type: application/x-www-form-urlencoded' \
      --data 'grant_type=client_credentials'
    ```
  </Step>

  <Step title="Read the response">
    A successful request returns the token and its lifetime:

    ```json theme={null}
    {
      "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
      "expires_in": 3600,
      "token_type": "Bearer"
    }
    ```

    Unlike other endpoints, this response has no `api_response` field.
  </Step>

  <Step title="Call the API with the token">
    Send the token in the `Authorization` header of every other request:

    ```bash theme={null}
    curl --request GET \
      --url 'https://api.perform.ai/v5/carrier-configs/' \
      --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...'
    ```

    <Check>
      If the response contains `"api_response": "200"`, your authentication setup works end to end.
    </Check>
  </Step>
</Steps>

## Token lifetime

* Tokens are valid for **1 hour** (`expires_in: 3600` seconds).
* Requesting a new token does not invalidate existing ones — multiple tokens can be valid at the same time, so you can fetch a fresh token before the old one expires and rotate without downtime.
* Generate tokens on demand or on a schedule; there is no refresh token in this flow.

## Troubleshooting

| Symptom                                                                     | Cause and fix                                                                                                                                                                        |
| --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Token request returns HTTP 403 with `"message": "Key not authorized"`       | The Client ID or Client Secret is wrong, or the Basic header is malformed. Re-check the credentials under **Integrations > API** and confirm the Base64 encoding has no line breaks. |
| Functional endpoint returns HTTP 403 with `"message": "Key not authorized"` | The Bearer token is expired or invalid. Generate a new token and retry.                                                                                                              |
| Token request returns an HTML error or times out                            | Confirm you are calling `https://api.perform.ai/auth/oauth/token/` — HTTPS, with the trailing slash.                                                                                 |

## Next steps

* Follow the [quickstart](/quickstart) to create your first shipment.
* Read [responses and errors](/api-reference/overview) to understand the `api_response` envelope used by all functional endpoints.
