API de facturación electrónica
URL base https://e-cf.com.do/api/public/v1. Todas las respuestas son JSON.
Autenticación
Genere una API Key en su portal (Integración). Envíela en cada petición:
Authorization: Bearer ecf_live_xxxxxxxxxxxxxxxx # o bien X-API-Key: ecf_live_xxxxxxxxxxxxxxxx
Las llaves ecf_test_ trabajan contra pre-certificación o certificación; ecf_live_ contra producción.
Pruebas de integración sin DGII
Genere una clave ecf_sandbox_ en la pestaña Pruebas de integración. Use la URL https://e-cf.com.do/api/public/sandbox/v1, no la URL fiscal. Las claves de pruebas no funcionan en la API fiscal y las fiscales no funcionan aquí.
curl -X POST https://e-cf.com.do/api/public/sandbox/v1/ecf \
-H "Authorization: Bearer $SANDBOX_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: PRUEBA-001" \
-d '{"tipo":32,"items":[{"nombre":"Prueba","cantidad":1,"precioUnitario":1000,"itbis":18}]}'Datos válidos: HTTP 201 y ACEPTADO. Datos inválidos: HTTP 422 y RECHAZADO con validacion.errores por campo. Un reintento con la misma clave devuelve la prueba original (HTTP 200); si cambia el JSON, HTTP 409.
GET /ecf lista las pruebas; GET /ecf/{id} recupera el resultado; GET /ecf/{id}/xml descarga una vista sin firma, con e-NCF cero como marcador. El identificador es SIM-…, no un e-NCF fiscal.
Siempre devuelve simulado: true, enviadoDGII: false y validezFiscal: false. No usa certificados, secuencias, QR, webhooks reales ni conexión DGII. Valida JSON, campos requeridos, fechas, descuentos y cálculos locales; no valida XSD ni garantiza aceptación de la DGII. Certificación y producción continúan en la API fiscal.
Emitir e-CF
POST /ecf — Nosotros asignamos el e-NCF, generamos el XML oficial, lo firmamos y lo enviamos a la DGII. Use Idempotency-Key para que un reintento no cree una factura duplicada.
curl -X POST https://e-cf.com.do/api/public/v1/ecf \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: FAC-1001" \
-d '{
"tipo": 31,
"fechaEmision": "2026-10-22",
"tipoPago": 1,
"comprador": { "rnc": "101000000", "razonSocial": "CLIENTE SRL" },
"items": [
{ "nombre": "Servicio de consultoría", "cantidad": 10,
"precioUnitario": 1500.50, "itbis": 18, "esServicio": true },
{ "nombre": "Libro", "cantidad": 2, "precioUnitario": 850, "itbis": 0 }
]
}'| Campo | Descripción |
|---|---|
| tipo | 31, 32, 33, 34, 41, 43, 44, 45, 46, 47 |
| tipoPago | 1 contado · 2 crédito (requiere fechaLimitePago) · 3 gratuito |
| comprador.rnc | Obligatorio en 31, 41 y 45 |
| referencia | Notas 33/34: { ncfModificado, fechaNcfModificado, codigoModificacion } |
| items[].precioUnitario | Hasta 4 decimales; montos se redondean a 2 |
| items[].itbis | 18, 16 o 0 (exento) |
Las facturas de consumo (32) menores a RD$250,000 se envían como resumen (RFCE) y reciben respuesta inmediata. Las demás quedan EN_PROCESO con un TrackId.
HTTP/1.1 201 Created
{
"id": "2e1b...",
"encf": "E310000000001",
"status": "EN_PROCESO",
"trackId": "90442598-e9e4-...",
"montoTotal": 19405.9,
"codigoSeguridad": "0lyqgX",
"fechaFirma": "22-10-2026 15:13:54",
"qrUrl": "https://ecf.dgii.gov.do/ecf/ConsultaTimbre?RncEmisor=...",
"links": { "self": ".../ecf/2e1b...", "xml": ".../ecf/2e1b.../xml" }
}Consultar
GET /ecf— lista (?status=ACEPTADO&limit=50)GET /ecf/{id | eNCF}— estado; si está en proceso consultamos la DGII en ese momentoGET /ecf/{id}/xml— XML firmadoPOST /ecf/{id}— reintenta el envío si quedó enERROR_ENVIOGET /recibidos— e-CF recibidos de sus suplidores
Estados
FIRMADO → EN_PROCESO → ACEPTADO | ACEPTADO_CONDICIONAL | RECHAZADO. Si no pudimos comunicarnos con la DGII: ERROR_ENVIO (el e-NCF se conserva, reintente).
Si un RFCE es rechazado con secuenciaUtilizada: true, ese e-NCF ya no puede usarse: emita uno nuevo.
Webhook
Configure su URL en el portal. Cuando el estado sea final enviamos:
POST https://su-erp.com/webhooks/ecf
X-ECF-Signature: hex(HMAC-SHA256(secreto, cuerpo))
{ "event": "ecf.status", "data": { ...mismo formato que GET /ecf/{id} } }Anulación de secuencias
POST https://e-cf.com.do/api/public/v1/anulaciones
{ "rangos": [ { "tipo": 31, "desde": "E310000000500", "hasta": "E310000000510" } ] }Aprobación comercial
Apruebe (1) o rechace (2) un e-CF recibido de un suplidor:
POST https://e-cf.com.do/api/public/v1/aprobaciones
{ "rncEmisor": "131880681", "encf": "E310000000099",
"fechaEmision": "2026-10-22", "montoTotal": 1180, "estado": 1 }URLs de receptor
Regístrelas en la Oficina Virtual de la DGII. Reemplace {RNC} por el suyo:
GET https://e-cf.com.do/api/public/fe/{RNC}/semilla
POST https://e-cf.com.do/api/public/fe/{RNC}/validacioncertificado
POST https://e-cf.com.do/api/public/fe/{RNC}/recepcion -> responde ARECF firmado
POST https://e-cf.com.do/api/public/fe/{RNC}/aprobacioncomercialErrores
| 401 | API Key ausente, inválida o revocada |
| 404 | Comprobante no encontrado |
| 409 | Sin certificado o sin secuencias disponibles |
| 422 | Datos inválidos — revise detalles |
| 502 | La DGII respondió con error — revise detalle |