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.
Shape estándar
Todos los errores 4xx/5xx siguen este shape:
{
"error": {
"type": "invalid_request_error",
"code": "missing_field",
"message": "El campo 'link_id' es requerido.",
"param": "link_id",
"doc_url": "https://docs.rail.cl/guides/errors#missing_field"
}
}
| Field | Tipo | Significa |
|---|
type | string | Categoría del error |
code | string | Identificador específico (usar para lógica) |
message | string | Texto en español para mostrar al user |
param | string? | Field específico que rompió (opcional) |
doc_url | string? | URL a esta doc con anchor al code (opcional) |
Types
type | HTTP | Significa |
|---|
invalid_request_error | 400 | Validación de body/query/params |
authentication_error | 401 | Credencial inválida o ausente |
permission_error | 403 | Credencial válida pero sin scope |
not_found_error | 404 | Recurso no existe o no pertenece al cliente |
conflict_error | 409 | Estado conflictivo (idempotency_conflict, in_progress, etc) |
rate_limit_error | 429 | Demasiados requests — backoff |
bank_error | 502 | El banco rebotó (transient) |
internal_error | 500 | Error nuestro — reintentá |
Catálogo de codes
Auth
code | Significa |
|---|
invalid_credential | Key inexistente, malformada o revocada |
insufficient_scope | Key válida pero sin permisos para el endpoint |
wrong_mode | Estás usando sk_test contra recursos live o viceversa |
Validación
code | Significa |
|---|
missing_field | Falta un campo requerido (ver param) |
invalid_field | Campo con valor inválido (ver param) |
unknown_field | Campo no reconocido en el body |
Recursos
code | Significa |
|---|
link_not_found | El link_id no existe o no pertenece al cliente |
account_not_found | El account_id no existe |
bank_not_supported | El bank_id no está habilitado |
Refresh intents
code | Significa |
|---|
refresh_intent_in_progress | Ya hay un intent activo para este link |
refresh_intent_cooldown | Esperá los 5min de cooldown desde el último intent |
Bancos (transient — reintentables)
code | Significa |
|---|
bank_unavailable | Banco caído o muy lento |
bank_format_change | Banco cambió HTML, parser nuestro está roto. Rail está sobre eso. |
rejected_credentials | Banco rechazó las creds. User debe re-conectar (no es transient técnicamente — es del user). |
Idempotency
code | Significa |
|---|
idempotency_conflict | Misma Idempotency-Key con body diferente |
Manejo recomendado
async function railFetch<T>(path: string, opts: RequestInit): Promise<T> {
const res = await fetch(`https://api.rail.cl${path}`, opts);
if (!res.ok) {
const body = await res.json().catch(() => ({}));
const err = body.error ?? {};
throw new RailError(res.status, err.code, err.message, err.param);
}
return res.json();
}
class RailError extends Error {
constructor(
public status: number,
public code: string,
message: string,
public param?: string,
) {
super(message);
}
}
Después, en tu app:
try {
await railFetch('/v1/refresh_intents', { ... });
} catch (e) {
if (e instanceof RailError) {
if (e.code === 'refresh_intent_in_progress') {
// No es error real — ya está corriendo
return;
}
if (e.code === 'rejected_credentials') {
// Notificá al user para que re-conecte
}
if (e.status >= 500) {
// Transient, reintentar con backoff
}
}
}