# Keys: what each one is, and who may handle it

Three different credentials get confused constantly. They are not
interchangeable.

| Credential | Header | Who holds it | May an agent handle it? |
|---|---|---|---|
| **Spendline API key** | `x-spendline-key` | The customer's account | Yes, a **scoped child key**, via the onboarding flow |
| **Provider API key** (OpenAI, Anthropic, …) | `Authorization` / `x-api-key` | The application, unchanged | It stays in the app's env. Never accept one into your context. |
| **Stored provider key** | n/a, encrypted at rest in Spendline | The customer, entered in the dashboard | **No. Human-only.** |

## The rule that breaks integrations

Never send the Spendline key as `x-api-key`.

Anthropic uses `x-api-key` for the Claude provider key. Put the Spendline key
there and it is forwarded to Anthropic, which rejects it, and you have leaked
your Spendline key to a third party. Always `x-spendline-key`.

## Root keys vs child keys

| | Root / owner key | Child key |
|---|---|---|
| Proxy traffic | yes | yes |
| Read spend, budgets, policies | yes | yes |
| Create/modify budgets, policies, reroutes | yes | **no**: HTTP 403 |
| Manage API keys, billing, team | yes | **no** |
| Close a month | yes | **no** |

The onboarding flow issues a **child key only**. An agent never receives the
account root key through any programmatic path. This is deliberate: a key is
standing access to a financial control plane.

If you need a governance change and hold only a child key, propose it, do not
try to escalate. See [onboarding](https://www.spendline.ai/agents/onboarding.md).

## Handling rules for agents

- Read the key from the environment (`SPENDLINE_API_KEY`). Write it to `.env`,
  never to source, never to a committed file, never into chat.
- Never place a key in a URL or query string. Spendline **rejects** requests whose
  query string names a credential, this is enforced, not advisory.
- Never log a key, including in a diagnostic block. Redact to `ac_…` + last 4.
- If a human pastes a provider key or Spendline key into your conversation, tell
  them to rotate it.

## Creating additional keys

```
POST /api/api-keys        # owner authority required
GET  /api/api-keys        # list keys you own
DELETE /api/api-keys/:id  # owner authority required
```

The raw key is returned **once** at creation and never again. A key cannot delete
itself.

## Storing provider keys in Spendline

Only needed for cross-provider rerouting. Human-only, in the dashboard, encrypted
at rest. Nine of the ten providers may carry a custom base URL; Anthropic may not.
