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

# Authentication

> API keys, rate limits, and error handling.

## API keys

Every `/v1` request needs an API key sent as a bearer token:

```bash theme={null}
curl "https://api.onroamly.com/v1/destinations" \
  -H "Authorization: Bearer rk_live_…"
```

Keys are created from the [API page in your Roamly
account](https://www.onroamly.com/account/api). API access is enabled per
account — if you don't see the page, contact
[hello@onroamly.com](mailto:hello@onroamly.com).

<Warning>
  A key's full value is shown **once**, when it's created. Store it somewhere
  safe — if you lose it, revoke the key and create a new one. Revocation takes
  effect immediately.
</Warning>

You can hold up to 5 active keys, so you can rotate without downtime: create a
new key, switch your integration over, then revoke the old one.

## Rate limits

Each key may make **120 requests per minute**. Beyond that, requests return
`429` with a `Retry-After` header. The whole catalog fits in a couple of
requests, so most integrations sit nowhere near the limit.

## Errors

Errors use conventional HTTP status codes with a JSON body:

```json theme={null}
{
  "error": {
    "code": "invalid_api_key",
    "message": "Unknown API key."
  }
}
```

| Status | Code                    | Meaning                                           |
| ------ | ----------------------- | ------------------------------------------------- |
| 401    | `missing_api_key`       | No `Authorization` header was sent                |
| 401    | `invalid_api_key`       | The key is malformed or unknown                   |
| 401    | `revoked_api_key`       | The key was revoked                               |
| 403    | `api_access_disabled`   | API access is switched off for the account        |
| 400    | `invalid_currency`      | `currency` must be `AUD` or `USD`                 |
| 400    | `invalid_destination`   | `destination` must be a non-empty slug            |
| 404    | `destination_not_found` | No destination with that slug                     |
| 404    | `plan_not_found`        | No plan with that id                              |
| 404    | `not_found`             | Unknown route                                     |
| 429    | `rate_limited`          | Slow down and retry after the `Retry-After` delay |
| 405    | `method_not_allowed`    | Only `GET` is supported                           |
