# Create and send API keys

Every billed Paxa API request authenticates with an API key sent as a request header. Create keys in the dashboard, send them on each request, and cap what each key can spend.

Every billed request to the Paxa API authenticates with an API key sent as a request header. Keys start with `pxa_` and belong to your account. A request without a valid key answers [401 unauthorized](https://paxalabs.com/docs/errors#unauthorized). The catalog endpoints ([models](https://paxalabs.com/docs/api/models), [voices](https://paxalabs.com/docs/api/voices)) and [health](https://paxalabs.com/docs/api/health) are public and need no key.

## Create a key

Create keys on the [API keys page](https://paxalabs.com/app/keys) of the dashboard. The full key is shown exactly once, at creation. Only a hash is stored, and the key cannot be shown again. An account holds up to 20 keys, counting disabled ones.

## Send a key

Send the key in the `Authorization` header with the `Bearer` scheme, or in the `x-api-key` header. When both are present, `Authorization` wins. A malformed `Authorization` header is rejected, and the server does not fall through to `x-api-key`.

Authorization header:

```bash
curl https://api.paxalabs.com/v1/me \
  -H "Authorization: Bearer $PAXA_API_KEY"
```

x-api-key header:

```bash
curl https://api.paxalabs.com/v1/me \
  -H "x-api-key: $PAXA_API_KEY"
```

## Set a spending cap

A key can carry an optional credit limit. Set it at creation or edit it later in the dashboard. Once the key has spent that many credits, its requests answer [403 key_limit](https://paxalabs.com/docs/errors#key_limit) and nothing more is charged. Give each environment and each teammate its own capped key.

## Disable or delete a key

Disabling a key is reversible. Requests signed with it answer 401 until you enable it again. Deleting a key is permanent and takes effect immediately. Usage already recorded stays in your history.

> Keys are secrets. Call the API from your server and keep keys in environment variables. A key shipped in client-side code is public. If a key leaks, create a replacement and delete the leaked one.
