Desarrolladores · API v1 · versión 2026-10-22
Eventos RADIAN
Registra ante la DIAN los eventos de una factura: el acuse de recibo (030), el reclamo (031), el recibo del bien o servicio (032) y la aceptación expresa (033) de una factura que te emitieron, y la aceptación tácita (034) de una factura tuya a crédito.
1. Los cinco eventos
event_code | Evento | Sobre | Cómo se identifica la factura |
|---|---|---|---|
030 | Acuse de recibo | Una factura recibida | invoice (CUFE, número, emisor) |
031 | Reclamo | Una factura recibida | invoice y claim (obligatorio) |
032 | Recibo del bien o servicio | Una factura recibida | invoice |
033 | Aceptación expresa | Una factura recibida | invoice |
034 | Aceptación tácita | Una factura propia a crédito, validada y no de consumidor final | invoice_id (inv_…) |
Los eventos 035 a 051 (aval, endosos, pago, cesión…) necesitan un participante RADIAN habilitado y no están disponibles: validation_error en event_code.
2. Antes de emitir
- Los eventos
030y032los firma el representante legal de la empresa: se registra en la app. Sin él,422 company_not_enabledconreason: "missing_legal_representative".GET /v1/company→capabilities.radian_eventsdice qué tienes. - Se comprueba antes de numerar. El NIT del emisor de una factura recibida no puede ser el de tu empresa (
invoice.issuer.nit).
3. Enviar un evento
Envía un evento RADIAN sobre una factura: el acuse de recibo (030), el reclamo (031), el recibo del bien o servicio (032) y la aceptación expresa (033) de una factura RECIBIDA (invoice), o la aceptación tácita (034) de una factura PROPIA a crédito (invoice_id, de Trevol). Los eventos 035 a 051 necesitan un participante RADIAN y no están disponibles. El 030 y el 032 necesitan el representante legal de la empresa (lo firma): se configura en la app. Un rechazo es final: el siguiente intento es otro evento, con otro número (POST nuevo). Un evento vivo del mismo código sobre la misma factura es 409 duplicate_document con existing_id: reintenta ese con POST …/send. already_registered: true (con 201) solo significa que la DIAN ya mostraba el CUDE de ESTE evento; si la factura ya tenía ese evento por otro camino es 422 dian_rejected con already_registered_elsewhere: true. La DIAN pide el evento anterior antes del siguiente: en la 2026-10-21 es 409 previous_event_pending; en la 2026-10-22, 202 processing y Trevol lo manda cuando aparezca. Si la DIAN contesta 98 («en proceso de validación») es 202 validating: no reenvíes. Para saber si el 034 procede antes de pedirlo, usa GET /v1/invoices/{id}/tacit_acceptance.
curl https://api.trevol.si/v1/radian_events \
-H "Authorization: Bearer $TREVOL_LLAVE" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"external_id": "ERP-ACUSE-OJ1234",
"event_code": "030",
"invoice": {
"cufe": "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
"number": "OJ1234",
"type": "01",
"issuer": {
"nit": "890330031",
"check_digit": 3,
"document_type": "31",
"name": "OSPINA Y ASOCIADOS SAS"
}
}
}'HTTP/1.1 201 Created
Location: /v1/radian_events/rev_3f0c1a2b3f0c1a2b3f0c1a2b3f0c1a2b
{
"id": "rev_3f0c1a2b3f0c1a2b3f0c1a2b3f0c1a2b",
"object": "radian_event",
"environment": "test",
"status": "accepted",
"event_code": "030",
"number": "AR994000123",
"prefix": "AR",
"external_id": "ERP-ACUSE-OJ1234",
"origin": "api",
"cude": "abababababababababababababababababababababababababababababababababababababababababababababababab",
"issued_at": "2026-10-23T09:15:02-05:00",
"invoice": {
"cufe": "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
"number": "OJ1234",
"type": "01",
"issuer": {
"nit": "890330031",
"check_digit": 3,
"document_type": "31",
"name": "OSPINA Y ASOCIADOS SAS"
}
},
"claim": null,
"software": "own",
"provider": "company",
"dian": {
"status_code": "02",
"message": "Documento validado por la DIAN",
"rules": []
},
"already_registered": false,
"already_registered_elsewhere": false,
"tacit": false,
"created_at": "2026-10-23T09:15:02-05:00",
"updated_at": "2026-10-23T09:15:03-05:00"
}El reclamo (031) lleva su concepto:
curl https://api.trevol.si/v1/radian_events \
-H "Authorization: Bearer $TREVOL_LLAVE" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"external_id": "ERP-RECLAMO-OJ1234",
"event_code": "031",
"invoice": {
"cufe": "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
"number": "OJ1234",
"type": "01",
"issuer": {
"nit": "890330031",
"check_digit": 3,
"document_type": "31",
"name": "OSPINA Y ASOCIADOS SAS"
}
},
"claim": {
"code": "02",
"note": "Faltaron dos cajas"
}
}'
4. La aceptación tácita (034)
Procede cuando pasan 3 días hábiles desde el recibo del bien o servicio (032) sin que el comprador reclame ni acepte. Para no gastar un evento en vano, pregunta primero:
curl https://api.trevol.si/v1/invoices/inv_3f0c1a2b3f0c1a2b3f0c1a2b3f0c1a2b/tacit_acceptance \
-H "Authorization: Bearer $TREVOL_LLAVE"
HTTP/1.1 200 OK
{
"object": "tacit_acceptance",
"invoice_id": "inv_3f0c1a2b3f0c1a2b3f0c1a2b3f0c1a2b",
"allowed": false,
"available_from": "2026-10-27",
"rules": [
{
"code": "LGC14",
"severity": "rejection",
"local": true,
"message": "Faltan días hábiles para la aceptación tácita.",
"explanation": "Pasan 3 días hábiles desde el recibo del bien o servicio (evento 032)."
}
]
}Solo lee: consulta a la DIAN con el certificado de la empresa y no envía nada; usa el mismo historial que el envío, y tiene su propio límite de 30 consultas por minuto por llave. Cuando procede, se pide con invoice_id en lugar de invoice:
curl https://api.trevol.si/v1/radian_events \
-H "Authorization: Bearer $TREVOL_LLAVE" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"external_id": "ERP-TACITA-FE1234",
"event_code": "034",
"invoice_id": "inv_3f0c1a2b3f0c1a2b3f0c1a2b3f0c1a2b"
}'Si todavía no procede, el envío responde 422 tacit_acceptance_not_due con la fecha y las reglas; el evento queda en error con su número y se reintenta con POST /v1/radian_events/{id}/send cuando proceda.
HTTP/1.1 422
Content-Type: application/problem+json
{
"type": "https://trevol.si/api/errores#tacit_acceptance_not_due",
"title": "La aceptación tácita todavía no procede",
"status": 422,
"code": "tacit_acceptance_not_due",
"detail": "La aceptación tácita (034) todavía no procede para esta factura.",
"retryable": false,
"available_from": "2026-10-27",
"rules": [
{
"code": "LGC14",
"severity": "rejection",
"local": true,
"message": "Faltan días hábiles para la aceptación tácita.",
"explanation": "Pasan 3 días hábiles desde el recibo del bien o servicio (evento 032)."
}
],
"request_id": "req_5b1c5b1c5b1c5b1c5b1c5b1c"
}
5. Lo que hay que saber
- Un rechazo es final. El siguiente intento es otro evento con otro número (un
POSTnuevo, con otraIdempotency-Key). No hayPUT. - Un evento vivo por factura y código. Otro
POSTdel mismo código sobre la misma factura es409 duplicate_documentcon elexisting_id(rev_…), lo haya creado la API o la app. Para reintentar ese evento:POST /v1/radian_events/{id}/send. - El orden de la DIAN. La DIAN pide el evento anterior antes del siguiente. Si todavía no lo muestra, en la versión 2026-10-21 es
409 previous_event_pending(no se envió nada; reintenta conPOST …/send); en la 2026-10-22 es un202 processingy Trevol lo manda cuando aparezca. - El 98 de la DIAN («en proceso de validación») es
202constatus: "validating"en las dos versiones: Trevol solo consulta; no reenvíes. already_registered: true(con201) significa que la DIAN ya mostraba el CUDE de este evento. Si la factura ya tenía ese evento por otro camino, es422 dian_rejectedcondocument.already_registered_elsewhere: true.- Solo se descarga el
…/xml. Se cobra con la lista de eventos del canal API. - El
external_ides único entre los eventos (aparte de las facturas y las nóminas).
Las respuestas son las de toda la API: 201 cuando la DIAN valida, 422 dian_rejected con document cuando la rechaza, 422 validation_error si Trevol lo rechaza antes de numerar (no se gasta ningún número), 402 sin saldo, y con la DIAN sin contestar un 202 processing (versión 2026-10-22) o un 503 dian_unavailable (2026-10-21). Idempotency-Key es obligatoria al crear o corregir, y external_id es opcional.
6. Rutas
| Método | Ruta | Qué hace |
|---|---|---|
| POST | /v1/radian_events | Emitir un evento RADIAN |
| GET | /v1/radian_events | Listar (evento RADIAN) |
| GET | /v1/radian_events/{id} | Un evento radian |
| POST | /v1/radian_events/{id}/send | Reenviar una pendiente o en error |
| GET | /v1/radian_events/{id}/xml | Archivo xml |
| GET | /v1/invoices/{id}/tacit_acceptance | ¿Procede ya la aceptación tácita (034) de esta factura? |
7. Avisos (webhooks)
Salen por cualquier camino. El data es un resumen sin nombres ni NIT de quien emitió la factura. Los avisos «todavía no procede» y «falta el evento anterior» no emiten radian_event.error.
| Tipo | Cuándo |
|---|---|
radian_event.accepted | La DIAN validó el evento RADIAN. Pasa por cualquier camino (API, app, conector o verificación de fondo). (Catálogo 2: un * de un endpoint creado antes de la fase 3 no lo recibe hasta que se guarde de nuevo su lista de eventos.) |
radian_event.rejected | La DIAN rechazó el evento. Un rechazo es final: el siguiente intento es otro POST /v1/radian_events (otro número). (Catálogo 2: un * de un endpoint creado antes de la fase 3 no lo recibe hasta que se guarde de nuevo su lista de eventos.) |
radian_event.error | El evento quedó en error: la DIAN no confirmó y Trevol dejó de reintentar. data.error lleva un code y un texto fijo. Reenvíalo con POST …/send. (Catálogo 2: un * de un endpoint creado antes de la fase 3 no lo recibe hasta que se guarde de nuevo su lista de eventos.) |
{
"id": "evt_3f0c1a2b3f0c1a2b3f0c1a2b3f0c1a2b",
"object": "event",
"type": "radian_event.rejected",
"timestamp": "2026-10-23T14:15:03Z",
"environment": "test",
"api_version": "2026-10-22",
"data": {
"object": "radian_event",
"id": "rev_3f0c1a2b3f0c1a2b3f0c1a2b3f0c1a2b",
"status": "rejected",
"environment": "test",
"event_code": "031",
"number": "RC994000124",
"prefix": "RC",
"external_id": "ERP-RECLAMO-OJ1234",
"origin": "api",
"cude": "abababababababababababababababababababababababababababababababababababababababababababababababab",
"issued_at": "2026-10-23T09:15:02-05:00",
"invoice": {
"cufe": "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
"number": "OJ1234",
"id": null
},
"dian": {
"status_code": "99",
"rules": [
{
"code": "LGC09",
"severity": "rejection"
}
]
}
}
}
8. Campos
Evento (cuerpo de POST)
| Campo | Tipo | Qué es |
|---|---|---|
external_id | texto | Tu identificador del documento: único entre los documentos API de la empresa y el ambiente. En los eventos es único entre los eventos (aparte de las facturas y las nóminas). |
event_code obligatorio | texto | "030" acuse de recibo, "031" reclamo, "032" recibo del bien o servicio, "033" aceptación expresa (las cuatro sobre una factura RECIBIDA) o "034" aceptación tácita (sobre una factura PROPIA a crédito). Los 035 a 051 necesitan un participante RADIAN y no están disponibles. |
invoice | ReceivedInvoice | 030–033: la factura RECIBIDA sobre la que va el evento (CUFE, número y quién la emitió). |
invoice_id | texto | 034: el id (inv_…) de una factura de Trevol: propia, validada, a crédito y que no sea de consumidor final. Va aparte de invoice para que cada esquema sea plano en los SDK. |
claim | EventClaim | Solo en el reclamo (031) y obligatorio en él: {code: "01" a "04", note?}. |
software | own | dian_free | 030–033: own (el Software Propio de la empresa, por defecto) o dian_free (el software gratuito de la DIAN). El 034 se firma con el Software Propio. |
provider | dian | company | 030–033: quién es el proveedor tecnológico: dian (por defecto con dian_free) o company (por defecto con own). |
Factura recibida (invoice)
| Campo | Tipo | Qué es |
|---|---|---|
cufe | texto | |
number | texto | |
type | texto | Tipo de documento de la factura ("01" a "04"; por defecto "01"). |
issuer | ReceivedInvoiceIssuer | |
acquirer_document_type | texto | El tipo de documento con que el emisor identificó a la empresa en la factura ("31" NIT o "13" cédula). Por defecto, el de la empresa (si no, la regla AAH09). |
Emisor de la factura (invoice.issuer)
| Campo | Tipo | Qué es |
|---|---|---|
nit | texto | |
check_digit | entero | Opcional: si viene, tiene que ser el DV del NIT. |
document_type | texto | Tipo de documento (tabla 13.2.1 de la DIAN): 13 CC, 31 NIT, 22 CE, 41 PA… |
name | texto | Se guarda (va en el XML) pero no sale en los webhooks. |
Reclamo (claim)
| Campo | Tipo | Qué es |
|---|---|---|
code | texto | Código (texto). |
note | texto |
Evento (lo que devuelve la API)
Un evento RADIAN 030–034 sobre una factura. Solo archivo xml. Un rechazo es final.
| Campo | Tipo | Qué es |
|---|---|---|
id | texto | |
object | radian_event | |
environment | test | live | |
status | pending | sending | validating | accepted | rejected | error | processing | validating: la DIAN respondió 98 («en proceso de validación»); no es un error, responde 202 en las dos versiones y Trevol solo consulta (el 98 significa «no reenvíes»). processing: solo en la 2026-10-22, un envío en duda o el evento anterior que aún no aparece: Trevol lo sigue resolviendo. error incluye el envío en duda de la 2026-10-21. |
event_code | 030 | 031 | 032 | 033 | 034 | |
number | texto (puede ser null) | |
prefix | texto (puede ser null) | |
external_id | texto (puede ser null) | |
origin | api | app | |
cude | texto (puede ser null) | |
issued_at | fecha y hora (puede ser null) | |
invoice | objeto | 030–033: la factura recibida (con el emisor). 034: {id, cufe, number} de la factura propia. |
claim | EventClaim (puede ser null) | |
software | own | dian_free | |
provider | dian | company | |
dian | objeto | |
already_registered | booleano | true: GetStatusEvent ya mostraba el CUDE de ESTE evento (un envío en duda que sí llegó); se cerró accepted sin reenviar. |
already_registered_elsewhere | booleano | true: la DIAN rechazó con LGC01, la factura ya tiene ese evento (quizá de otro software); no hace falta enviarlo. |
tacit | booleano | 033 rechazada con DC24c: la factura ya quedó aceptada tácitamente. |
created_at | fecha y hora | |
updated_at | fecha y hora (puede ser null) |
Aceptación tácita (GET …/tacit_acceptance)
¿Procede ya la aceptación tácita (034) sobre una factura propia? Solo lectura: consulta GetStatusEvent con el certificado de la empresa y no envía nada. Límite propio: 30 por minuto por llave.
| Campo | Tipo | Qué es |
|---|---|---|
object | tacit_acceptance | |
invoice_id | texto | |
allowed | booleano | |
available_from | fecha (AAAA-MM-DD) (puede ser null) | Desde cuándo procede (3 días hábiles después del recibo del bien, 032). |
rules | lista de objeto | Las reglas (LGC…) que impiden el 034 ahora; llevan local: true. |