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

# Authentication

> Send a scoped API key as a Bearer token.

Send your API key in the `Authorization` header on every request:

```bash theme={null}
curl https://invoice.horizonpay.co/api/v1/invoices \
  -H "Authorization: Bearer $INVOICE_AI_API_KEY"
```

The SDKs and the CLI read the key from the `INVOICE_AI_API_KEY` environment variable. Only `GET /openapi.json` works without a key.

## Create a key

Create keys in [Settings → API keys](https://invoice.horizonpay.co/settings/api-keys). Give the key a name, choose its scopes and, optionally, an expiry in days (`0` never expires).

Keys look like `inv_live_ab12cd34_7Kf9QmXz2pR4vNt6LwYb8HsJ3dGc5eAu`. The full key is shown once. If you lose it, revoke it and create a new one.

<Note>
  There's no test mode. Every key works on your real account. To try things out, create a customer with an email address you control.
</Note>

You can't create, list or revoke keys through the API.

## Scopes

A request without the endpoint's scope fails with `403 forbidden`, and `detail` names the missing scope.

| Scope | Allows |
| - | - |
| `business:read` | `GET /business` |
| `clients:read` | List and read customers |
| `clients:write` | Create, update and archive customers |
| `products:read` | List and read products and prices |
| `products:write` | Create, update and archive products and prices |
| `invoices:read` | List and read invoices, PDFs, events and invoice items |
| `invoices:write` | Create, edit and delete **draft** invoices and their lines |
| `invoices:finalize` | Finalize and void invoices |
| `invoices:send` | Email invoices. Also finalizes a draft before sending it. |
| `payments:write` | Mark invoices paid |
| `webhooks:manage` | List, create and delete webhook endpoints |

Presets in Settings:

* **Read only:** `business:read`, `clients:read`, `invoices:read`.
* **Raise and send invoices:** Read only, plus `clients:write`, `invoices:write`, `invoices:finalize`, `invoices:send` and `payments:write`.

Give each integration only the scopes it needs.

## Errors

A missing, malformed, unknown, revoked or expired key returns `401 unauthorized`. The `detail` says which, for example `This API key has been revoked.` See [Errors](/errors).

## Rotate a key

1. Create a new key with the same scopes.
2. Deploy it everywhere the old key is used.
3. Check the old key's **last used** time in Settings, then revoke it. Revocation takes effect on the next request.

<Warning>
  Keep keys on your server. Never put one in browser code, a mobile app, a public repository or a URL. If a key leaks, revoke it in Settings right away.
</Warning>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.