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

# API keys

> Every /v1 request authenticates with an API key: Authorization: Bearer sk_test_... (test) or

Every `/v1` request authenticates with an API key: `Authorization: Bearer sk_test_...` (test) or
`sk_live_...` (live). The key's mode scopes all data — a test key never sees live resources, and
vice-versa. Bootstrap your first pair with `POST /v1/organizations` (dev only), then mint and
rotate keys through `/v1/api_keys`.

These routes are **platform-scoped**: the `Invoice-Account` header is not honored here (sending it
returns 400 `connect.not_supported_here`). You manage keys with your own key, never on behalf of a
connected account.

## Create a key

The plaintext key is returned **once**, at creation. Store it immediately — it is never shown
again (only a `prefix` for identification). `mode` is independent of the calling key, so a test
key can mint a live key.

```bash theme={null}
curl -sX POST $BASE/v1/api_keys \
  -H "authorization: Bearer $KEY" -H 'content-type: application/json' \
  -d '{ "name": "server-side worker", "mode": "live" }'
```

```json theme={null}
{
  "object": "api_key",
  "id": "key_...",
  "name": "server-side worker",
  "mode": "live",
  "prefix": "sk_live_ab12",
  "key": "sk_live_...",      // the full secret — shown ONLY here
  "created_at": "2026-07-10T18:25:43Z",
  "revoked_at": null,
  "version": null
}
```

## List, rename, pin a version

```bash theme={null}
curl -s $BASE/v1/api_keys -H "authorization: Bearer $KEY"          # both modes; no secrets
curl -sX PATCH $BASE/v1/api_keys/key_123 -H "authorization: Bearer $KEY" \
  -H 'content-type: application/json' -d '{ "name": "renamed" }'
```

`PATCH` accepts `name` and/or `version`. A `version` is validated against the supported API-version
registry (an unknown value returns 400 `request.invalid_version`); a pinned version applies to
requests made with that key unless overridden by the `Invoice-Version` header. The list endpoint
paginates with `starting_after` / `ending_before`.

## Rotate and revoke

To rotate: create a replacement key, deploy it, then revoke the old one.

```bash theme={null}
curl -sX DELETE $BASE/v1/api_keys/key_old -H "authorization: Bearer $KEY"
```

Revocation is a soft delete (sets `revoked_at`). A revoked key fails auth immediately with
**401 `auth.key_revoked`** — there is no grace period. If you revoke the **last active key of a
mode**, the response includes a `warning` so you don't lock yourself out.

## Security notes

* Keys are stored only as a hash; the API can never show you an existing key's secret.
* Treat `sk_live_` keys as production secrets. Use separate keys per service so you can revoke one
  without disrupting the others.
* Every response carries a `Request-Id`; log it alongside key activity for auditing.
