# Authentication

Every request carries an API key of your agency. Keys are created in your panel under **Developers → API keys** and start with `tam_live_`.

The API works on your agency's real data: bookings are made with the airlines your agency uses and paid from your agency wallet, and they appear in your panel's booking list like any other booking. To build and test without real tickets, use your platform's **test server** (same API, simulated airlines) with a key created there.

## Sending the key

```http
Authorization: Bearer tam_live_ab12cd34XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```

Keys are secrets. Call the API **from your server only** — never from a browser, a mobile app or anything a customer can inspect.

## Scopes

A key only reaches the endpoints its scopes allow; anything else returns `403 auth.insufficient_scope`. Give each system the smallest set it needs — for example, a price-display widget backend needs only `flights:read`.

A scope is only available when the module behind it is installed for your agency (`flights:*` needs the flight module).

## IP allow-list (recommended)

When you create or edit a key you can list the IP addresses or CIDR ranges (`203.0.113.10`, `203.0.113.0/24`, IPv6 too) it may be used from. Requests from other addresses get `403 auth.ip_not_allowed`.

## Expiry, rotation and revocation

- **Expiry** — optional; after it the key returns `401 auth.key_expired`.
- **Rotate** — creates a new key with the same settings. The old key keeps working for **24 hours**, so you can deploy the new one without downtime.
- **Revoke** — stops the key immediately (`401 auth.key_revoked`). Do this at once if a key may have leaked.

The panel shows when and from which IP each key was last used.

## Checking a key

```bash
curl https://quickota.com/api/v1/account -H "Authorization: Bearer tam_live_..."
```

```json
{
  "data": { "agencyId": "…", "keyId": "…", "scopes": ["flights:read", "flights:book"] },
  "meta": { "requestId": "req_…" }
}
```

## Authentication errors

| Code | Status | Meaning |
|---|---|---|
| `auth.missing_key` | 401 | No `Authorization: Bearer` header. |
| `auth.invalid_key` | 401 | Unknown or malformed key. |
| `auth.key_expired` / `auth.key_revoked` | 401 | Create or rotate a key in the panel. |
| `auth.ip_not_allowed` | 403 | Calling IP is not on the key's allow-list. |
| `auth.insufficient_scope` | 403 | The key lacks the scope this endpoint needs. |
| `account.module_not_installed` | 403 | Your agency does not have the product installed. |
| `account.api_suspended` | 403 | API access is suspended — contact support. |
