Tema
Conceptos
Lo que hay detrás de los campos. Está ordenado por lo que se necesita entender antes: ambiente, identificadores, ciclo de vida, y los dos casos raros —contingencia y lotes— que solo importan cuando algo se sale de lo normal.
Ambiente: 00 pruebas, 01 producción
Hacienda tiene dos ambientes y son mundos separados: distintas credenciales, distintos correlativos, distintos sellos. Un documento de pruebas no existe en producción y viceversa.
El ambiente lo fija la configuración del contribuyente, no la petición. Lo que sí te dice en cuál estás es el prefijo de tu API key: sk_test_ o sk_live_. Es deliberado — si una llave se filtra en un log, se ve de un vistazo si el problema es grave.
Todo lo que emitas contra sk_live_ tiene valor fiscal, aunque haya sido sin querer. Se anula con una nota de crédito, un evento de retorno o una invalidación, no borrándolo.
Los dos identificadores de un documento
Un DTE tiene dos números y hacen cosas distintas. Confundirlos cuesta tiempo.
Código de generación
2F380579-2A15-42E8-9ADF-4EA97AE4DA3AUn UUID en mayúsculas. Lo genera el emisor, es único en todo el sistema de Hacienda, y es la clave con la que se consulta todo: el estado, el PDF, el JSON, la línea de tiempo, y el documento que ajusta una nota de crédito.
Guárdalo en tu base junto a tu propia venta. Es el enlace entre tu sistema y el fiscal.
Número de control
DTE-01-M001P001-000000000000042
│ │ │ └── correlativo, 15 dígitos
│ │ └── establecimiento (M001) y punto de venta (P001)
│ └── tipo de documento (CAT-002)
└── prefijo fijoEs el correlativo: una secuencia sin huecos por cada combinación de tipo, establecimiento y punto de venta. Es lo que revisa un auditor.
Dos consecuencias prácticas:
- Un correlativo consumido no se recupera. Si emites un documento por error, el número queda usado y hay que justificar qué pasó con él. Por eso
Idempotency-Keyes obligatoria. - Un correlativo no retrocede. Si vienes de otro proveedor y ya ibas por el 1500, se posiciona la serie con
PUT /api/v1/dte/series. Hacia atrás, nunca: serían dos documentos con el mismo número.
El ciclo de un documento
┌──────────────┐
POST /documentos ──────▶│ TRANSMITIENDO│
└──────┬───────┘
│
┌───────────────┼────────────────┐
▼ ▼ ▼
┌──────────┐ ┌────────────┐ ┌──────────────────┐
│ SELLADO │ │ RECHAZADO │ │ EN_CONTINGENCIA │
└────┬─────┘ └────────────┘ └──────────────────┘
│
▼
┌─────────────┐
│ INVALIDADO │
└─────────────┘| Estado | Qué significa |
|---|---|
TRANSMITIENDO | Firmado y en camino a Hacienda. Todavía no existe fiscalmente. |
SELLADO | Hacienda lo aceptó. selloRecibido trae los 40 caracteres del sello. Este es el único estado que cuenta. |
RECHAZADO | Hacienda lo rechazó. codigoMsg y descripcionMsg dicen por qué. El correlativo queda consumido igual. |
EN_CONTINGENCIA | Hacienda no respondió y el documento quedó acumulado. Ver abajo. |
INVALIDADO | Estaba sellado y se anuló con un evento de invalidación. |
FIRMADO, BORRADOR, ERROR_FIRMA | Estados internos. Si ves ERROR_FIRMA de forma persistente, el certificado del contribuyente tiene un problema. |
Cómo enterarte de que pasó a SELLADO
Tres caminos, de mejor a peor:
- Webhook. Te avisan. Es lo correcto para un sistema que factura a diario. → Webhooks
?esperar=8sal emitir. Para una caja que tiene que imprimir el ticket ahora. Máximo 20 segundos.- Sondear
GET /api/v1/dte/documentos/{cg}. Funciona, pero si lo haces cada segundo para cada documento acabarás limitado por peticiones. Úsalo como red de seguridad del webhook, no como mecanismo principal.
Qué hacer si un documento sale RECHAZADO
Un rechazo no se reintenta tal cual: Hacienda ya dijo que ese contenido no le sirve. Lo que se hace es corregir y emitir uno nuevo, que consumirá el siguiente correlativo.
descripcionMsg trae el motivo textual de Hacienda y observaciones el detalle. Los rechazos más comunes son datos del receptor incompletos en un CCF y códigos de catálogo que no existen.
El documento rechazado no se invalida: no llegó a existir, así que no hay nada que anular.
Contingencia
Cuando Hacienda no responde —se cae, o hay mantenimiento—, el sistema no deja de facturar. Los documentos se firman igual y quedan EN_CONTINGENCIA.
Lo importante para ti: el documento es válido y se le puede entregar al cliente. La normativa lo contempla. Cuando Hacienda vuelve, se declara el evento de contingencia y los acumulados se transmiten.
Del lado del integrador no hay nada especial que hacer, salvo no interpretar EN_CONTINGENCIA como un error. Si tu sistema bloquea la venta cuando el documento no está SELLADO, en una contingencia dejas de vender sin necesidad.
Lotes
Para cargas masivas —una migración, el cierre de un mes acumulado— está POST /api/v1/dte/lotes, que recibe muchos documentos de una vez y los procesa en segundo plano.
No lo uses para la operación normal. Un lote no te da el sello de un documento concreto rápido, y el punto de venta necesita justo eso.
Catálogos
Hacienda define 33 catálogos de códigos: unidades de medida, actividades económicas, departamentos, formas de pago. Están servidos en GET /api/v1/dte/catalogos y GET /api/v1/dte/catalogos/{cat}.
Los que más se usan:
| Catálogo | Para qué | Valor típico |
|---|---|---|
| CAT-002 | Tipo de documento | 01 Factura, 03 CCF, 04 NR, 11 FEX, 14 FSE… |
| CAT-011 | Tipo de ítem | 1 bien, 2 servicio |
| CAT-014 | Unidad de medida | 59 unidad |
| CAT-016 | Condición de la operación | 1 contado, 2 crédito |
| CAT-017 | Forma de pago | 01 efectivo, 02 débito, 03 crédito, 05 transferencia |
| CAT-019 | Actividad económica | del receptor, en el CCF |
| CAT-022 | Tipo de documento de identidad | 36 NIT, 13 DUI |
| CAT-012 / 013 / 036 | Departamento / municipio / distrito | dirección |
Trampa con los municipios (CAT-013): el código no es único por sí solo, se repite entre departamentos. El municipio 23 existe en varios. Solo tiene sentido junto a su departamento, y por eso el endpoint acepta ?padre=06.
Emisor, establecimientos y puntos de venta
Un contribuyente tiene uno o varios establecimientos (sucursales) y cada uno tiene uno o varios puntos de venta (cajas). El correlativo es por combinación, así que dos cajas de la misma sucursal llevan series separadas.
Al emitir puedes elegir desde dónde con codEstable y codPuntoVenta. Si los omites se usa el primero activo — quien tiene una sola caja no necesita saber que esto existe.
Si tu sistema tiene varias sucursales, mándalos siempre: dejar que el sistema elija hace que dos sucursales compartan correlativo y eso es un problema de auditoría, no de software.