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

# Autenticación

> Modelo de 4 credenciales — sk, pk, wt, et.

Rail usa **4 tipos de credenciales**. Cada uno tiene un scope y lifetime distinto. Si mezclás (mandás un `sk` donde se espera `pk`, o viceversa), la API responde `403`.

## 1. Secret key — `rail_sk_{live|test}_…`

Server-to-server. Es la única credencial que puede leer cuentas y movimientos.

| Atributo       | Valor                                                                                   |
| -------------- | --------------------------------------------------------------------------------------- |
| Uso            | Backend ↔ Rail API                                                                      |
| Lifetime       | Permanente (hasta revocar)                                                              |
| Header         | `Authorization: Bearer rail_sk_live_…`                                                  |
| Scope          | `links:read`, `links:write`, `accounts:read`, `movements:read`, `refresh_intents:write` |
| Almacenamiento | Env del backend (`RAIL_API_KEY`). **Nunca en frontend.**                                |

## 2. Publishable key — `rail_pk_{live|test}_…`

Browser-safe. La usa el widget para autenticarse al pedir su `widget_token`.

| Atributo       | Valor                                                       |
| -------------- | ----------------------------------------------------------- |
| Uso            | Frontend (widget)                                           |
| Lifetime       | Permanente                                                  |
| Header         | `Authorization: Bearer rail_pk_live_…`                      |
| Scope          | Solo `widget_tokens:write`                                  |
| Almacenamiento | Env del frontend (`NEXT_PUBLIC_RAIL_KEY` / `VITE_RAIL_KEY`) |

<Note>
  Exponerla es seguro: el único endpoint que la acepta es `POST /v1/widget_tokens`, y el `wt_*` resultante es single-use y efímero. Un atacante con tu `pk_` puede emitir tokens infinitos pero no leer data del banco.
</Note>

## 3. Widget token — `wt_{8hex}_sec_…`

Abre el widget de Rail Connect. Single-use.

| Atributo | Valor                                        |
| -------- | -------------------------------------------- |
| Uso      | Inicializar el widget en el frontend         |
| Lifetime | 10 minutos                                   |
| Emisión  | `POST /v1/widget_tokens` (con `sk_` o `pk_`) |
| Consumo  | El widget lo marca `consumed_at` al abrirse  |

Para **refresh con MFA async**, Rail emite automáticamente un token `ri_{intentId}_sec_…` dentro del `refresh_intent.requires_mfa.widget_token`. El widget lo recibe y lo trata igual que un `wt_*`.

## 4. Exchange token — `et_…`

One-shot. El widget lo devuelve al frontend al terminar el connect exitoso. Tu backend lo canjea por el `link_id` real.

| Atributo | Valor                                            |
| -------- | ------------------------------------------------ |
| Uso      | Bridge widget → backend del cliente              |
| Lifetime | 5 minutos                                        |
| Emisión  | Auto (lo emite Rail al cerrar el widget)         |
| Consumo  | `POST /v1/exchange_tokens/{id}` (requiere `sk_`) |

**Por qué existe:** las credenciales bancarias nunca tocan tu backend. Tu frontend solo ve un `et_` opaco que tu backend canjea por el `link_id` definitivo.

## Modo test vs live

Las keys vienen en dos modos:

* **`test`**: para integración sin tocar bancos reales (sandbox).
* **`live`**: producción. Cada llamada que dispara sync llama al banco real.

Los recursos creados con `sk_test` solo se ven con keys `_test`. No hay cross-talk entre modos. Los responses incluyen `"mode": "live"` o `"mode": "test"`.

<Note>
  **Test mode ya está disponible.** Conecta bancos fake con credenciales mágicas (RUT `11.111.111-1` + clave `rail-sandbox`) y recibe cuentas + movimientos deterministas, sin tocar un banco real. Ver [Test mode (Sandbox)](/test-mode) para la guía completa y la tabla de escenarios.
</Note>

## Manejo de errores de auth

| Status | `error.code`         | Significa                                                   |
| ------ | -------------------- | ----------------------------------------------------------- |
| `401`  | `invalid_credential` | Key inexistente, revocada o malformada                      |
| `403`  | `insufficient_scope` | La key existe pero no tiene scope para ese endpoint         |
| `403`  | `wrong_mode`         | Estás usando `sk_test` contra recursos `live` (o viceversa) |

Ver [guías → Errores](/guides/errors) para el shape completo del error envelope.
