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

# Authentication

The Reflecto API authenticates every request with an opaque bearer token.

## Token format

```
rfk_live_aB3xQ7mN9pK2vR5tY8uW4sZ1cE6dF0gH
└──┬──┘└──────────────────┬─────────────────┘
prefix      32 URL-safe alphanumeric chars
```

| Prefix      | Purpose                                  |
| ----------- | ---------------------------------------- |
| `rfk_live_` | Live sender token. Used with `/v1/send`. |
| `rfk_test_` | Sandbox / dry-run sender token (V1).     |
| `rfd_live_` | Receiver token for SSE streaming (V1).   |

<Note>
  Only `rfk_live_` ships in MVP. `rfk_test_` (sandbox sender) and
  `rfd_live_` (SSE receiver) are V1 — listed here so the Secret Scanning
  regex and forward-compat tokens are documented up front, but you cannot
  generate either today.
</Note>

The 32-character suffix provides ≥160 bits of entropy from the URL-safe
alphabet `[A-Za-z0-9]`. The prefix is recognizable by the GitHub Secret
Scanning regex `rf[kd]_(live|test)_[A-Za-z0-9]{32}` so leaked sender (`rfk_`)
and V1 receiver (`rfd_`) tokens both get flagged automatically.

## Where tokens come from

Tokens are created and managed on your **paired Android device**, not via the
public API. On first install, Reflecto generates a token labeled **Default**
and stores it on every paired device. You can create additional labeled
tokens (e.g. "GitHub Actions", "Pi-hole") from the Android app's
**API Tokens** screen. The Chrome extension can view existing tokens
read-only in MVP; full management UI lands in V1.

Token plaintext is shown **once** at creation. After that, the Android app
gates re-reveal behind `BiometricPrompt`. The server stores only a SHA-256
hash.

## Sending requests

The canonical form is the standard `Authorization` header:

```bash theme={null}
curl -H "Authorization: Bearer rfk_live_…" \
     -d "Hello world" \
     https://api.reflecto.dev/v1/send
```

A capability-URL alias is also available for environments that can't set
custom headers:

```
POST https://api.reflecto.dev/v1/send/rfk_live_aB3x…
```

Use the header form whenever you can. Path-tokens leak more easily — referrer
headers, shell history, screenshots. The server redacts the URL before
writing access logs, but client-side leaks are out of our reach.

## Rotating and revoking

From the Android app's **API Tokens** screen you can:

* **Create new** — generates a fresh token with a label and optional scope.
* **Revoke** — instantly invalidates the token. Subsequent requests return
  `401 invalid_token`. After 30 days the audit row is GC'd.
* **Rotate** — create a new token, update your integrations to use it, then
  revoke the old one. There is no in-place rotation flow; this two-step
  pattern keeps the revocation boundary unambiguous.

Token mutations are pushed to every paired device via an encrypted
`type=token_update` message, so the list stays in sync across surfaces.

## Failure modes

These are the authentication-layer rejections — checks that run before the
request body is parsed. Both return the flat `{ error: "..." }` shape (see
[Errors](/guides/errors) for the full response shape note).

| Status | `error` code    | Meaning                                    |
| ------ | --------------- | ------------------------------------------ |
| 401    | `missing_token` | No `Authorization: Bearer …` header sent.  |
| 401    | `invalid_token` | Token format invalid, unknown, or revoked. |

`403 priority_capped` is also a token-scope outcome but fires *after* token
validation succeeds, so it's a scope/authorization concern rather than
authentication. See [Errors → Scope (403)](/guides/errors) for the full
behavior and remediation.
