Errores
Códigos de error de la API de Simplo, clases de error del SDK por status HTTP y las reglas de reintento automático.
Toda falla del SDK lanza una subclase de SimploError. Captura estrecho
cuando puedas actuar sobre el caso, amplio en el resto:
import Simplo, { RateLimitError, SimploError, ValidationError } from '@simplohq/sdk';
const simplo = new Simplo();
try { await simplo.dtes.emit(params);} catch (error) { if (error instanceof ValidationError) { // Input malo — corrige la request, no la reintentes tal cual. for (const issue of error.details ?? []) { console.error(`${issue.field}: ${issue.code} — ${issue.message}`); } } else if (error instanceof RateLimitError) { // El SDK ya reintentó; frena al llamador. console.error(`Rate limit. Reintenta en ${error.retryAfter ?? '?'}s`); } else if (error instanceof SimploError) { console.error(error.status, error.code, error.message, error.requestId); } else { throw error; // error de programación — no lo tragues }}Propiedades del error
Sección titulada «Propiedades del error»| Propiedad | Tipo | Descripción |
|---|---|---|
status |
number | undefined |
Status HTTP (ausente en fallas de conexión) |
code |
string | undefined |
Código de la API legible por máquina, ej. "VALIDATION_ERROR" |
message |
string |
Descripción legible por humanos |
requestId |
string | undefined |
ID de la request — inclúyelo al contactar soporte |
details |
ValidationIssue[] |
Issues a nivel de campo (field, code, message) en errores de validación |
action |
string | undefined |
Siguiente paso recomendado por la API, cuando existe |
docUrl |
string |
Link a la documentación relevante |
Clases de error por status
Sección titulada «Clases de error por status»| Status | Clase | ¿Reintentar? | Causas típicas |
|---|---|---|---|
| 400/422 | ValidationError |
No — corrige la request | Dígito verificador de RUT inválido, campos requeridos ausentes |
| 401 | AuthenticationError |
No — corrige credenciales | API key errónea o revocada (Autenticación) |
| 403 | PermissionError |
No | La key no tiene el permiso o rol requerido |
| 404 | NotFoundError |
No | ID equivocado, o recurso de otra empresa |
| 409 | ConflictError |
Depende (ver abajo) | Folio duplicado; idempotency key aún en vuelo |
| 429 | RateLimitError |
Automático | Demasiadas requests (los límites son por empresa) |
| 5xx | ServerError |
Automático (si es seguro) | Problema transitorio de la API |
| — | ConnectionError |
Automático (si es seguro) | Falla de red, DNS, timeout |
| — | WebhookVerificationError |
No — rechaza la entrega | Firma mala, timestamp vencido (Webhooks) |
Códigos que vas a ver como integrador
Sección titulada «Códigos que vas a ver como integrador»| Código | Descripción |
|---|---|
401 |
Credencial inválida, revocada o expirada. La respuesta no distingue el motivo (anti-enumeración): revisa el header y el prefijo sk_simplo_. |
409 IDEMPOTENCY_IN_PROGRESS |
La misma Idempotency-Key aún se está procesando. Espera y consulta el estado en vez de reintentar de inmediato. |
409 (folio duplicado) |
Conflicto de folio al emitir. |
422 IDEMPOTENCY_BODY_MISMATCH |
Reutilizaste una Idempotency-Key con un body distinto al original. Usa una key nueva por cada emisión distinta. |
429 |
Rate limit: 120 llamadas por minuto por empresa, compartido entre REST y MCP. Espera y reintenta. |
503 (idempotencia) |
Servicio de idempotencia temporalmente no disponible al emitir. Reintenta con la misma key. |
Reintentos automáticos
Sección titulada «Reintentos automáticos»El SDK reintenta en 429, 5xx y errores de red con backoff exponencial y
jitter, respetando el header Retry-After. Por defecto: 2 reintentos;
sobrescríbelo con maxRetries en el cliente o por request.
Regla de seguridad: un POST solo se reintenta cuando lleva una
Idempotency-Key. dtes.emit genera una automáticamente (UUID v4), así que
los reintentos de emisión nunca pueden duplicar un documento. Otros POSTs
(folios.upload, webhooks.create) no se reintentan automáticamente —
vuelve a llamarlos tú si hace falta; ambos son seguros de re-ejecutar (un CAF
duplicado devuelve ConflictError).
const simplo = new Simplo({ maxRetries: 3, timeout: 30_000 });await simplo.dtes.list({}, { maxRetries: 0 }); // override por request