Documentación de la API
La API de EdFactura es REST sobre HTTPS. Todas las respuestas son JSON en UTF-8, con el mismo formato, y las fechas usan ISO 8601 (AAAA-MM-DD).
- Cree una cuenta gratis (su solicitud se aprueba en breve).
- En el panel, vaya a API keys y genere una llave. Guárdela: se muestra una sola vez.
- Envíela en la cabecera
X-API-Keyen cada petición.
curl "https://api.edfactura.com/v1/rnc/{rnc}" \
-H "X-API-Key: SU_API_KEY"
Autenticación
Cada petición debe incluir su API key en una de estas cabeceras:
X-API-Key: edf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # o bien Authorization: Bearer edf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
La llave no se acepta en la URL (?api_key=): quedaría guardada en historiales, bitácoras de servidores y proxies.
Buenas prácticas
- Guarde la llave en una variable de entorno o en un gestor de secretos, nunca en el código fuente ni en un repositorio.
- Use una llave por sistema o entorno (producción, pruebas) para poder revocarlas por separado.
- Asigne solo los permisos que el sistema necesita y una fecha de expiración cuando sea posible.
- Si su servidor tiene IP fija, agréguela en IPs permitidas.
Uso desde el navegador (CORS)
Por seguridad, una llave solo funciona desde un navegador si el dominio de la página está en sus Orígenes permitidos (admite comodín: *.midominio.com). Aun así, cualquier visitante podría ver la llave en el código de la página: prefiera llamar a la API desde su servidor.
Sandbox y producción
Hay dos tipos de llave. La URL es la misma: el ambiente lo determina la llave.
| Ambiente | Prefijo | Datos | Cuota mensual |
|---|---|---|---|
| Sandbox | edf_test_… | Datos de prueba fijos (en la página de cada módulo). No consulta a la DGII. | No consume |
| Producción | edf_live_… | Datos reales: padrón y servicios públicos de la DGII. | Consume (solo respuestas 2xx) |
Cada respuesta indica el ambiente en meta.ambiente y en la cabecera X-API-Environment. Ambas llaves respetan el límite por minuto del plan. Integre y pruebe todos los casos (incluidos los errores) en sandbox; cambie a la llave de producción al desplegar.
Formato de respuesta
Toda respuesta tiene success. Si es true, los datos están en data; si es false, el detalle está en error. Programe contra error.code (estable), no contra el texto de error.message (puede cambiar).
{
"success": true,
"data": { "...": "..." },
"meta": {
"request_id": "9f1c2a7b3e4d5f60",
"timestamp": "2026-09-25T10:15:00-04:00"
}
}
{
"success": false,
"error": {
"code": "rnc_not_found",
"message": "El RNC 101000000 no está registrado en la DGII."
},
"meta": { "request_id": "c41d09e2a7b3f851", "...": "..." }
}
Cada respuesta incluye la cabecera X-Request-Id, igual a meta.request_id. Inclúyala al reportar un problema.
Errores
| error.code | HTTP | Significado |
|---|---|---|
| missing_api_key | 401 | No se envió la cabecera X-API-Key. |
| invalid_api_key | 401 | La llave no existe, está mal escrita o fue revocada. |
| expired_api_key | 401 | La llave pasó su fecha de expiración. |
| account_suspended | 403 | La cuenta dueña de la llave está suspendida. |
| ip_not_allowed | 403 | La llave tiene IPs permitidas y la petición vino de otra. |
| origin_not_allowed | 403 | Llamada desde navegador sin el dominio en "Orígenes permitidos". |
| insufficient_scope | 403 | La llave no tiene el permiso del módulo. |
| module_not_in_plan | 403 | El plan de la cuenta no incluye ese módulo. |
| not_found | 404 | El endpoint no existe. |
| rnc_not_found | 404 | Producción: el RNC o cédula no figura en el padrón de la DGII (se indica la fecha del archivo). Sandbox: no está en los datos de prueba (no se consultó la DGII); ver error.details.fuente. |
| method_not_allowed | 405 | Método HTTP no soportado en esa ruta (ver cabecera Allow). |
| version_retired | 410 | La versión de la API usada fue retirada. Migre a la versión vigente. |
| invalid_rnc · invalid_query · invalid_filter · invalid_ncf · invalid_encf · invalid_security_code · invalid_qr_url | 422 | Parámetros con formato inválido. El mensaje indica cómo corregirlo. |
| rate_limited | 429 | Superó el límite por minuto. Espere los segundos de Retry-After. |
| quota_exceeded | 429 | Consumió la cuota mensual de su plan. |
| sandbox_limit | 429 | Llegó al tope diario de peticiones del sandbox (llaves edf_test_). |
| internal_error | 500 | Error inesperado. Reporte el request_id a soporte. |
| dgii_unexpected | 502 | La DGII respondió en un formato que no pudimos interpretar. |
| dgii_unavailable | 503 | El servicio de la DGII no respondió. Reintente más tarde. |
| dgii_busy | 503 | Muchas consultas en curso hacia la DGII. Espere los segundos de Retry-After. |
Límites y cuotas
Hay dos límites: peticiones por minuto (por cuenta y ambiente: todas sus llaves suman) y consultas por mes (por cuenta). Solo las respuestas exitosas (2xx) consumen la cuota mensual. Cada respuesta informa el estado del límite por minuto:
| Cabecera | Descripción |
|---|---|
| X-RateLimit-Limit | Peticiones permitidas por minuto. |
| X-RateLimit-Remaining | Peticiones restantes en el minuto actual. |
| X-RateLimit-Reset | Momento (Unix) en que se reinicia el contador. |
| Retry-After | Solo en 429 por límite: segundos a esperar. |
| Plan | Consultas / mes | Peticiones / minuto | API keys | Subusuarios |
|---|---|---|---|---|
| Pro | 50,000 | 120 | 10 | Ilimitados |
| Empresarial | Ilimitadas | 600 | 50 | Ilimitados |
| Personalizado | A medida: se acuerdan con cada cliente | |||
Módulos
Cada módulo tiene su página, con sus endpoints.
Estado del servicio
Endpoint público para monitoreo. Responde 200 si el servicio está operativo, o 503 si hay degradación.
{ "success": true, "data": { "status": "ok" }, "meta": { "request_id": "…", "timestamp": "…" } }
Versionado
La versión va en la ruta (/v1) y cada respuesta la informa en la cabecera X-API-Version. Dentro de una versión solo se hacen cambios compatibles: endpoints nuevos, parámetros opcionales o campos nuevos en las respuestas. Su integración debe ignorar los campos que no conozca.
Los cambios incompatibles se publican como una versión nueva (/v2) que convive al menos 12 meses con la anterior. Cuando una versión se declara obsoleta, sus respuestas incluyen las cabeceras estándar Deprecation y Sunset (fecha de retiro); después de esa fecha responde 410 version_retired.
| Versión | Estado | Publicada | Retiro |
|---|---|---|---|
| v1 | Vigente | 2026-09-25 | — |