01Qué hace Lume y qué haces tú
| Lume | Tú |
|---|---|
| Arma el XML del e-CF desde tu venta | Le pasas la venta (o tu propio XML firmado) |
| Controla la numeración eNCF | Lo firmas con el certificado del emisor |
| Valida antes de transmitir | Obtienes el token de autenticación |
| Transmite a la DGII y reintenta | Imprimes la representación impresa |
| Consulta el veredicto y reconcilia | Guardas la venta |
| Conserva el registro fiscal |
Lume nunca recibe la llave privada. Ni el .p12, ni su contraseña, ni un PIN.
No es una cortesía: custodiar certificados de terceros abre requisitos regulatorios ante INDOTEL que preferimos que ninguna de las dos partes asuma.
02Antes de escribir código
El emisor tiene que estar certificado ante la DGII con software = Lume. Sin eso no hay emisión válida, por perfecta que sea la integración. Ese proceso lo acompañamos nosotros y toma entre 7 y 18 días hábiles.
- Un contribuyente no puede estar postulado con dos proveedores a la vez. Si venía en proceso con otro sistema, hay que reiniciar.
- Iniciar la certificación con Lume no lo desconecta de su proveedor actual. Puede seguir facturando hasta que termine.
Puedes crear credenciales y desarrollar contra certecf desde el primer día. Lo que no funciona hasta que la certificación cierre es emitir en producción.
03Tu credencial
Authorization: Bearer lum_cert_...La credencial identifica a tu sistema, y está autorizada sobre una lista explícita de RNC emisores. El RNC viaja siempre explícito en cada petición; si no estás autorizado sobre él, la respuesta es 403 nombrando ambos.
Si tu sistema atiende a varios emisores, puedes indicar quién disparó la operación:
X-Lume-Actor: cliente_42/usuario_7Se guarda para auditoría. No otorga permisos.
Auto-inscripción de emisores (credenciales sistema)
Si tu credencial es de scope sistema (un SaaS que atiende a muchos emisores), puedes autorizar tus propios emisores sin intervención nuestra — ideal para altas self-service:
{ "rnc": "131123456" } → { "ok": true, "rnc": "131123456" }Es idempotente y queda auditado. La emisión real igual exige que ese RNC esté certificado ante la DGII con software = Lume; inscribir un RNC no certificado no permite emitir todavía.
04El token de DGII
Este es el paso que sorprende, así que va primero.
Transmitir a la DGII exige firmar una semilla con el certificado del emisor y cambiarla por un token de una hora. No basta con que el comprobante venga firmado: la autenticación misma necesita la llave.
Como no custodiamos certificados, ese paso lo haces tú:
# 1. Pedir la semilla
curl https://ecf.dgii.gov.do/certecf/autenticacion/api/autenticacion/semilla
# 2. Firmarla con el certificado del emisor (XML-DSig)
# 3. Cambiarla por un token
curl -X POST https://ecf.dgii.gov.do/certecf/autenticacion/api/autenticacion/validarsemilla \
-F 'xml=@semilla-firmada.xml;type=text/xml'
# → { "token": "...", "expira": "...", "expedido": "..." }{
"token": "...",
"expira": "2026-09-01T18:09:38Z",
"environment": "certecf"
}Lo cacheamos por emisor y ambiente. Renuévalo antes de que venza: sin token vigente no transmitimos — aunque el comprobante sí queda registrado y sale solo cuando entregues uno nuevo.
05Armar el XML (recomendado) o numerar tú
El eNCF va dentro del XML firmado, y la firma cubre el contenido: no se puede renumerar después. Hay dos caminos.
Opción A — Lume arma el XML desde tu venta (recomendado)
Le pasas la venta; Lume reserva el eNCF, arma el e-CF XSD-ordenado con la identidad del emisor tomada del padrón (no del payload), lo valida y te devuelve el XML sin firmar. No reimplementas la lógica fiscal de los 10 tipos.
{
"environment": "certecf",
"tipo": "31",
"rnc": "133281201",
"referencia": "POS-2026-09-01-00412",
"comprador": { "rnc": "131123456", "razonSocial": "Ferretería La Nacional" },
"items": [
{ "descripcion": "Servicio", "cantidad": 1, "precioUnitario": 1000, "indicadorFacturacion": "1" }
]
}{ "encf": "E310000001501", "tipo": "31", "xml": "<ECF>…</ECF>", "vencimiento": "31-12-2026" }indicadorFacturacion: 1=gravado 18% · 2=gravado 16% · 3=gravado 0% · 4=exento.
| Tipo | Requiere |
|---|---|
| 33, 34 (notas) | documentoModificado: ncfModificado, fechaNcfModificado, codigoModificacion (34 añade razonModificacion e indicadorNotaCredito) |
| 41, 47 (compras / exterior) | retencion en cada ítem: indicadorAgente, montoITBISRetenido, montoISRRetenido |
| 32 (consumo) | no va por aquí → usa POST /emitir-consumo |
Luego firmas ese XML (tu vault / stack) y lo emites en el paso 6.
Opción B — armas tu propio XML
Si ya generas el e-CF en tu stack, pide sólo el número:
{ "rnc": "131123456", "ecfType": "31", "environment": "certecf" }
→ { "encf": "E310000001501", "vencimiento": null }La reserva es atómica: dos llamadas concurrentes nunca obtienen el mismo número.
06Emitir
Firma el XML (de armar o propio) y envíalo:
Idempotency-Key: {tu-id-de-venta}
{
"xml": "<ECF>…</ECF>",
"kind": "ecf",
"environment": "certecf",
"referencia": "POS-2026-09-01-00412"
}{
"id": "febb8ff5-…",
"encf": "E320000000103",
"estado": "transmitido",
"track_id": "e8c09c43-…",
"codigo_seguridad": "abc123",
"qr": "https://ecf.dgii.gov.do/…"
}Es 202, no 200. Aceptamos el comprobante y la DGII decide después. Tu cajero no espera.
El Idempotency-Key es obligatorio. Reintentar con la misma clave devuelve el mismo comprobante con "idempotente": true y nunca crea un segundo. Es lo que hace seguro reintentar tras un timeout, cuando no sabes si llegamos a recibirlo.
Imprime de inmediato, no nos esperes. El codigo_seguridad son los primeros 6 caracteres del SignatureValue de tu propio XML, así que ya tienes todo para el Timbre y el QR.
07Saber qué pasó
Y para listar los de un emisor:
Acepta ambiente, estado y limite. Devuelve solo los de ese RNC; si tu credencial no está autorizada sobre él, 403. Para paginar, pasa antes_de con el creado_at del último que recibiste.
| Estado | Significa |
|---|---|
recibido | Lo tenemos y lo validamos. Todavía no salió |
transmitido | Enviado a la DGII, esperando veredicto |
aceptado | La DGII lo aceptó |
rechazado | La DGII lo rechazó. Incluye su respuesta sin traducir |
Nosotros consultamos el veredicto por ti y reconciliamos. No tienes que hacer polling contra la DGII.
08Errores
Todos verificados contra el servicio, no inventados.
| Código | Cuándo | Qué hacer |
|---|---|---|
401 | Falta la credencial o no es válida | Revisa el header Authorization |
409 | Emitir en ecf con el emisor sin certificar | Espera a certified; mientras tanto integra contra certecf |
403 | No estás autorizado sobre ese RNC | Pídenos la autorización para ese emisor |
400 | Falta Idempotency-Key | Manda tu identificador de venta |
400 | Falta el RNC o environment | Van siempre explícitos. No hay default |
400 | Falta el bloque del tipo al armar | 33/34 requieren documentoModificado; 41/47 retencion por ítem |
422 | El XML no está firmado | Fírmalo antes. Lume no firma documentos |
409 | No hay token de DGII vigente | Entrega uno. El comprobante ya quedó registrado |
502 | Error hablando con la DGII | Reintenta con la misma Idempotency-Key |
El cuerpo de los errores trae como_resolver cuando hay algo concreto que hacer.
09Ambientes
environment es obligatorio en cada petición. No hay valor por defecto, y testecf está rechazado explícitamente.
| Valor | Qué es |
|---|---|
certecf | Certificación. Aquí desarrollas y aquí se certifica cada emisor |
ecf | Producción. Comprobantes fiscales reales |
Un emisor solo puede emitir en certecf mientras su postulación está activa. Una vez que llega a Finalizado, la DGII cierra esa ventana y responde "no tiene una postulación activa".
Las pruebas de integración ocurren durante la certificación de un emisor real. Es una restricción del régimen, no una decisión nuestra.
10Lo que no está en v0
- Recepción de e-CF de terceros, ARECF y aprobación comercial
- Anulación de secuencias no utilizadas
- Webhooks — hoy se consulta con
GET /documentos/{id} - Sub-rangos por punto de emisión, para POS offline con varias cajas
Ya disponible: armar el XML desde tu venta (POST /v1/documentos/armar, sección 5) para todos los tipos estándar (31, 33, 34, 41, 43–47). El consumo final (32) va por POST /emitir-consumo.
11Referencia rápida
| Método | Ruta | Para qué |
|---|---|---|
POST | /v1/emisores/enroll | (scope sistema) auto-autorizar un RNC emisor |
POST | /v1/documentos/armar | Armar el e-CF (sin firmar) desde tu venta + reservar eNCF |
POST | /emisores/{rnc}/token | Entregar el token de DGII |
POST | /reservar-encf | Reservar el siguiente eNCF (si armas tu propio XML) |
POST | /submit | Emitir un comprobante firmado |
GET | /documentos/{id} | Estado y transiciones |
GET | /emisores/{rnc}/documentos | Listar los comprobantes de un emisor |
POST | /consulta | Consultar un trackId |
GET | /health | Estado del servicio |