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

# Authentication

> Authenticate requests with a Bearer API key

All API requests require a Bearer token in the `Authorization` header.

## Making authenticated requests

Include your API key in every request:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.clevis.dev/v1/payroll/calculate \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{ ... }'
  ```

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

  response = httpx.post(
      "https://api.clevis.dev/v1/payroll/calculate",
      headers={"Authorization": "Bearer YOUR_API_KEY"},
      json={ ... },
  )
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://api.clevis.dev/v1/payroll/calculate", {
    method: "POST",
    headers: {
      Authorization: "Bearer YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ ... }),
  });
  ```
</CodeGroup>

<Warning>
  Keep your API key secret. Do not expose it in client-side code, public repositories, or browser-accessible environments.
</Warning>

## Rate limits

Each API key is limited to **120 requests per minute** by default. When exceeded, the API returns a `429` status with the `RATE_LIMIT_EXCEEDED` error code.

## Authentication errors

| Code                  | HTTP | Description                            |
| --------------------- | ---- | -------------------------------------- |
| `MISSING_AUTH_TOKEN`  | 401  | No `Authorization` header provided     |
| `INVALID_API_KEY`     | 401  | The API key is not in the allowed list |
| `RATE_LIMIT_EXCEEDED` | 429  | Too many requests per minute           |

```json theme={null}
{
  "error": {
    "code": "MISSING_AUTH_TOKEN",
    "message": "Authorization header is required",
    "details": {},
    "request_id": "01HX9B2KM3..."
  }
}
```

## Request ID

Every API response includes a unique `request_id` (in the response body and the `X-Request-ID` header). Include this ID when contacting support to help us trace your request through our logs.
