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

# Authentication

> How your backend authenticates to the Recurr API — secret API keys, live vs test, scopes, and rotation.

<Warning>
  **🚧 Under development.** The authentication model below is the committed
  contract; the API and key-management dashboard are being built. This page is
  for planning your integration, not yet for live calls.
</Warning>

The Recurr REST API authenticates with a **secret API key**, sent as a Bearer
token on every request:

```bash theme={null}
curl https://api.recurr.dev/v1/subscribers \
  -H "Authorization: Bearer rk_live_xxxxxxxxxxxxxxxxxxxxxxxx"
```

This is distinct from **webhook** authentication: Recurr *signs* the events it
sends you, and you verify the signature — see
[Overview → Authentication](/api-reference/overview#authentication). API keys are
for the calls **you make to us**; signatures are for the calls **we make to you**.

## Live vs test keys

Every key is **environment-scoped**, and the prefix tells you which:

| Prefix      | Operates on                                              | Use for                                 |
| ----------- | -------------------------------------------------------- | --------------------------------------- |
| `rk_live_…` | your **live** data — real subscribers, real charges      | production                              |
| `rk_test_…` | isolated **test** data — no real charges, no real emails | development + the docs "Try it" console |

Same base URL, same endpoints — the **key** decides the environment. There is no
separate sandbox hostname. See [Test mode](/api-reference/test-mode) for how test
data is isolated.

<Note>
  A `rk_test_` key can never touch live data, and a `rk_live_` key never touches
  test data. Keep them straight in your config (e.g. `RECURR_API_KEY` per
  environment).
</Note>

## Getting + managing keys

Keys are created in your dashboard under **Settings → API keys** by a user with
the `developer` (or `admin`) role. When you create a key:

* The **secret** is shown **once** — store it immediately in your secrets
  manager. Recurr stores only a hash; we can't show it again.
* Each key carries a **scope** (read-only vs read-write) so you can issue a
  least-privilege key per integration.
* Keys are listed by prefix + last-four + creation date for identification.

## Rotation + revocation

* **Rotate** by creating a new key, deploying it, then revoking the old one —
  both work during the overlap, so there's no downtime.
* **Revoke** immediately if a key is exposed; revocation takes effect at once.
* Keys auto-revoke when the issuing member is removed or the account is
  offboarded.

## Keeping keys safe

<Warning>
  Secret keys are **server-side only**. Never embed a `rk_live_` key in an app
  binary, mobile client, browser JavaScript, or a public repo — anyone with the
  key can act as your backend. The "no app changes" integration model means your
  keys live in *your* server, not the app.
</Warning>

* Store keys in a secrets manager, not source control.
* Use a separate key per environment + per integration.
* Prefer a **read-only** key for anything that only reads.
* Rotate on a schedule and after any suspected exposure.

## Errors

A missing, malformed, revoked, or wrong-environment key returns `401`:

```json theme={null}
{ "error": { "type": "unauthorized", "message": "Invalid or missing API key." } }
```

See [Errors](/api-reference/overview#error-handling) for the full envelope.
