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

# Authentication & Rate Limiting

The Travtus API requires every request to be authenticated using a Bearer token.
Tokens are obtained via the OAuth 2.0 `client_credentials` grant using the credentials provided to you by Travtus.

<Steps>
  <Step title="Request an access token">
    POST your credentials to the token endpoint to receive an access token valid for **60 minutes**.
  </Step>

  <Step title="Call the API">
    Include the access token in the `Authorization` header of every API request.

    ```bash theme={null}
    Authorization: Bearer <access_token>
    ```
  </Step>

  <Step title="Re-authenticate when the token expires">
    The token is valid for **60 minutes** (3600 seconds). Request a new token before it expires to maintain uninterrupted access.
  </Step>
</Steps>

***

## Request an Access Token

### Request body (`application/x-www-form-urlencoded`)

<ParamField body="client_id" type="string" required>
  Your API client ID.
</ParamField>

<ParamField body="client_secret" type="string" required>
  Your API client secret.
</ParamField>

<ParamField body="grant_type" type="string" required>
  Must be `client_credentials`.
</ParamField>

### Response

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

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

<ResponseField name="expires_in" type="integer">
  Seconds remaining until the token expires. Up to 3600 on a fresh token (60 minutes).
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST 'https://api.travtus.com/oauth2/token' \
    -H 'Content-Type: application/x-www-form-urlencoded' \
    -d 'grant_type=client_credentials' \
    -d 'client_id=<client-id>' \
    -d 'client_secret=<client-secret>'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'https://api.travtus.com/oauth2/token',
      headers={'Content-Type': 'application/x-www-form-urlencoded'},
      data={
          'grant_type': 'client_credentials',
          'client_id': '<client-id>',
          'client_secret': '<client-secret>',
      }
  )
  token_data = response.json()
  access_token = token_data['access_token']
  ```

  ```typescript TypeScript theme={null}
  async function getAccessToken(): Promise<string> {
    const params = new URLSearchParams({
      grant_type: 'client_credentials',
      client_id: '<client-id>',
      client_secret: '<client-secret>',
    });

    const response = await fetch('https://api.travtus.com/oauth2/token', {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: params,
    });

    const tokenData = await response.json();
    return tokenData.access_token;
  }
  ```
</RequestExample>

<ResponseExample>
  ```json Response theme={null}
  {
    "access_token": "eyJraWQiOiJzXC9jaDliOVJcL1FwM1lzamQ4cHA1aXRodjJENkxoY1lqSFp4YVE4cFVXNmM9IiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIzaDc5aGs0c29mdXNiM2Z0Z25rMTMzZzBqNCIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoidHJhdnR1cy1hcGlcL2tub3dsZWRnZS1ncmFwaCIsImF1dGhfdGltZSI6MTcwNTQ4ODc5OCwiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tXC91cy1lYXN0LTJfa21KUXNXQVJKIiwiZXhwIjoxNzA1NDkyMzk4LCJpYXQiOjE3MDU0ODg3OTgsInZlcnNpb24iOjIsImp0aSI6Ijc4OGU5MGIxLTBjYjMtNGRhYi04ZTcxLTY1MTBmZWJjOWMzNiIsImNsaWVudF9pZCI6IjNoNzloazRzb2Z1c2IzZnRnbmsxMzNnMGo0In0.ig8jULH9Y01bvFtUAR_XJO5ljR60mo3XdFXiA58qbNpKSNwvJx1tqpLLOSYTG19O_ZrPBpOAT-kPPlYyL9mqacQvybr_CeWkFp_9WuQP8zSEvrDbg7_jwXN4JYSItEVc_NSs2PArUhYEB_gkOOSs814-DO726L6hUr3R6rn1Wk3bz-KU--U9gI9xh0cvQ0RGD1bCryTAG9qSmrz0LR8Dw96jrCPU0Sgv57gXvJ8M1Z-7oa8ajnwfRJaRGQired8coOt9mFiYPjR5GJWW5QCPELpOTKFJRWfi5nc9vvyKLJgdPeGqQyqruj_bBgA7b9hkwePbpNPRt6f9WVl11ip12w",
    "token_type": "Bearer",
    "expires_in": 3600
  }
  ```
</ResponseExample>

***

## Call the API

Include the `access_token` in the `Authorization` header of every request.

```
Authorization: Bearer <access_token>                                                                                                      
```

<Note>
  The bearer token is valid for **60 minutes** (3600 seconds). Once it expires, you must re-authenticate to obtain a new token. Requesting a new token on every API call is unnecessary and may result in throttling.
</Note>

<CodeGroup>
  ```python Python theme={null}
  import requests
  import json

  url = "https://api.travtus.com/messages/"

  payload = json.dumps({
    "channel": "email",
    "group_external_ref": "<community-external-ref>",
    "first_name": "First",
    "last_name": "Last",
    "email": {
      "source": "<source>",
      "message_id": "<message-id>",
      "text": "<message-text>",
      "created_datetime": "2025-06-27T16:45:13.000000",
      "from_email_address": "<from-email>",
      "to_email_addresses": "<to-email>",
      "subject": "<subject>",
      "conversation_id": "<conversation-id>",
      "references": []
    }
  })

  response = requests.post(url, headers={
    'Content-Type': 'application/json',
    'Authorization': 'Bearer <access_token>'
  }, data=payload)

  print(response.text)
  ```

  ```typescript TypeScript theme={null}
  async function sendMessage(accessToken: string): Promise<void> {
    const url = "https://api.travtus.com/messages/";

    const payload = {
      channel: "email",
      group_external_ref: "<community-external-ref>",
      first_name: "First",
      last_name: "Last",
      email: {
        source: "<source>",
        message_id: "<message-id>",
        text: "<message-text>",
        created_datetime: "2025-06-27T16:45:13.000000Z",
        from_email_address: "<from-email>",
        to_email_addresses: "<to-email>",
        subject: "<subject>",
        conversation_id: "<conversation-id>",
        references: [],
      },
    };

    const response = await fetch(url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${accessToken}`,
      },
      body: JSON.stringify(payload),
    });

    const data = await response.json();
    console.log(data);
  }
  ```
</CodeGroup>

***

## Rate Limiting

The Travtus API enforces rate limits to ensure platform stability and fair usage across all clients. Exceeding a limit returns HTTP **429 Too Many Requests**. Implement exponential backoff when retrying after a 429 response.

### Token endpoint (`/oauth2/token`)

| Limit          | Value               |
| -------------- | ------------------- |
| Sustained rate | 100 requests/second |
| Burst          | 200 requests        |

### All other API endpoints

| Limit          | Value                  |
| -------------- | ---------------------- |
| Sustained rate | 10,000 requests/second |
| Burst          | 5,000 requests         |

### How limits are applied

* Limits are applied per API key at the API Gateway level.
* The burst limit allows short spikes above the sustained rate.
* Clients should implement retry logic with exponential backoff on 429 responses.
