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

# Authentication

> How to authenticate with the Teel API

The Teel API uses a **secret API key** sent as a bearer token on every request. Same pattern as Stripe, OpenAI, Anthropic, Resend. Your server holds the key in env vars or a vault and presents it on every call.

```bash theme={null}
curl https://api.teel.finance/recipients \
  -H "Authorization: Bearer sk_live_a3f2x9k7m4q8…"
```

## Key format

```
sk_<env>_<43 url-safe base64 chars>
```

| Prefix     | Environment | Base URL                           |
| ---------- | ----------- | ---------------------------------- |
| `sk_live_` | Production  | `https://api.teel.finance`         |
| `sk_test_` | Sandbox     | `https://api-sandbox.teel.finance` |

<Note>
  Sandbox provider APIs don't move real funds — use `sk_test_…` keys against `api-sandbox.teel.finance` for end-to-end integration testing before switching to production credentials.
</Note>

The fixed `sk_` prefix is recognized by GitHub secret scanning, GitGuardian, and TruffleHog — if you accidentally commit a key, you'll get a leak notification. The visible `live` vs `test` distinction prevents the "prod creds in Slack" failure mode.

<Warning>
  Use each key only against its matching host. A key sent to the wrong environment is rejected with `403` and the body `{"error": "environment_scope mismatch"}` — `sk_live_…` belongs on `api.teel.finance`, `sk_test_…` on `api-sandbox.teel.finance`.
</Warning>

## Issuing a key

API keys are issued by the Teel onboarding team. Email **[support@teel.finance](mailto:support@teel.finance)** (or your dedicated onboarding contact) to request:

* A new `sk_test_…` sandbox key
* A new `sk_live_…` production key (after KYB approval)
* Additional keys for separate use cases (e.g. one per service)
* A scope change on an existing key

The plaintext key is delivered through an encrypted channel and shown **exactly once** — Teel stores only an argon2id hash plus the first 12 characters for identification. We cannot retrieve the plaintext later, so save it to your secret manager immediately.

Self-service key creation from the dashboard is on the roadmap.

## Scopes

Each key carries a subset of scopes. Default for a newly-minted key is read-only:

| Scope              | What it allows                                    |
| ------------------ | ------------------------------------------------- |
| `quotes:read`      | Fetch quotes (`/quotes/*`)                        |
| `payouts:write`    | Execute payouts (`POST /rfq/execute`)             |
| `payouts:read`     | List / fetch your own payouts                     |
| `recipients:write` | Create / update / delete recipients               |
| `recipients:read`  | List / fetch recipients                           |
| `webhooks:write`   | Create / update / delete webhook subscriptions    |
| `webhooks:read`    | List / fetch webhook subscriptions and deliveries |

Webhook subscriptions are managed entirely through the API with the `webhooks:read` / `webhooks:write` scopes — see the [Webhooks guide](/guides/webhooks).

## Rotation

To roll a key, contact **[support@teel.finance](mailto:support@teel.finance)**. We issue a new key alongside the existing one and keep the previous key working for **7 days** to give you time to redeploy. After the overlap window, the old key returns `401`.

Rotations are logged to the partner-visible audit feed under the same business.

## Revocation

If you suspect compromise, contact **[support@teel.finance](mailto:support@teel.finance)** to revoke the key immediately. Active in-memory caches drain within 30 seconds; after that, every request with the revoked key returns `401`. Use revocation rather than rotation during incident response — rotation has a 7-day overlap window you don't want when responding to a leak.

## What happens if a key is compromised

1. **Blast radius is bounded by the key's scopes** — a key with `quotes:read` only cannot create payouts. Issue narrowly-scoped keys per use case so a leaked CI key can't act as a leaked production key.
2. **Teel only custodies funds via escrow + smart wallets.** A captured key cannot drain a wallet — it can only place actions the holder of the key could place anyway, all of which are audited and rate-limited.
3. **Revoke first, investigate second.** Rotation's 7-day overlap is wrong for an active compromise; revoke + mint a new key + redeploy.

## Storage

* **Server-side only.** Never embed a `sk_live_…` key in a mobile app, browser bundle, or any artifact a partner of yours can read. Use a backend you control.
* **One secret per environment.** Mirror the key into your env-vars / vault under names like `TEEL_API_KEY`. Don't share a key across staging and production.
* **CI secret scanning.** Configure your CI to fail on `sk_live_` / `sk_test_` substrings in commits. Most CI providers have built-in detectors for this prefix shape.

## Error responses

| Status                  | Meaning                                                                                                                                                                       |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `401 Unauthorized`      | Missing / malformed `Authorization` header, or the key is unknown / revoked                                                                                                   |
| `403 Forbidden`         | Key is valid but lacks the scope the endpoint requires (e.g. you called `POST /rfq/execute` with a `quotes:read`-only key), or the key was sent to the wrong environment host |
| `429 Too Many Requests` | Per-key rate limit exceeded — back off per the `Retry-After` header                                                                                                           |

## Rate limiting

Per-key rate limits apply. Each response carries:

```http theme={null}
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1700001234
```

On a `429`, also: `Retry-After: <seconds>`. Wait at least that long before the next request.

Specific limits per endpoint family + the per-key default are documented in the [Errors & retries](/errors) guide.

## Dashboard authentication

The Teel dashboard is a separate, browser-only session and is **not** the API authentication path. Partner integrations should always use the `sk_` API key pattern above — dashboard sessions are not accepted on `api.teel.finance` or `api-sandbox.teel.finance`.

If you build an internal tool that needs to act on behalf of multiple Teel accounts, request one `sk_` key per account rather than reusing your own dashboard session.
