TU SISTEMA + SIFE
Envía los datos.
SIFE procesa el e-CF.
Conecta tu ERP, punto de venta o aplicación. Tu sistema envía un JSON; SIFE prepara el XML, lo valida, lo firma con el certificado de tu empresa y gestiona su procesamiento fiscal.
La API requiere una credencial y habilitación específicas para tu empresa. Coordina el alta y el piloto con SIFE antes de enviar solicitudes de emisión. No se ofrece un sandbox público; los ejemplos son sintéticos.
Base de la API:
https://facturacion.digisign.do/api/v1/integrations
La primera versión procesa facturas de crédito fiscal electrónico E31. Las facturas que alcancen un resultado fiscal permitido se registran en ventas y cuentas por cobrar de SIFE. La condición «contado» no registra un cobro de dinero.
Antes de integrar
- Configura la identidad fiscal de tu empresa en SIFE.
- Carga tu certificado digital y su contraseña por la pantalla segura de SIFE. El certificado y su contraseña no se envían en cada factura ni por correo o chat.
- Completa la habilitación productiva y la configuración del rango E31. Un certificado cargado, por sí solo, no habilita la emisión.
- Solicita el alta asistida de una integración para tu empresa. Se vincula a un usuario autorizado y a sus permisos vigentes.
- Valida el JSON y realiza el piloto acordado antes de automatizar la emisión.
Para varias empresas necesitas una integración autorizada por empresa. SIFE determina el emisor, certificado, ambiente y e-NCF a partir de la credencial. Estos campos no se aceptan en el JSON.
Autenticación
Utiliza HTTPS y un token Bearer desde el servidor de tu aplicación. Guarda la credencial en tu gestor de secretos; no la incluyas en JavaScript del navegador, aplicaciones móviles, repositorios, URLs o registros.
Authorization: Bearer <credencial de tu integración>
Content-Type: application/json
Idempotency-Key: ERP-2026-000123-intento-1El alta inicial es asistida, con vigencia de 90 días. La rotación invalida el token anterior y conserva el acceso de la misma integración a sus operaciones. La revocación bloquea nuevas solicitudes y nuevos lotes del trabajador API; un lote en curso o un documento ya reservado puede continuar por su circuito fiscal.
| Permiso API | Uso |
|---|---|
| documents:validate | Consultar capacidades y validar JSON. |
| documents:write | Solicitar emisión. Requiere permisos SIFE para emitir y administrar clientes. |
| documents:read | Consultar operaciones propias. |
| artifacts:read | Descargar XML/PDF. Requiere permisos SIFE para ver facturas y exportar. |
Tu primer JSON
Ejemplo sintético para estudiar el contrato. No lo envíes como una factura real. Los importes y cantidades son cadenas decimales, sin separadores de miles.
{
"version": 1,
"external_id": "ERP-2026-000123",
"document_type": "E31",
"issue_date": "2026-10-01",
"currency": "DOP",
"income_type": "01",
"buyer": {
"tax_id": "131000002",
"legal_name": "Cliente Sintetico SRL"
},
"payment": {
"type": "cash"
},
"items": [
{
"description": "Servicio de ejemplo",
"kind": "service",
"quantity": "1",
"unit_price": "100.00",
"tax_treatment": "itbis_18"
}
],
"expected_total": "118.00"
}Descargar JSON de ejemplo ↓Campos y límites
| Campo | Regla |
|---|---|
| version / document_type | 1 (número entero) y "E31". |
| external_id | Referencia única de tu integración, de 1 a 100 caracteres: letras, números, punto, guion, guion bajo o dos puntos. Debe empezar con letra o número. |
| issue_date | AAAA-MM-DD. No admite fecha futura según República Dominicana; el período contable y el rango se revalidan al reservar. |
| currency | DOP, USD o EUR. Para USD/EUR es obligatorio exchange_rate_to_dop, positivo, hasta 3 enteros y 4 decimales. Para DOP debes omitirlo. |
| income_type | Cadena "01" a "06", según el tipo de ingreso que corresponda al documento. |
| buyer | tax_id: RNC de 9 dígitos o cédula de 11. legal_name: hasta 150 caracteres. Si el comprador ya existe en SIFE, el nombre debe coincidir exactamente. Si no existe, se crea su ficha básica. |
| payment | type: cash o credit. Para credit, due_date obligatorio, desde la fecha de emisión hasta 365 días después; terms opcional, máximo 15 caracteres. Para cash, omite due_date y terms. |
| items | De 1 a 200 líneas. description hasta 80 caracteres; kind: goods o service. quantity positiva hasta 2 decimales; unit_price no negativo hasta 4 decimales. Máximo 12 dígitos enteros por valor. |
| tax_treatment | itbis_18, zero_rated o exempt. El tratamiento fiscal lo elige el emisor según su operación. |
| discount (opcional) | Por línea: {"method":"percentage","value":"10.00"} o {"method":"fixed","value":"5.00"}. Hasta 2 decimales; no puede superar la base ni el 100 %. |
| amounts_include_itbis | Booleano opcional, por defecto false. Si todas las líneas son exentas, debe omitirse. |
| expected_total (opcional) | Total esperado con hasta 2 decimales. Se compara con el cálculo de SIFE y se rechaza si difiere. El total del documento debe ser positivo. |
Máximo 256 KiB por cuerpo JSON, 60 solicitudes por minuto por integración y 100 solicitudes pendientes de reserva. El límite por minuto incluye las consultas. No se admiten compresión, claves JSON duplicadas ni campos desconocidos.
Endpoints
Todas las rutas siguientes son relativas a la base de la API y requieren autenticación.
| Método y ruta | Resultado |
|---|---|
| GET /capabilities | Capacidades del contrato. No certifica que la empresa esté lista para emitir. |
| POST /documents/validate | Valida JSON y cálculo. Responde 200, valid=true y emission_authorized=false. No reserva número ni emite. |
| POST /documents | Registra solicitud durable. Requiere Idempotency-Key. Nueva: 202; repetición idéntica: 200. |
| GET /operations?external_id=… | Recupera la operación por tu referencia. |
| GET /operations/{operation_id} | Consulta procesamiento y resultados separados. |
| GET /operations/{operation_id}/xml | Descarga los bytes originales del XML firmado cuando estén disponibles. |
| GET /operations/{operation_id}/pdf | Descarga la representación PDF de la factura aceptada y materializada. |
Enviar y consultar
- Guarda localmente external_id, Idempotency-Key y el JSON definitivo antes de enviar.
- Opcionalmente, llama a /documents/validate para detectar errores de estructura y cálculo.
- Envía /documents y guarda operation_id y Location.
- Consulta la operación cada 5 segundos al inicio; aumenta progresivamente el intervalo hasta 60 segundos. Respeta Retry-After y el límite compartido de consultas.
- Al recibir el resultado, actualiza tu sistema y descarga los artefactos disponibles.
Respuesta de admisión (202):
{
"operation_id": "00000000-0000-4000-8000-000000000001",
"external_id": "ERP-2026-000123",
"status": "queued",
"idempotent_replay": false,
"links": {
"self": "/api/v1/integrations/operations/00000000-0000-4000-8000-000000000001"
}
}No acredita admisión por el motor, envío a DGII, aceptación fiscal ni entrega al comprador. Un TrackId tampoco demuestra aceptación.
Estados y resultados
La consulta devuelve processing, e_ncf, dgii, buyer_delivery, commercial_approval y links. No combines estas dimensiones en un único «enviado».
| processing | Interpretación y acción |
|---|---|
| queued | Solicitud guardada; todavía no hay reserva fiscal vinculada. |
| attention | No pudo reservarse; consulta error y solicita revisión. Repetir el mismo POST devuelve la misma operación, no la reabre. |
| reserved | Existe una reserva de numeración. Sigue consultando. |
| remote_unknown / polling | Resultado remoto incierto o en consulta. Conserva la operación y su número; no crees otra factura. |
| reported_used / reported_reusable | Resultado intermedio comunicado por el motor; espera una decisión terminal. Ninguno autoriza al cliente a reutilizar un número. |
| accepted / accepted_conditional | Resultado fiscal aceptado o aceptado condicional. Los artefactos pueden aparecer después de la materialización. |
| rejected_attention / identity_conflict / expired_unadmitted | Requiere revisión y resolución operativa. No reenvíes con una identidad nueva automáticamente. |
dgii contiene status, track_id, reported_code y sequence_used. Antes del resultado, status puede ser not_submitted, pending_submission o processing. buyer_delivery refleja el estado de entrega y el acuse técnico disponibles; no significa lectura humana. commercial_approval permanece en not_available en esta versión: no publica una decisión comercial.
Los enlaces xml/pdf son null hasta materializarse la factura. Una descarga puede responder 409 artifact_not_ready mientras se completa la disponibilidad del artefacto. No se ofrece un PDF fiscal definitivo para una factura pendiente o rechazada.
Errores y recuperación
{
"error": {
"code": "totals_mismatch",
"field": "expected_total",
"request_id": "00000000-0000-4000-8000-000000000002"
}
}| HTTP | Acción |
|---|---|
| 400 · invalid_json | Corrige JSON inválido o claves duplicadas. |
| 401 · invalid_credentials | Comprueba la credencial, vigencia y revocación. |
| 403 · permission_denied / company_unavailable | Revisa permisos, usuario y empresa con el administrador. |
| 404 · operation_not_found | Comprueba la referencia y que usas la misma integración. |
| 409 · idempotency_conflict | La clave o referencia ya está vinculada a otro contenido. Recupera la operación y concilia; no cambies la clave para forzar emisión. |
| 409 · artifact_not_ready | Consulta la operación y espera la disponibilidad del artefacto. |
| 409 · operation_integrity_failed | Detén esa operación y comunica request_id al soporte. |
| 413 / 415 | Reduce el JSON a 256 KiB o corrige Content-Type / Content-Encoding. |
| 422 | Corrige el campo señalado. No se admitió una operación nueva en esta respuesta. |
| 429 | Espera Retry-After: límite de peticiones o cola de admisión llena. |
| 503 | API deshabilitada o servicio no disponible. Si enviabas una factura, primero recupera su operación por external_id. |
Los rechazos del proxy o servidor web pueden devolver un cuerpo distinto de JSON. Comprueba siempre el código HTTP y Content-Type antes de interpretar la respuesta.
Ante timeout o pérdida de conexión: consulta por external_id o repite exactamente el mismo JSON y la misma Idempotency-Key. Su longitud es de 8 a 128 caracteres, con el mismo conjunto permitido para external_id. Cambiar el orden de las propiedades JSON no cambia la identidad; cambiar valores, omitir campos antes presentes o pasar de "1" a "1.00" sí la cambia.
El error de una operación attention puede ser certificate_or_connector_unavailable, company_not_ready, range_unavailable, buyer_profile_conflict, buyer_withholding_not_supported, invoice_allowance_exceeded o fiscal_preflight_failed. Resuelve la causa con soporte; el contrato inicial no tiene endpoint para reabrir operaciones. Los errores de infraestructura pueden mantener la solicitud en queued hasta recuperar el servicio. api_schema_unavailable (503) indica que falta completar la preparación técnica de la empresa; no debes cambiar de referencia para intentar emitir.
Ejemplos de código
Ejecuta estos ejemplos únicamente desde tu servidor, con un entorno y datos autorizados. Define SIFE_BASE_URL como https://facturacion.digisign.do/api/v1/integrations. SIFE_TOKEN representa una variable gestionada de forma segura; nunca publiques su valor. Guarda tu documento en factura.json antes de usar los comandos.
cURL · Validar sin emitir
curl --fail-with-body --silent --show-error \
"$SIFE_BASE_URL/documents/validate" \
-H "Authorization: Bearer $SIFE_TOKEN" \
-H "Content-Type: application/json" \
--data-binary @factura.jsonJavaScript del servidor · Solicitar y recuperar
const base = process.env.SIFE_BASE_URL;
const headers = {
Authorization: `Bearer ${process.env.SIFE_TOKEN}`,
"Content-Type": "application/json",
"Idempotency-Key": clavePersistida
};
const respuesta = await fetch(base + "/documents", {
method: "POST", headers, body: jsonPersistido
});
// Conserva clavePersistida, external_id y jsonPersistido incluso si falla la red.
const resultado = await respuesta.json();
if (![200, 202].includes(respuesta.status)) {
throw new Error(resultado.error?.code ?? "request_failed");
}
const consulta = await fetch(
base + "/operations/" + encodeURIComponent(resultado.operation_id),
{ headers: { Authorization: headers.Authorization } }
);
if (!consulta.ok) throw new Error("status_unavailable");
const estado = await consulta.json();PHP · Validar un documento
$ch = curl_init(getenv('SIFE_BASE_URL') . '/documents/validate');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('SIFE_TOKEN'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => file_get_contents('factura.json'),
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($body === false) { throw new RuntimeException('network_error'); }
curl_close($ch);
$result = json_decode($body, true, 32, JSON_THROW_ON_ERROR);
if ($status !== 200) {
throw new RuntimeException($result['error']['code'] ?? 'request_failed');
}Variantes del documento
Estos archivos son ejemplos sintéticos para validar el contrato. No representan documentos reales ni deben enviarse a emisión:
- Crédito en USD: payment.type="credit", vencimiento y tasa explícita hacia DOP. El total esperado 118.00 está expresado en USD; no es un total en pesos.
- Venta exenta: tax_treatment="exempt"; omite amounts_include_itbis. Total 100.00 DOP.
- Descuento de 10 % por línea: base 100.00, descuento 10.00, ITBIS 16.20 y total 106.20 DOP.
Si el precio ya incluye ITBIS, usa amounts_include_itbis=true: precio 118.00 con cantidad 1 e ITBIS 18 % conserva un total de 118.00. No sumes documentos de distintas monedas para conciliar balances.
Ejemplo de estado aceptado
Respuesta ilustrativa; los identificadores fiscales son sintéticos. La aceptación fiscal y la entrega técnica se consultan por separado:
{
"operation_id": "00000000-0000-4000-8000-000000000001",
"external_id": "ERP-2026-000123",
"environment": "production",
"document_type": "E31",
"processing": "accepted",
"error": null,
"e_ncf": "E310000000001",
"state_version": 4,
"created_at": "2026-10-04T19:00:00.000000Z",
"dgii": {
"status": "accepted", "track_id": "ejemplo-sintetico",
"reported_code": 1, "sequence_used": true
},
"buyer_delivery": { "status": "not_available", "acknowledgement": null },
"commercial_approval": { "status": "not_available" },
"links": {
"self": "/api/v1/integrations/operations/00000000-0000-4000-8000-000000000001",
"xml": "/api/v1/integrations/operations/00000000-0000-4000-8000-000000000001/xml",
"pdf": "/api/v1/integrations/operations/00000000-0000-4000-8000-000000000001/pdf"
}
}Conserva el último estado y su state_version cuando esté disponible. Descargar el XML no lo vuelve a firmar ni provoca otro envío fiscal. Si tu aplicación perdió el resultado del POST, recupera primero:
curl --fail-with-body --silent --show-error --get \
"$SIFE_BASE_URL/operations" \
-H "Authorization: Bearer $SIFE_TOKEN" \
--data-urlencode "external_id=ERP-2026-000123"Validación del primer sistema cliente
- Revisa el documento de tu sistema contra OpenAPI y los límites publicados.
- Configura la credencial en el servidor y comprueba /capabilities.
- Valida estructura y cálculo con /documents/validate. Eso no es una prueba fiscal ni valida el certificado contra DGII.
- Acuerda con SIFE un documento real y su autorización para el piloto. Conserva su referencia, clave y JSON antes de enviarlo.
- Envía una sola solicitud y consulta la misma operación hasta obtener el resultado o una instrucción de revisión.
- Verifica el número, importes, moneda y los artefactos. Distingue aceptación DGII, entrega al comprador y aceptación comercial.
- Comprueba recuperación de conexión sin crear otro documento, y define alertas para operaciones pendientes o que requieren atención.
No existe un plazo de respuesta garantizado de DGII en este contrato. Si una operación permanece pendiente, conserva sus identificadores y solicita soporte; no cambies la clave ni el número para forzar otra emisión.
Alcance de esta versión
- E31, DOP/USD/EUR, contado/crédito, bienes/servicios, ITBIS 18 %, tasa cero, exentos y descuentos por línea.
- Consulta periódica de resultados. Webhooks, feed de eventos y otros tipos e-CF quedan para fases posteriores.
- No admite retenciones ni clientes con perfiles de retención activos, recargos, descuentos globales, XML ya firmado o numeración elegida por el cliente.
- No incluye endpoints de cobros, cancelación, reenvío fiscal, envío de correo ni gestión de certificados. Los circuitos de entrega existentes de SIFE siguen su configuración.
- Conserva los controles de suscripción y cupo de la empresa; esta API no autoriza cargos por exceso. Condiciones comerciales de la integración sujetas al alta acordada.
Para iniciar la integración: contacta al equipo de SIFE. Comparte la versión del contrato, el código de error y request_id; no compartas credenciales ni certificados.