Emitir Documento Electrónico
POST /api/v1/documento-electronico — emite cualquier tipo de documento electrónico (FE, NCE, NDE) y retorna un DTO con el CDC y URLs de seguimiento.
POST /api/v1/documento-electronico
Emite un documento electrónico y lo encola para envío a SIFEN. La respuesta es asíncrona: la API retorna inmediatamente con estado: PENDIENTE y un CDC ya calculado. El procesamiento real ocurre en segundo plano (lote → firma → envío SIFEN → resultado). Usá GET /status/:cdc o el statusUrl retornado para hacer polling del estado final.
Autenticación
Authorization: Bearer {api-key} — requerido
Idempotencia
Idempotency-Key es un header opcional de 1 a 255 caracteres ASCII visibles, sin espacios al inicio ni al final. El flujo compartido está definido en Idempotencia y Reintentos Seguros.
Idempotency-Key: 7d444840-9dc0-11d1-b245-5ffdce74fad2En emisión, el replay devuelve el mismo 202, documento, CDC, correlativo y Location; nunca reserva otro número. Si el contrato no está disponible, 503 idempotency-unavailable no crea el documento ni consume el correlativo.
Request body
El campo tipoDocumento determina el schema completo del request. Ver los modelos:
Campos comunes a todos los tipos
| Campo | Tipo | Req. | Descripción |
|---|---|---|---|
tipoDocumento | enum | Sí | Tipo de documento — ver la lista de modelos arriba |
fechaEmision | datetime | Sí | Fecha y hora de emisión (YYYY-MM-DDTHH:mm:ss) |
tipoEmision | enum | Sí | NORMAL o CONTINGENCIA |
numeroEstablecimiento | integer | Sí | Número de establecimiento (1-999) |
puntoExpedicion | integer | Sí | Punto de expedición (1-999) |
receptor | object | Sí | Datos del receptor — ver Campos del receptor |
items | array | Sí | Lista de ítems — ver Modelo Ítem |
monedaOperacion | enum | No | Moneda de la operación (ej: PYG, USD). Por defecto PYG |
descuentoGlobalPorcentaje | number | No | Porcentaje global mayor que 0 y menor o igual a 100. No se admite en Nota de Remisión |
infoEmisor | string | No | Texto libre adicional del emisor (campo SIFEN B005) |
Campos condicionales según el tipo de documento
Estos campos no aplican a todos los tipos de documento. Omitir el que corresponde a tu tipoDocumento devuelve 400 validation-error.
| Campo | Tipo | Obligatorio cuando | Descripción |
|---|---|---|---|
tipoTransaccion | enum | tipoDocumento es FACTURA_ELECTRONICA o AUTOFACTURA_ELECTRONICA | Naturaleza de la operación (VENTA_MERCADERIA, PRESTACION_SERVICIOS, …). En NCE, NDE y NRE no se informa |
condicionOperacion | enum | tipoDocumento es FACTURA_ELECTRONICA, AUTOFACTURA_ELECTRONICA o NOTA_DE_REMISION_ELECTRONICA | CONTADO o CREDITO. No aplica a NCE ni NDE |
condicionPago | object | condicionOperacion es CONTADO o CREDITO | Medio de pago o modalidad de crédito — ver Modelo Condición de Pago |
motivoEmision | enum | tipoDocumento es NOTA_DE_CREDITO_ELECTRONICA o NOTA_DE_DEBITO_ELECTRONICA | Motivo del ajuste (DEVOLUCION, DESCUENTO, AJUSTE_DE_PRECIO, …) |
documentoAsociado | object | tipoDocumento es NOTA_DE_CREDITO_ELECTRONICA o NOTA_DE_DEBITO_ELECTRONICA | El documento que se modifica. Opcional en FE (anticipos) — ver Modelo Documento Asociado |
Campos del receptor
El bloque receptor usa los mismos nombres de campo en toda operación, pero cuáles son obligatorios depende de tipoContribuyente. Schema completo en Modelo Receptor.
| Campo | Tipo | Req. | Descripción |
|---|---|---|---|
tipoContribuyente | enum | Sí | CONTRIBUYENTE (receptor con RUC) o NO_CONTRIBUYENTE. Siempre se envía |
tipoOperacion | enum | Sí | B2B, B2C, B2G, B2F |
numeroDocumento | string | Sí | RUC sin DV, cédula o pasaporte según el caso. Para el receptor innominado, el literal "0" |
nombreRazonSocial | string | Sí | Nombre o razón social. Para el receptor innominado, el literal "Sin Nombre" |
tipoContribuyenteReceptor | enum | Condicional | Obligatorio cuando tipoContribuyente = CONTRIBUYENTE. PERSONA_FISICA o PERSONA_JURIDICA (campo SIFEN D207). No se envía para NO_CONTRIBUYENTE: SIFEN lo rechaza con el código 1303 |
digitoVerificador | string | Condicional | Obligatorio cuando tipoContribuyente = CONTRIBUYENTE. Un solo dígito — el DV del RUC del receptor |
tipoDocumento | enum | Condicional | Obligatorio cuando tipoContribuyente = NO_CONTRIBUYENTE. CEDULA_PARAGUAYA, PASAPORTE, INNOMINADO, etc. No se envía para CONTRIBUYENTE |
direccion | string | Condicional | Obligatoria para tipoOperacion = B2F y para la Nota de Remisión. Opcional en el resto |
email | string | No | Si está configurado el envío automático, Sifende manda el KuDE a esta dirección |
tipoContribuyente decide tres campos a la vez, y es el motivo de rechazo más frecuente al integrar. Si el receptor es CONTRIBUYENTE, tipoContribuyenteReceptor y digitoVerificador van sí o sí, y tipoDocumento no se envía. Si es NO_CONTRIBUYENTE, es exactamente al revés. La guía Receptor B2B y B2C cubre cada caso con su ejemplo.
Respuesta exitosa
Status: 202 Accepted
La respuesta es un objeto JSON con el CDC, el estado inicial (PENDIENTE) y URLs auxiliares para seguimiento.
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"cdc": "01800123451001001000000122026042710000000006",
"estado": "PENDIENTE",
"tipoDocumento": "FACTURA_ELECTRONICA",
"iTiDe": 1,
"numeroDocumento": 1,
"numeroFormateado": "001-001-0000001",
"fechaCreacion": "2026-04-27T10:30:00",
"qrUrl": "https://ekuatia.set.gov.py/consultas-test/qr?...",
"statusUrl": "https://api.sifende.com.py/api/v1/documento-electronico/status/01800123451001001000000122026042710000000006",
"kudeUrl": "https://api.sifende.com.py/api/v1/documento-electronico/01800123451001001000000122026042710000000006/kude"
}Headers de respuesta
| Header | Valor | Descripción |
|---|---|---|
Location | {statusUrl} | URL absoluta para consultar el estado del documento |
Campos del DTO
| Campo | Tipo | Descripción |
|---|---|---|
id | uuid | Identificador público del documento en Sifende. No es una clave de idempotencia |
cdc | string(44) | Código de Control del Documento Electrónico — identificador único en SIFEN |
estado | enum | Estado inicial: siempre PENDIENTE en la respuesta de emisión |
tipoDocumento | enum | Tipo del documento creado (eco del request) |
iTiDe | integer | Código numérico SIFEN del tipo (1=FE, 5=NCE, 6=NDE) |
numeroDocumento | integer | Número correlativo asignado dentro del punto de expedición |
numeroFormateado | string | Número en formato establecimiento-puntoExpedicion-secuencia (ej: 001-001-0000001) |
fechaCreacion | datetime | Timestamp de creación del registro |
qrUrl | string | URL del QR oficial de SIFEN para el KuDE |
statusUrl | string | URL absoluta para consultar el estado |
kudeUrl | string | URL absoluta para descargar el KuDE en PDF (disponible una vez que el DE quedó registrado en SIFEN: APROBADO o APROBADO_OBSERVACION) |
El estado inicial es siempre PENDIENTE. Hacé polling a statusUrl o GET /status/:cdc cada 5–10 segundos hasta llegar a un estado terminal: APROBADO, APROBADO_OBSERVACION, RECHAZADO o ERROR. APROBADO_OBSERVACION es un resultado exitoso: el DE quedó registrado, con observaciones en mensajeRechazo. Ver Polling de resultados.
Errores comunes
| Status | Tipo | Cuándo ocurre | Acción |
|---|---|---|---|
| 400 | validation-error | Campos inválidos, faltantes o ramas de pago incompatibles | Corregí las rutas incluidas en errors y reenviá el request |
| 400 | validation-error | En CREDITO: falta condicionCredito, se mezclan PLAZO/CUOTA, no coincide cuotas con detalleCuotas, la entrega es inválida o la moneda no es PYG | Ajustá condicionPago según la referencia |
| 400 | invalid-enum-value | Valor de enumeración no reconocido | Usá un valor publicado por GET /api/v1/public/enums |
| 404 | timbrado-not-found | No hay timbrado configurado | Configurá un timbrado vigente |
| 404 | certificate-not-found | No hay certificado digital subido | Cargá el certificado del contribuyente |
| 422 | documento-electronico-generation-error | Una invariante fiscal interna impide generar el DE | Revisá el detalle y contactá soporte si el request cumple OpenAPI |
La API ejecuta la validación 400 antes de reservar la secuencia. Un payload inválido no consume numeración ni crea un registro de documento electrónico.
Ejemplos
Los dos casos de receptor que cubren la mayoría de las integraciones. Copiá el que corresponda a tu operación — lo que los diferencia es el bloque receptor.
Factura B2C — consumidor final identificado
Factura a crédito por cuotas
El siguiente body coincide con el fixture válido publicado por OpenAPI:
curl -X POST https://api.sifende.com.py/api/v1/documento-electronico \
-H "Authorization: Bearer $SIFENDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tipoDocumento": "FACTURA_ELECTRONICA",
"fechaEmision": "2026-09-18T10:30:00",
"tipoEmision": "NORMAL",
"numeroEstablecimiento": 1,
"puntoExpedicion": 1,
"tipoTransaccion": "VENTA_MERCADERIA",
"monedaOperacion": "PYG",
"receptor": {
"tipoContribuyente": "CONTRIBUYENTE",
"tipoOperacion": "B2B",
"tipoContribuyenteReceptor": "PERSONA_JURIDICA",
"numeroDocumento": "80012345",
"digitoVerificador": "7",
"nombreRazonSocial": "Comercial San Roque S.A."
},
"condicionOperacion": "CREDITO",
"condicionPago": {
"tipo": "CREDITO",
"condicionCredito": "CUOTA",
"cuotas": 3,
"detalleCuotas": [
{
"monto": 40000,
"fechaVencimiento": "2026-09-18"
},
{
"monto": 40000,
"fechaVencimiento": "2026-10-18"
},
{
"monto": 40000,
"fechaVencimiento": "2026-11-18"
}
]
},
"items": [
{
"codigo": "PROD-001",
"descripcion": "Resma de papel A4 75g",
"cantidad": 10,
"unidadMedida": "UNI",
"precioUnitario": 12000,
"afectacionTributaria": "GRAVADO",
"tasaIVA": 10
}
]
}'Para crédito a plazo, reemplazá la rama por condicionCredito: "PLAZO" y plazoCredito; no envíes cuotas ni detalleCuotas. La API sólo admite crédito en PYG por ahora.
Factura B2B — receptor contribuyente con RUC
Respecto del ejemplo anterior, en el bloque receptor: tipoContribuyente pasa a CONTRIBUYENTE y tipoOperacion a B2B, se agregan tipoContribuyenteReceptor y digitoVerificador, y se saca tipoDocumento. El numeroDocumento es el RUC sin el dígito verificador.
Próximos pasos
- Receptor B2B y B2C: cada caso de receptor con su ejemplo y los rechazos asociados.
- Consultar el estado del documento
- Modelo Receptor: schema completo del bloque
receptor.