# Autenticación

> API keys de Simplo (sk_simplo_ y sk_simplo_sandbox_), scopes, el header X-Api-Key, creación, revocación e higiene de credenciales.

## API keys (recomendado)

Simplo autentica con API keys **por empresa**. Una key se muestra **una sola
vez** al crearla — guárdala en un gestor de secretos (Simplo solo conserva su
hash SHA-256 y un prefijo de 8 caracteres para mostrar).

Cada key fija dos cosas además de la empresa:

- **El ambiente** — el modelo de Stripe: `sk_simplo_sandbox_...` opera el
  [sandbox](/comienza/quickstart/) de tu empresa (self-serve, incluido en
  cualquier plan con Facturación); `sk_simplo_...` (sin `_sandbox_`) opera
  producción (se habilita por empresa — ver
  [Pasar a producción](/comienza/pasar-a-produccion/)). Mismo endpoint,
  mismo contrato: la key decide el ambiente.
- **El scope** — qué superficie alcanza:

| Scope | Qué permite |
| --- | --- |
| `billing:dte` | Emitir y consultar DTEs vía la API REST de facturación — exactamente las cinco rutas de la [tabla del quickstart](/comienza/quickstart/#qué-puede-hacer-tu-api-key) (`POST`/`GET /billing/dte`, detalle, PDF, XML). El resto de `/api/v1/billing/*` es solo-sesión y responde `403 BILLING_API_KEY_ROUTE_NOT_ALLOWED`. |
| `agent:read` | Lectura de datos vía el [MCP](/agentes/conecta-tu-agente/) y los tools de agente. Es el scope por defecto de una key nueva. **No** sirve para emitir. |

Una key `billing:dte` **no** es de solo lectura — emite documentos
tributarios. Y no es intercambiable con `agent:read`: el MCP responde `401`
a una key `billing:dte`, y la fachada de facturación no acepta `agent:read`.

La key viaja en el header `X-Api-Key`. Con el SDK (aún no publicado en npm):

```ts
import Simplo from '@simplohq/sdk';

const simplo = new Simplo({ apiKey: process.env.SIMPLO_API_KEY });
```

Si omites `apiKey`, el cliente lee la variable de entorno `SIMPLO_API_KEY` y
lanza un error de inmediato (no en la primera request) si no existe ninguna.

**La credencial es la empresa.** Una API key está ligada a exactamente una
empresa: cada llamada queda acotada a ella y ningún parámetro puede ampliar
ese alcance. Para operar varias empresas, ver
[Multi-empresa](/comienza/multi-empresa/).

## Crear, listar y revocar keys

Puedes gestionar tus keys desde **Desarrolladores** en tu cuenta de Simplo
(solo dueño o administrador de la empresa), o por API autenticándote con tu
JWT de sesión. `environment` elige el ambiente (`"sandbox"` o `"live"`; si
lo omites, es `"live"`) y `scopes` la superficie:

```bash
curl -sS -X POST https://api.simplo.cl/api/v1/api-keys \
  -H "Authorization: Bearer $SIMPLO_JWT" \
  -H "Content-Type: application/json" \
  -d '{"name": "Backend de facturación", "environment": "sandbox", "scopes": ["billing:dte"]}'
```

La respuesta `201 Created` incluye el campo `key` **esta única vez** — no se
puede recuperar después:

```json
{
  "id": "a1b2c3d4-...",
  "name": "Backend de facturación",
  "prefix": "sk_simpl",
  "is_sandbox": true,
  "revoked": false,
  "created_at": "2026-06-13T12:00:00Z",
  "key": "sk_simplo_sandbox_3f9a...e1"
}
```

Al crear una key sandbox, tu empresa necesita su identidad completa: sin RUT
real el mint responde `422 COMPANY_RUT_REQUIRED_FOR_SANDBOX` (y sin razón
social, `422 COMPANY_RAZON_SOCIAL_REQUIRED_FOR_SANDBOX`) — complétala en la
app y reintenta.

Para listar o revocar:

```bash
curl -sS https://api.simplo.cl/api/v1/api-keys \
  -H "Authorization: Bearer $SIMPLO_JWT"

curl -sS -X DELETE https://api.simplo.cl/api/v1/api-keys/$KEY_ID \
  -H "Authorization: Bearer $SIMPLO_JWT"
```

El listado **nunca** devuelve el valor completo de la key, solo su metadata
(`prefix`, `scopes`, `last_used_at`, `revoked`). Revocar es idempotente y
tiene efecto inmediato.

## Higiene de keys

- Nunca envíes una API key a un navegador o app móvil. Llama a Simplo desde tu
  backend.
- Nunca la commitees. Usa variables de entorno o un gestor de secretos.
- Rota creando una key nueva, desplegándola y revocando la antigua. La
  revocación es inmediata.

## Bearer tokens (avanzado)

Si ya tienes un JWT emitido por Simplo (por ejemplo dentro de una integración
que autentica usuarios contra Simplo), puedes pasarlo en lugar de una API key.
Se envía como `Authorization: Bearer <token>`:

```ts
const simplo = new Simplo({ token: sessionJwt });
```

Prefiere API keys para integraciones server-to-server: no expiran con el
calendario de una sesión y son revocables individualmente.

## Modos de falla

| Status | Clase de error        | Significado                                                     |
| ------ | --------------------- | --------------------------------------------------------------- |
| 401    | `AuthenticationError` | Credencial ausente, malformada, revocada, expirada o desconocida — o una key `billing:dte` contra el MCP. |
| 403    | `PermissionError`     | Credencial válida, pero sin permiso para esta acción. Con una API key en `/billing/*`, el código `BILLING_API_KEY_ROUTE_NOT_ALLOWED` significa que la ruta es solo-sesión — no es un problema de tu cuenta. |

La API intencionalmente no distingue *por qué* ocurrió un 401
(anti-enumeración). Revisa el nombre del header (`X-Api-Key`), el prefijo de
la key (`sk_simplo_`) y que no esté revocada.

> **Manda siempre un `User-Agent` propio:**
> Si recibes un **`403` cuyo cuerpo NO es JSON** y dice `error code: 1010`, no
> es tu key: es nuestro CDN bloqueando la petición **antes** de que llegue a la
> API, por la firma del cliente HTTP.
>
> Medido el 2026-09-04: el `User-Agent` por defecto de `urllib` de Python
> (`Python-urllib/3.x`) se bloquea. `requests`, `curl`, Go, Node, Java y axios
> pasan sin problema, igual que el ejemplo Python de esta documentación (usa
> `http.client`, que no manda `User-Agent`).
>
> Identifica tu integración y te ahorras la clase entera de problema:
>
> ```
> User-Agent: mi-erp/1.2 (integración Simplo)
> ```
>
> Es buena práctica de todas formas: cuando nos escribas por un problema,
> podemos encontrar tus requests por ese nombre.

Ver [Errores](/referencia/errores/) para el manejo completo.

---

Versión HTML: https://docs.simplo.cl/comienza/autenticacion/ · Índice para agentes: https://docs.simplo.cl/llms.txt
