Manejo de errores

Todos los errores de la API siguen el mismo formato: error es un mensaje legible para humanos y code es el código estable de máquina contra el que debes programar tu lógica.

json
{
  "ok": false,
  "error": "La empresa no tiene folios disponibles para el tipo 33.",
  "code": "NO_FOLIOS"
}

Errores HTTP comunes

CódigoDescripciónQué hacer
400Request inválido (datos faltantes o mal formados)Revisar el body del request
401No autenticadoRenovar el JWT o verificar la API Key
403Sin permisos o límite del plan alcanzadoVerificar el rol del usuario; si el code es PLAN_LIMIT, ver Límites del plan
404Recurso no encontradoVerificar el ID o folio en el path
409Conflicto (ej: folio ya usado)Verificar el estado actual del recurso
410Archivo expirado (plan gratuito)Si el code es XML_EXPIRADO, ver Expiración de archivos
422Validación fallidaEl SII rechazó los datos del DTE
429Rate limit superadoEsperar el tiempo indicado en Retry-After
503Servicio no disponibleRedis no disponible, reintentar en 30s

Límites del plan

Aparte del rate limit HTTP (429), cada plan tiene cuotas mensuales: emisión de DTEs, boletas, consultas al SII, usuarios, empresas y API keys. Cuando alcanzas un tope, la API responde 403 con el código estable PLAN_LIMIT:

json
{
  "ok": false,
  "error": "Límite de consultas mensuales alcanzado. Actualice su plan.",
  "code": "PLAN_LIMIT"
}

A diferencia del 429, esto no se resuelve esperando unos segundos: el contador de cada período se reinicia al inicio del próximo mes (hora de Chile), o subes de plan. Distingue PLAN_LIMIT (403, cupo del plan agotado) de 429 (ráfaga de requests, se recupera solo) por el code, no por el status.

La cuota de consultas al SII cubre las llamadas que Folyo hace por ti a servicios externos de pago por uso (consulta de contribuyente, situación tributaria, sincronización del RCV, estado de DTE, folios, RCOF, acuse, extracción con IA). Emitir DTEs no descuenta de esta cuota; tiene la suya. Cada respuesta sujeta a cuota trae los headers X-Quota-Limit, X-Quota-Remaining y X-Quota-Period. Revisa Rate limits y cuotas para el detalle de qué llamadas consumen cuota.

Expiración de archivos en el plan gratuito

En el plan gratuito, la descarga del XML firmado y del PDF de cada documento está disponible solo por un tiempo desde la emisión. En los planes de pago los archivos no expiran.

Ambiente del documentoDescarga disponible por
Producción4 horas
Certificación30 minutos

Pasada la ventana, GET /v1/dte/xml/:tipo/:folio y GET /v1/dte/pdf/:tipo/:folio responden 410 con el código estable XML_EXPIRADO (el PDF comparte el código porque se genera a partir del XML):

json
{
  "ok": false,
  "error": "El XML del DTE tipo 33 folio 1001 ya no está disponible: el plan gratuito lo conserva por 4 horas desde la emisión (30 minutos si es del ambiente de certificación). El documento sigue emitido y vigente ante el SII; no vuelva a emitirlo. Los planes de pago conservan los XML sin límite de tiempo.",
  "code": "XML_EXPIRADO"
}

Dos cosas importantes:

  • El documento no desaparece: solo expira la descarga. El DTE sigue emitido y vigente ante el SII, con su folio consumido, y lo sigues viendo en el listado de documentos con montos, receptor y estado. No vuelvas a emitirlo: duplicarías el documento ante el SII.
  • Guarda los archivos al emitir. El resultado del job de emisión y el webhook dte.emitido llegan dentro de la ventana: descarga el XML y el PDF apenas el job termina y almacénalos de tu lado. Si necesitas re-descargar más adelante, cualquier plan de pago conserva los archivos sin expiración.

Errores de emisión DTE

Cuando el job de emisión falla (estado: "failed"), el campo error del resultado contiene el detalle:

ErrorDescripción
SII_REJECTEDEl SII rechazó el DTE. Ver detail para el código SII.
NO_FOLIOSNo hay folios disponibles para el tipo de DTE.
CERT_ERRORError con el certificado digital (vencido o inválido).
XML_SIGN_ERRORError al firmar el XML. Verificar el certificado.

Reintentos

La API no reintenta automáticamente los requests fallidos del cliente. Sin embargo, Folyo reintenta el envío al SII de forma automática antes de marcar el job como failed.

Para los webhooks, Folyo reintenta la entrega hasta 5 veces con backoff exponencial.