> Docs index: https://convertextrato.com/llms.txt

# Authentication


## API keys

Send your API key as a Bearer token in the `Authorization` header of every request:

```bash
curl https://energized-butterfly-12.convex.site/v1/jobs \
  -H "Authorization: Bearer bsk_live_..."
```

Keys start with `bsk_live_`. A missing, invalid, revoked or expired key returns `401 INVALID_API_KEY`.

The owner or an admin of the account manages keys on the [API keys page](https://convertextrato.com/admin/api-keys). There you can:

- **Create** a key with a name, an access level and an expiration (30, 90 or 365 days, or never). The key is shown only once.
- **Revoke** a key. Requests with it fail at once.

Keep keys on your server. Never ship them in a browser or mobile app.

## Permissions

Each key has one access level for Jobs:

| Access level   | Permissions               | Allows                                               |
| -------------- | ------------------------- | ---------------------------------------------------- |
| Read-only      | `jobs:read`               | List Jobs, get Jobs and Statement Files with results |
| Read and write | `jobs:read`, `jobs:write` | Everything above, plus upload files and delete Jobs  |

Each endpoint needs one permission:

| Endpoint                                     | Permission   |
| -------------------------------------------- | ------------ |
| `POST /v1/jobs`                              | `jobs:write` |
| `GET /v1/jobs`                               | `jobs:read`  |
| `GET /v1/jobs/{id}`                          | `jobs:read`  |
| `GET /v1/jobs/{id}/statement-files/{fileId}` | `jobs:read`  |
| `DELETE /v1/jobs/{id}`                       | `jobs:write` |

A key without the permission gets `403 PERMISSION_DENIED`.

Give each integration the lowest access it needs. For example, a dashboard that only shows results needs a read-only key.

## Plans and quotas

The plan of the account owner decides API access. The **Starter** and **Professional** plans include the API. Other plans get `402 PLAN_REQUIRED`.

| Plan         | Pages per month | Pages per file |
| ------------ | --------------- | -------------- |
| Starter      | 50              | 20             |
| Professional | 200             | 20             |

API uploads and web app uploads share the same monthly pages. A Job that does not fit in the pages left returns `402 QUOTA_EXCEEDED`, and no pages are spent. The quota resets at 00:00 UTC on the first day of each month.

Images count as one page each.

## Rate limits

Each account can make 60 requests per minute, across all of its keys. Over the limit, the API returns `429 RATE_LIMITED` with a `Retry-After` header. The header holds the number of seconds to wait before retrying.
