# API keys (/en/docs/autenticacion)

Authentication is a single bearer token.

```bash
curl https://api.facturia.cl/v1/documents \
  -H "Authorization: Bearer sk_live_9lQpV3fA2mKcRt7wZxYb1Nde"
```

| Prefix     | Mode                                 | Talks to the SII (Chile's tax authority)?                                                  | Cost                                                                                    |
| ---------- | ------------------------------------ | ------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------- |
| `sk_test_` | **test** — a fully simulated sandbox | Never                                                                                      | Free forever                                                                            |
| `sk_live_` | **live** — real emission             | Yes (SII certification or production, depending on the empresa — the company you emit for) | The single plan: $19.990 CLP + IVA (VAT) per month **per empresa**, unlimited documents |

Keys are account-scoped, shown once, stored hashed, and revoked one at a time. Create them in the
dashboard or through the API.

A key carries three things:

* a **mode** (`test` / `live`) — immutable, encoded in the prefix;
* a **set of scopes** — see [Scopes](/en/docs/autenticacion/scopes);
* an **empresa allowlist** — `["*"]` (every empresa in the account, including ones created later) or
  an explicit list of RUT, Chile's taxpayer id numbers.

> **Trap — There is no publishable key in v1**
>
> The API is server to server. Never put a secret key in a browser, a mobile app, or the prompt of an
> agent a third party can read. If a key leaks, revoke it: revocation is immediate and irreversible.
>
> To hand an artifact to someone who has no key — the recipient, their accountant, a WhatsApp thread —
> there are [public links](/en/docs/emision/artefactos#enlaces-publicos): signed, unguessable,
> expiring and revocable, and they cannot be escalated into an API credential.

## Who am I [#who-am-i]

```bash
curl https://api.facturia.cl/v1/account \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

```json
{
  "object": "account",
  "id": "acct_01K2QW8V6ZR3T5NM",
  "name": "Connect Core",
  "key": {
    "id": "key_01K2QWA3F2",
    "name": "production-backend",
    "mode": "live",
    "last4": "1Nde",
    "scopes": ["documents:read", "documents:write", "tax:read"],
    "empresas": ["77928532-4", "78281439-7"],
    "created_at": "2026-08-01T17:22:04Z",
    "last_used_at": "2026-08-14T13:04:10Z"
  },
  "limits": { "requests_per_minute": 300, "emissions_per_second": 10 }
}
```

This is the cheap call for a health check: it tells you which key you are using, with which scopes,
over which empresas, and under which limits.

## Empresa token [#empresa-token]

A key whose allowlist holds exactly one empresa is an **empresa token**: the `Facturia-Empresa`
header becomes optional, and if you do send it, it has to match or you get
`400 empresa_mismatch`.

This is the recommended shape when you integrate a single company, or when you hand a key to a
customer's system: the key cannot address anything but that RUT.

## Email verification [#email-verification]

Signing up does not require proving your address, and neither does logging in, reading anything, or
using the whole product in **test mode**. Verification blocks exactly one thing: creating a **live**
credential.

```bash
# Confirmar — el token viene del enlace del correo. No necesita sesión:
# quien hace clic tiene un enlace, posiblemente en otro dispositivo.
curl -sS https://api.facturia.cl/account/verify \
  -H "Content-Type: application/json" -d '{"token":"..."}'

# Reenviar — este sí necesita la sesión, para que no nos puedan usar para mandarle correo a nadie.
curl -sS -X POST https://api.facturia.cl/account/verification/resend \
  -H "Authorization: Bearer $TOKEN"
```

The link is single-use, lives 24 hours, and is bound to the address it was sent to: if the account's
email changes in the meantime, the token is rejected rather than confirming an address it was never
delivered to. Clicking twice is a success, not an error. Resends are rate limited and answer `429`
with `Retry-After`.

Minting an `sk_live_` key from an unverified account returns
`403 email_verification_required`.

- [Scopes and empresas](/en/docs/autenticacion/scopes): What each scope grants and how it combines with the allowlist.

- [Root keys and rotation](/en/docs/autenticacion/llaves-root): Mint one key per customer without a human opening a dashboard.

- [Rate limits](/en/docs/autenticacion/limites): The published buckets and the headers that tell you where you are.
