# Account and keys (/en/docs/referencia/cuenta)

Base: `https://api.facturia.cl/v1`. Every endpoint in this chapter authenticates with `Authorization: Bearer` unless stated otherwise, and the error envelope is the one in [Errors](/en/docs/errores).

| Method   | Path                                                    | What it does                                              |
| -------- | ------------------------------------------------------- | --------------------------------------------------------- |
| `GET`    | [`/account`](#get-account)                              | Retrieve the account and the key in use                   |
| `GET`    | [`/api_keys`](#get-api-keys)                            | List API keys (metadata only; secrets are never returned) |
| `POST`   | [`/api_keys`](#post-api-keys)                           | Mint an API key (root key only)                           |
| `DELETE` | [`/api_keys/{key_id}`](#delete-api-keys-key-id)         | Revoke an API key immediately (root key only)             |
| `POST`   | [`/api_keys/{key_id}/roll`](#post-api-keys-key-id-roll) | Issue a replacement secret for a key (root key only)      |

## `GET /account` [#get-account]

**Retrieve the account and the key in use**

The authenticated account and the credential in use — email, plan, empresas\_ready/total, and the calling key's own scopes, mode and allowlist.

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

**Responses**

| Code      | Meaning                                                                                                                                                                                                                                                                                                 | Body          |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `200`     | The account.                                                                                                                                                                                                                                                                                            | Account       |
| `400`     | `empresa_header_forbidden` — this operation is account-level; a `Facturia-Empresa` header on it is refused rather than silently ignored.                                                                                                                                                                | ErrorResponse |
| `401`     | Missing, malformed or revoked key.                                                                                                                                                                                                                                                                      | ErrorResponse |
| `429`     | Too many requests.                                                                                                                                                                                                                                                                                      | ErrorResponse |
| `default` | An error not otherwise enumerated for this operation, in the same §5.5 envelope as every other refusal. Branch on `error.code`, never on the HTTP status alone or on `error.message` — a code this operation has not been seen to throw yet is still safer to route on than a string meant for a human. | ErrorResponse |

## `GET /api_keys` [#get-api-keys]

**List API keys (metadata only; secrets are never returned)**

A root key sees every key on the account. An ordinary key sees only itself.

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

**Parameters**

| Parameter | In    | Required | Type    | Notes                                                   |
| --------- | ----- | -------- | ------- | ------------------------------------------------------- |
| `limit`   | query | —        | integer |                                                         |
| `cursor`  | query | —        | string  | Opaque cursor from a previous response's `next_cursor`. |

**Responses**

| Code      | Meaning                                                                                                                                                                                                                                                                                                 | Body            |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- |
| `200`     | A list of API keys.                                                                                                                                                                                                                                                                                     | lista de ApiKey |
| `401`     | Missing, malformed or revoked key.                                                                                                                                                                                                                                                                      | ErrorResponse   |
| `429`     | Too many requests.                                                                                                                                                                                                                                                                                      | ErrorResponse   |
| `default` | An error not otherwise enumerated for this operation, in the same §5.5 envelope as every other refusal. Branch on `error.code`, never on the HTTP status alone or on `error.message` — a code this operation has not been seen to throw yet is still safer to route on than a string meant for a human. | ErrorResponse   |

## `POST /api_keys` [#post-api-keys]

**Mint an API key (root key only)**

Requires a root key (`sk_live_root_…` / `sk_test_root_…`) carrying `keys:write`.
Guardrails, enforced server-side: the new key's `empresas` must be a subset of the
minter's allowlist and its `scopes` a subset of the minter's scopes (violations return
`403 privilege_escalation`); mode is inherited from the minter; root keys cannot mint
root keys. The `secret` is returned exactly once.

```bash
curl -sS -X POST https://api.facturia.cl/v1/api_keys \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"name":"cliente — Comercial Andina","scopes":["documents:read","documents:write"]}'
```

**Parameters**

| Parameter         | In     | Required | Type   | Notes                                                                                                                                                                                                                         |
| ----------------- | ------ | -------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Idempotency-Key` | header | —        | string | Client-generated key, unique per logical operation, retained 24h and scoped to (account, empresa, endpoint). Replays return the original response with `Facturia-Idempotent-Replay: true`. Same key + different body → `409`. |

**Body**

| Field         | Type                                                                                                                                                                                                                                                                                                             | Required | Notes                                                                          |
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------ |
| `name`        | string                                                                                                                                                                                                                                                                                                           | yes      |                                                                                |
| `mode`        | `live` · `test`                                                                                                                                                                                                                                                                                                  | —        |                                                                                |
| `scopes`      | `documents:read` · `documents:write` · `received:read` · `received:write` · `empresas:read` · `empresas:write` · `folios:write` · `tax:read` · `tax:write` · `webhooks:read` · `webhooks:write` · `usage:read` · `keys:write` · `mandato:write` · `mandato:attest` · `onboarding:write` · `onboarding:attest`\[] | yes      |                                                                                |
| `empresas`    | Rut\[]                                                                                                                                                                                                                                                                                                           | —        | Subset of the minting key's allowlist. A single RUT makes it an empresa token. |
| **Responses** |                                                                                                                                                                                                                                                                                                                  |          |                                                                                |

| Code      | Meaning                                                                                                                                                                                                                                                                                                 | Body             |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
| `201`     | The minted key, including its secret.                                                                                                                                                                                                                                                                   | ApiKeyWithSecret |
| `400`     | Malformed or missing input.                                                                                                                                                                                                                                                                             | ErrorResponse    |
| `401`     | Missing, malformed or revoked key.                                                                                                                                                                                                                                                                      | ErrorResponse    |
| `403`     | Valid key, not permitted — scope, empresa allowlist, or mode.                                                                                                                                                                                                                                           | ErrorResponse    |
| `429`     | Too many requests.                                                                                                                                                                                                                                                                                      | ErrorResponse    |
| `default` | An error not otherwise enumerated for this operation, in the same §5.5 envelope as every other refusal. Branch on `error.code`, never on the HTTP status alone or on `error.message` — a code this operation has not been seen to throw yet is still safer to route on than a string meant for a human. | ErrorResponse    |

## `DELETE /api_keys/{key_id}` [#delete-api-keys-key-id]

**Revoke an API key immediately (root key only)**

Revoke a key immediately and irreversibly. Requires a root key or an account session (`403 root_key_required`) — an ordinary key cannot revoke keys, itself included.

```bash
curl -sS -X DELETE https://api.facturia.cl/v1/api_keys/key_01K2QWB7T4N9 \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parameters**

| Parameter | In   | Required | Type   | Notes |
| --------- | ---- | -------- | ------ | ----- |
| `key_id`  | path | yes      | string |       |

**Responses**

| Code      | Meaning                                                                                                                                                                                                                                                                                                 | Body          |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `204`     | Revoked. Revocation is immediate and unrecoverable.                                                                                                                                                                                                                                                     | —             |
| `401`     | Missing, malformed or revoked key.                                                                                                                                                                                                                                                                      | ErrorResponse |
| `403`     | Valid key, not permitted — scope, empresa allowlist, or mode.                                                                                                                                                                                                                                           | ErrorResponse |
| `404`     | No such object under this key.                                                                                                                                                                                                                                                                          | ErrorResponse |
| `429`     | Too many requests.                                                                                                                                                                                                                                                                                      | ErrorResponse |
| `default` | An error not otherwise enumerated for this operation, in the same §5.5 envelope as every other refusal. Branch on `error.code`, never on the HTTP status alone or on `error.message` — a code this operation has not been seen to throw yet is still safer to route on than a string meant for a human. | ErrorResponse |

## `POST /api_keys/{key_id}/roll` [#post-api-keys-key-id-roll]

**Issue a replacement secret for a key (root key only)**

The previous secret keeps working for 24 hours so you can deploy without downtime.

The roll is a compare-and-swap on the key's current hash, so two rolls of the
same key can never both land: exactly one wins and the loser answers
`409 api_key_roll_conflict`, whose secret is the live one. Roll once per key.

```bash
curl -sS -X POST https://api.facturia.cl/v1/api_keys/key_01K2QWB7T4N9/roll \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parameters**

| Parameter | In   | Required | Type   | Notes |
| --------- | ---- | -------- | ------ | ----- |
| `key_id`  | path | yes      | string |       |

**Responses**

| Code      | Meaning                                                                                                                                                                                                                                                                                                 | Body             |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
| `200`     | The key with its new secret.                                                                                                                                                                                                                                                                            | ApiKeyWithSecret |
| `401`     | Missing, malformed or revoked key.                                                                                                                                                                                                                                                                      | ErrorResponse    |
| `403`     | Valid key, not permitted — scope, empresa allowlist, or mode.                                                                                                                                                                                                                                           | ErrorResponse    |
| `409`     | State conflict — idempotency reuse, duplicate external\_id, artifact not ready.                                                                                                                                                                                                                         | ErrorResponse    |
| `429`     | Too many requests.                                                                                                                                                                                                                                                                                      | ErrorResponse    |
| `default` | An error not otherwise enumerated for this operation, in the same §5.5 envelope as every other refusal. Branch on `error.code`, never on the HTTP status alone or on `error.message` — a code this operation has not been seen to throw yet is still safer to route on than a string meant for a human. | ErrorResponse    |
