Flujo de emisión
Desde la versión v1.4.0, toda emisión de DTE es asíncrona.
Por qué asíncrono
Procesar un DTE contra el SII toma unos segundos. Un modelo asíncrono te da una respuesta inmediata y un manejo robusto de reintentos, sin dejar tu request colgado esperando.
El flujo
- Tu sistema envía
POST /v1/dte/emitircon el JSON del documento. Folyo valida los datos y responde202 Acceptedde inmediato con unjob_id. - Folyo procesa el documento y lo envía al SII en segundo plano.
- Recibes el resultado por uno de tres canales:
| Canal | Cuándo usar |
|---|---|
| Webhook | Recomendado. Tu endpoint recibe el evento dte.emitido con el resultado. |
| Polling | GET /v1/dte/emision/:jobId cada 2-3 segundos hasta un estado terminal: completed, failed, dlq o discarded. |
| SSE | Solo para dashboards en el browser. No recomendado para integraciones server-side. |
Estados del job
reserved— reserva interna previa al folio; no está publicable ni puede reclamarse.pending— en cola, esperando procesamiento.scheduled— reintento programado para una hora posterior.processing— en proceso contra el SII.completed— el SII recibió el envío y devolvió un Track ID. No confirma la aceptación final del DTE.failed— error terminal del procesamiento. Revisa el campoerrorpara el detalle.dlq— el job llegó a la cola de fallas por un error permanente o tras agotar sus reintentos; no implica un reintento automático. No reemitas todavía: primero confirma si el SII alcanzó a recibir el documento.discarded— un job reservado o en DLQ fue descartado manualmente; no continuará su procesamiento.
Después del envío: el veredicto del SII
Que el job termine en completed significa que el SII recibió el documento y le asignó un Track ID. El veredicto (aceptación o rechazo) llega después: el documento queda en estado enviado y Folyo consulta al SII de forma automática hasta obtener una respuesta firme, momento en que pasa a aceptado_sii o rechazado_sii.
La aceptación SII queda persistida y puede consultarse con GET /v1/dte/consulta/:tipo/:folio; no genera un webhook externo. Un rechazo SII sí dispara dte.rechazado. El evento dte.emitido corresponde al envío con Track ID, no a la aceptación tributaria final.
Normalmente el SII responde en minutos, pero en horas de alta carga puede demorar más de una hora en procesar un envío. Es una demora del SII, no un error:
- No reemitas un documento porque siga en
enviado: el folio ya está usado y una reemisión crea un documento duplicado. Si reintentas unPOST /v1/dte/emitirpor un error de red, usa siempre el headerIdempotency-Key. - Usa polling para la aceptación final y, si tu plan incluye webhooks, suscríbete a
dte.rechazadopara enterarte de un rechazo sin asumir un plazo fijo.
Idempotencia y validación previa
La Idempotency-Key se evalúa por tenant. Usa una clave por emisión lógica y conserva esa misma clave al reintentar el mismo body: Folyo devuelve el job existente. La misma clave con un cuerpo distinto responde 409 IDEMPOTENCY_KEY_CONFLICT.
Un estado failed o dlq no demuestra que el SII no haya recibido el documento: el fallo puede ocurrir después del intento de envío. No lo reemitas automáticamente. Antes de corregirlo, confirma con Folyo y el SII que no hubo envío, que no existe Track ID y que el documento no está registrado. Solo después de esa confirmación explícita usa el request corregido con una nueva clave. Si Folyo reencola operativamente el job original, no crees otra emisión.
Antes de crear el job, Folyo normaliza los giros para el XML del DTE: el GiroEmis efectivo de la empresa —el principal o el seleccionado con emisor_acteco— se acorta a 80 caracteres Unicode y el giro del receptor a 40. La normalización no modifica los datos guardados de la empresa ni del cliente; solo protege la emisión frente a los límites del SII.