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

# Authentication

> Authenticate with the Topify.ai public API using API keys.

The public API uses API key authentication. Every request must include your key in the `X-API-Key` header.

## Request header

```
X-API-Key: tk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

## Getting an API key

Generate API keys from your Topify.ai dashboard under **Management > Members**, or programmatically via the [agentic setup](/api-reference/agentic-setup) endpoints. Each key is scoped to your team and gives access to all projects owned by that team. Only team admins can create API keys.

<Note>
  You can view and copy the full API key from the Members page at any time. Keys created before March 2026 only display a prefix -- create a new key if you need the full value.
</Note>

## Rate limiting

Requests are rate-limited per API key. Limits depend on your plan tier:

| Tier     | Requests per minute | Burst allowance | Total per window |
| -------- | ------------------- | --------------- | ---------------- |
| Standard | 60                  | 10              | 70               |
| Premium  | 300                 | 50              | 350              |

### Response headers

Every response includes rate limit information:

| Header                  | Type    | Description                                             |
| ----------------------- | ------- | ------------------------------------------------------- |
| `X-RateLimit-Limit`     | integer | Maximum requests allowed in the current window          |
| `X-RateLimit-Remaining` | integer | Requests remaining before throttling                    |
| `Retry-After`           | integer | Seconds until the window resets (only present on `429`) |

### Rate limit exceeded

When you exceed the limit, the API returns HTTP `429`:

```json theme={null}
{
  "detail": "Rate limit exceeded. Retry after 42 seconds."
}
```

## Key lifecycle

| State        | Behavior                                          |
| ------------ | ------------------------------------------------- |
| **Active**   | Key is valid and accepts requests                 |
| **Inactive** | Key has been disabled by an admin. Returns `401`  |
| **Expired**  | Key has passed its expiration date. Returns `401` |

You can deactivate or delete keys at any time from the dashboard.

## Example requests

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X GET "https://topify-customer-api-production.up.railway.app/api/public/v1/projects" \
      -H "X-API-Key: tk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import httpx

    client = httpx.Client(
        base_url="https://topify-customer-api-production.up.railway.app/api/public/v1",
        headers={"X-API-Key": "tk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"},
    )

    resp = client.get("/projects")
    print(resp.json())
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const BASE_URL = "https://topify-customer-api-production.up.railway.app/api/public/v1";
    const API_KEY = "tk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

    const resp = await fetch(`${BASE_URL}/projects`, {
      headers: { "X-API-Key": API_KEY },
    });
    const data = await resp.json();
    console.log(data);
    ```
  </Tab>
</Tabs>

## Error responses

| Status | Detail                                        | Cause                                   |
| ------ | --------------------------------------------- | --------------------------------------- |
| `401`  | `Missing X-API-Key header`                    | No `X-API-Key` header provided          |
| `401`  | `Invalid API key`                             | Key hash not found in the database      |
| `401`  | `API key is inactive`                         | Key was disabled by an admin            |
| `401`  | `API key has expired`                         | Key passed its `expires_at` date        |
| `429`  | `Rate limit exceeded. Retry after N seconds.` | Too many requests in the current window |
