# Introducción (/docs) ## ¿Qué es Sifende? [#qué-es-sifende] Sifende es una plataforma que permite a empresas o personas emitir, gestionar y consultar documentos electrónicos (DEs) a través del sistema SIFEN de la DNIT, sin tener que implementar la infraestructura de integración por su cuenta. Con Sifende podés: * Emitir Facturas Electrónicas (FE), Notas de Crédito (NCE), Notas de Débito (NDE) y Notas de Remisión (NRE) * Consultar el estado de procesamiento en tiempo real * Descargar KuDE en PDF y XML firmado * Enviar comprobantes a tus clientes por email * Gestionar cancelaciones e inutilizaciones de numeración ## ¿Por dónde empezar? [#por-dónde-empezar] ## Para LLMs y agentes [#para-llms-y-agentes] Esta documentación está disponible en formatos optimizados para contexto: | Recurso | URL | Contenido | | ------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Índice (`llms.txt`) | [`/llms.txt`](/llms.txt) | Lista de todas las páginas con título y descripción; sirve como punto de entrada | | Contenido completo | [`/llms-full.txt`](/llms-full.txt) | Todas las páginas concatenadas en texto plano para contexto total | | Página individual | `/llms.mdx/docs/[slug]/content.md` | Cualquier página como Markdown limpio, p.ej. [`/llms.mdx/docs/referencia/documentos-electronicos/emitir/content.md`](/llms.mdx/docs/referencia/documentos-electronicos/emitir/content.md) | # Ambientes (/docs/conceptos/ambientes) La **API key determina el ambiente** de la operación. Los tres usan la misma URL base, `https://api.sifende.com.py`. | Aspecto | Sandbox de Sifende | Pruebas con SIFEN | Producción | | ------------------------ | ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | | Prefijo de claves nuevas | `sk_sandbox_` | `sk_test_` | `sk_live_` | | Opción al crearla | **SANDBOX — Simulador de Sifende** | **DEV — Pruebas con SIFEN** | **PROD — Documentos con validez fiscal** | | Envío a SIFEN | No se envían documentos | Ambiente de pruebas | Ambiente de producción | | Validez fiscal | Sin validez fiscal | Sin validez fiscal | Los documentos tienen efecto fiscal | | Timbrado y CSC | Sifende proporciona los valores de prueba | Cargá los valores del ambiente de pruebas | Cargá los valores de producción de la SET | Las claves antiguas conservan su valor y el ambiente al que quedaron vinculadas. No deduzcas su ambiente por el prefijo: consultalo en el panel. Rotar una clave conserva su ambiente. El certificado activo del contribuyente sirve para los tres ambientes. El timbrado y el CSC de DEV y PROD se configuran por separado. Cada ambiente conserva su propia numeración; las emisiones de DEV y SANDBOX no consumen ni reservan cupo de producción. ## Sandbox de Sifende [#sandbox-de-sifende] Usá una clave `sk_sandbox_` para probar emisión, consultas, descarga de KuDE y recepción de notificaciones sin enviar documentos a SIFEN. Necesitás un certificado activo, la dirección del emisor y al menos una actividad económica configurada. No tenés que cargar un timbrado ni un CSC para SANDBOX; los datos de la solicitud siguen sujetos a validación. La emisión devuelve `202 Accepted` con `estado: "PENDIENTE"`. Después, la consulta de estado muestra `APROBADO` con `protocoloAutorizacion` formado por `SBX-` seguido del CDC. Es una aprobación de prueba de Sifende: no proviene de SIFEN ni otorga validez fiscal. El KuDE lleva el rótulo **SANDBOX — SIN VALIDEZ FISCAL**. Para encontrar estos documentos en el panel, elegí **Sandbox** en el [filtro de ambiente](/docs/panel/documentos). Los correos y webhooks sí se entregan: usá una dirección de prueba en `receptor.email`. Para recibir `documento.aprobado`, configurá un [endpoint de webhooks](/docs/panel/webhooks) en **Sandbox**. Las notificaciones nuevas incluyen `ambiente: "SANDBOX"` y se entregan únicamente a los endpoints de ese ambiente. SANDBOX no admite cancelación, inutilización ni nominación: responde [`422 sandbox-operation-not-supported`](/docs/solucion-problemas/sandbox-operation-not-supported). Usá DEV para probar eventos y rechazos de SIFEN. Una aprobación en SANDBOX no comprueba que SIFEN vaya a aceptar el documento. ## Probar la integración [#probar-la-integración] Creá una clave `sk_test_` para enviar documentos al ambiente de pruebas de SIFEN, consultar resultados, descargar KuDE y probar rechazos. Los datos del ambiente de pruebas de SIFEN pueden diferir de los de producción; consultá [Rechazos comunes](/docs/solucion-problemas/rechazos-comunes#ambiente-prueba). ## Pasar a producción [#pasar-a-producción] 1. Verificá que el contribuyente esté habilitado para producción. 2. Cargá su [timbrado de producción](/docs/panel/timbrado) vigente y su [CSC de producción](/docs/panel/certificado-y-csc). Verificá que el certificado siga activo. 3. Creá una API key para **PROD — Documentos con validez fiscal**. Si falta un requisito, el panel indica qué completar. 4. Reemplazá la variable de entorno de tu integración por la nueva clave `sk_live_`. La URL base y el código de integración se mantienen. Las claves `sk_test_` existentes siguen siendo de pruebas. ## Mantener los ambientes separados [#mantener-los-ambientes-separados] Usá variables distintas, como `SIFENDE_API_KEY_TEST` y `SIFENDE_API_KEY_PROD`. Las respuestas de emisión y consulta de estado incluyen `ambiente`: `DEV`, `PROD` o `SANDBOX`. Guardá ese valor junto con el CDC y mostrá una indicación visible cuando tu sistema esté en pruebas. El ambiente de un documento no cambia al pasar el contribuyente a producción. Tampoco cambian de ambiente los eventos, reintentos, claves de idempotencia ni entregas de webhooks existentes. Para el checklist completo, consultá [Ir a producción](/docs/guias/ir-a-produccion). # Autenticación (/docs/conceptos/autenticacion) La API de integración usa una **API key** asociada a un contribuyente y a un ambiente. Enviá la clave completa en cada solicitud: ```http Authorization: Bearer sk_test_... ``` ## Elegir el ambiente [#elegir-el-ambiente] Las claves nuevas usan estos prefijos: * `sk_sandbox_`: permite pruebas en Sifende, sin envío a SIFEN ni validez fiscal. * `sk_test_`: envía al ambiente de pruebas de SIFEN, sin validez fiscal. * `sk_live_`: envía a producción. Todas usan `https://api.sifende.com.py`. El ambiente queda fijo al crear la clave; seleccioná el adecuado en **API Keys → Crear API Key**. Las claves antiguas conservan su ambiente aunque su prefijo no coincida; verificalo en el panel. Consultá [Ambientes](/docs/conceptos/ambientes). ## Ciclo de vida [#ciclo-de-vida] | Acción | Efecto | | -------- | ----------------------------------------------------------------------- | | Crear | La clave completa se muestra una sola vez; podés definir su expiración | | Rotar | Se genera una nueva clave y la anterior deja de funcionar al instante | | Eliminar | Se revoca el acceso de inmediato | | Vencer | La clave deja de aceptar solicitudes al llegar a la fecha de expiración | Para cambiar de clave sin interrumpir la integración, **creá otra**, configurala en tu sistema, verificá que funcione y eliminá la anterior. Mirá los pasos en [API keys del panel](/docs/panel/api-keys). ## Guardar la clave [#guardar-la-clave] Usá una variable de entorno o un gestor de secretos. La clave debe quedarse en tu servidor: no la incluyas en una página web, una app distribuida, registros de actividad o repositorios. Si se expuso, revocala y reemplazala. Como práctica de seguridad, planificá reemplazar la API key cada **90 días**. Es una recomendación para tu integración, no un vencimiento automático de Sifende. Seguí el [procedimiento de cambio sin interrupciones](/docs/panel/api-keys#cambiar-de-clave-sin-interrumpir-la-integración). ## Errores [#errores] | Status | Significado | | ------ | ----------------------------------------------------------------------------- | | `401` | Falta la clave, es inválida, venció o fue revocada | | `403` | La solicitud no tiene permiso para acceder al recurso o realizar la operación | Consultá [Autenticación de la API](/docs/referencia/autenticacion) para ver el formato de las respuestas. # CDC (Código de Control) (/docs/conceptos/cdc) El **CDC** (Código de Control) es el identificador único de un documento electrónico ante SIFEN. Tiene 44 caracteres numéricos y lleva toda la información esencial del documento codificada en su estructura. Es el dato más importante a guardar después de emitir. ## Qué es el CDC [#qué-es-el-cdc] ``` 01800123451001001000000122026042710000000006 ``` Cada documento electrónico tiene un único CDC, irrepetible. Lo genera Sifende al emitir y SIFEN lo valida. Es el código que aparece en el QR del KuDE y permite consultar el documento en e-kuatia. ## Estructura del CDC (44 dígitos) [#estructura-del-cdc-44-dígitos] El CDC se arma concatenando 11 campos en este orden: | Pos. | Largo | Campo | Descripción | | ----- | ----- | -------------------------- | ----------------------------------------------------------------------- | | 1–2 | 2 | Tipo de documento | `01` = FE, `04` = AFE, `05` = NCE, `06` = NDE, `07` = NRE | | 3–10 | 8 | RUC del emisor | Sin DV, padded con ceros a izquierda — ej. `80012345` | | 11 | 1 | DV del emisor | Dígito verificador del RUC del emisor | | 12–14 | 3 | Establecimiento | Número de sucursal (`001`–`999`) | | 15–17 | 3 | Punto de expedición | Caja/terminal dentro del establecimiento | | 18–24 | 7 | Número del documento | Secuencial por ambiente, tipo de documento, establecimiento y punto | | 25 | 1 | Tipo de contribuyente | `1` = persona física, `2` = persona jurídica | | 26–33 | 8 | Fecha de emisión | `AAAAMMDD` — ej. `20260427` | | 34 | 1 | Tipo de emisión | `1` = normal. El `2` (contingencia) todavía no está habilitado en SIFEN | | 35–43 | 9 | Código de seguridad | Aleatorio, 9 dígitos, generado por Sifende | | 44 | 1 | Dígito verificador del CDC | Calculado con módulo 11 sobre los 43 dígitos previos | Total: 2 + 8 + 1 + 3 + 3 + 7 + 1 + 8 + 1 + 9 + 1 = 44 caracteres. El tipo de contribuyente del emisor (posición 25) es parte del CDC y no hay que confundirlo con `numeroTimbrado`, que no aparece en el CDC. El timbrado se referencia indirectamente a través de la combinación `establecimiento + puntoExpedicion + numeroDocumento`. ## Ejemplo desglosado [#ejemplo-desglosado] Tomando el CDC `01800123451001001000000122026042710000000006`: ``` 01 80012345 1 001 001 0000001 2 20260427 1 000000000 6 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ DV módulo 11 del CDC │ │ │ │ │ │ │ │ │ └─ Código de seguridad (9 dígitos) │ │ │ │ │ │ │ │ └─ Tipo emisión: 1 = normal │ │ │ │ │ │ │ └─ Fecha 2026-04-27 │ │ │ │ │ │ └─ Tipo contribuyente: 2 = persona jurídica │ │ │ │ │ └─ Documento N° 0000001 │ │ │ │ └─ Punto expedición 001 │ │ │ └─ Establecimiento 001 │ │ └─ DV del RUC emisor (1) │ └─ RUC del emisor (sin DV) — 80012345 └─ Tipo: 01 = Factura Electrónica ``` ## Representación visual en el KuDE [#representación-visual-en-el-kude] En la representación gráfica del documento, el CDC se muestra en grupos de 4 dígitos para que sea más fácil de leer: ``` 0180 0123 4510 0100 1000 0001 2202 6042 7100 0000 0006 ``` ## Cómo se genera [#cómo-se-genera] Sifende genera el CDC con los datos del emisor, del documento y su numeración. Lo recibís en la respuesta de emisión; no tenés que calcularlo ni enviarlo. ## Cómo usar el CDC [#cómo-usar-el-cdc] El CDC es la clave primaria de tu documento ante SIFEN. Lo necesitás para: * Consultar estado: `GET /api/v1/documento-electronico/status/:cdc` * Descargar el KuDE: `GET /api/v1/documento-electronico/:cdc/kude` * Cancelar el documento: `POST /api/v1/documento-electronico/:cdc/cancelar` * Asociarlo en una NCE/NDE: el campo `documentoAsociado.cdc` referencia la FE original. * Consulta pública en e-kuatia: cualquier persona con el CDC puede verificar el documento en `https://ekuatia.set.gov.py/consultas/`. Guardá el CDC en tu sistema apenas Sifende lo retorne. Es el único dato que te permite operar sobre el documento después. Sin CDC no podés consultar, cancelar ni descargar el KuDE. ## CDC e idempotencia [#cdc-e-idempotencia] El CDC identifica al documento electrónico; no identifica la intención de emitirlo. La `Idempotency-Key` existe antes que el documento y es distinta del `id`, `deId`, CDC o ID de evento que la API devuelve después. Para recuperar una emisión, aplicá [Idempotencia y Reintentos Seguros](/docs/guias/idempotencia). ## Inmutabilidad [#inmutabilidad] Una vez generado, el CDC no se puede modificar. Si corregís y volvés a emitir un documento rechazado, Sifende asigna siempre un número nuevo y un CDC nuevo. El número rechazado queda libre y se puede [inutilizar](/docs/guias/inutilizar-numeracion). ## Próximos pasos [#próximos-pasos] * [Convenciones — CDC](/docs/referencia/convenciones): el formato exacto en la API. * [Timbrado y Numeración](/docs/conceptos/timbrado-numeracion): qué partes del CDC dependen del timbrado. * [Documentos Asociados](/docs/referencia/modelos/documento-asociado): cómo referenciar un CDC en NCE/NDE. # Ciclo de Vida de un Documento (/docs/conceptos/ciclo-de-vida) La emisión es asíncrona: una respuesta `202 Accepted` confirma que Sifende recibió el documento. Guardá su CDC para consultar el resultado. Sifende agrupa los documentos en [lotes](/docs/conceptos/lotes) para enviarlos a SIFEN. En [SANDBOX](/docs/conceptos/ambientes#sandbox-de-sifende), la consulta puede pasar de `PENDIENTE` a `APROBADO` sin envío a SIFEN. El protocolo es `SBX-` seguido del CDC y no tiene validez fiscal. Los estados de envío y respuestas de SIFEN de esta tabla corresponden a DEV y PROD. ## Estados del documento [#estados-del-documento] | Estado | Qué significa | Qué hacer | | ---------------------- | -------------------------------------------------------- | ------------------------------------------------------------------ | | `PENDIENTE` | Sifende recibió el documento y está preparando su envío | Seguí consultando | | `EN_LOTE` | En proceso de envío o a la espera del resultado de SIFEN | Seguí consultando | | `APROBADO` | SIFEN aceptó el documento | Detené las consultas; guardá el protocolo | | `APROBADO_OBSERVACION` | SIFEN aceptó el documento con observaciones | Detené las consultas y revisá `mensajeRechazo`; no lo reemitas | | `RECHAZADO` | SIFEN rechazó el documento | Detené las consultas y corregí el motivo antes de emitir uno nuevo | | `CANCELADO` | Se confirmó la cancelación de un documento aprobado | Detené las consultas | | `ERROR` | El envío falló de forma definitiva | Detené las consultas y revisá el panel; no lo reemitas | En `ERROR`, el documento no se reintenta solo. Pedí el reintento a [soporte](/docs/solucion-problemas/soporte) o seguí la [guía para reintentar el lote](/docs/panel/lotes). Al reintentarlo vuelve a `EN_LOTE` y podés retomar las consultas con el mismo CDC. Si después de varias horas sigue en `EN_LOTE`, puede pertenecer a un lote **Fallido**. Revisá **Historial de Lotes** en el detalle del documento y, si el lote está **Fallido**, seguí la [guía de reintento](/docs/panel/lotes). Conservá el mismo CDC. ## Recorrido habitual [#recorrido-habitual] ```text ┌─────────────┐ POST ──────► │ PENDIENTE │ └──────┬──────┘ │ Sifende prepara el envío ▼ ┌─────────────┐ │ EN_LOTE │ ◄───────────────────────┐ └──────┬──────┘ │ │ SIFEN procesa el documento │ ┌─────────────────┼─────────────────┐ │ Reintento desde ▼ ▼ ▼ │ el panel o soporte ┌─────────────┐ ┌───────────┐ ┌───────────┐ │ │ APROBADO │ │ RECHAZADO │ │ ERROR │────────┘ │ o │ └───────────┘ └───────────┘ │ APROBADO_ │ (final) │ OBSERVACION │ └──────┬──────┘ │ Cancelación dentro del plazo ▼ ┌─────────────┐ │ CANCELADO │ └─────────────┘ ``` Los errores transitorios se reintentan automáticamente antes de llegar a `ERROR`. Ese estado requiere una acción para continuar. ## Tiempos y consultas [#tiempos-y-consultas] El resultado puede tardar segundos o minutos; SIFEN puede demorar más. Consultá cada 5 segundos durante un máximo de 5 minutos. Si venció ese tiempo y el documento sigue en proceso, conservá el CDC y retomá la consulta después. El fin de la espera no significa que el documento haya sido rechazado. Usá [consultas de estado](/docs/guias/consultar-estado) o [webhooks](/docs/referencia/webhooks). El panel también muestra el estado del documento. ## Rechazos y observaciones [#rechazos-y-observaciones] En `RECHAZADO`, revisá `mensajeRechazo`, corregí los datos y [emití un nuevo documento](/docs/guias/reintentar-rechazados). Sifende asigna un número y un CDC nuevos. El número del rechazado queda libre y se puede inutilizar. En `APROBADO_OBSERVACION`, el documento quedó aceptado: guardá las observaciones para revisarlas y no lo reemitas. # Cómo Funciona Sifende (/docs/conceptos/como-funciona) Sifende conecta tu sistema con SIFEN. Enviás los datos comerciales en JSON y recibís el CDC para seguir el resultado del documento. ## Arquitectura general [#arquitectura-general] ## Flujo de un documento [#flujo-de-un-documento] 1. Tu sistema envía `POST /api/v1/documento-electronico` con una [API key](/docs/conceptos/autenticacion). 2. Sifende valida los datos y asigna un número y un CDC al documento. La respuesta `202 Accepted` incluye las URLs para consultar el estado y descargar el KuDE. 3. Sifende firma el XML con tu certificado según el Manual Técnico de SIFEN. Sifende agrupa los documentos para enviarlos a SIFEN. 4. Consultás el estado o recibís un [webhook](/docs/referencia/webhooks) con el resultado. 5. Cuando el documento está `APROBADO` o `APROBADO_OBSERVACION`, descargás su KuDE. La aceptación de la solicitud por Sifende no equivale a la aprobación de SIFEN. Guardá el CDC y consultá el [ciclo de vida](/docs/conceptos/ciclo-de-vida) para decidir cuándo seguir esperando, corregir el documento o pedir un reintento. ## Qué hace Sifende por vos [#qué-hace-sifende-por-vos] | Sifende | Tu sistema | | -------------------------------------------------- | ---------------------------------------------------------- | | Valida los datos recibidos | Envía los datos comerciales completos | | Asigna la numeración y genera el CDC | Guarda el CDC y el resultado de la emisión | | Firma el documento y lo envía a SIFEN | Configura el certificado, el CSC y el timbrado en el panel | | Reintenta automáticamente los errores transitorios | Consulta el estado y atiende los rechazos | | Prepara el KuDE | Descarga el PDF y lo entrega al cliente | Si el envío termina en `ERROR`, detené el seguimiento automático y revisá el panel o contactá a soporte. No emitas otro documento para reemplazarlo. ## Próximos pasos [#próximos-pasos] * [Documentos electrónicos](/docs/conceptos/documentos-electronicos). * [Ciclo de vida](/docs/conceptos/ciclo-de-vida). * [Configuración en el panel](/docs/panel). # Contribuyente (/docs/conceptos/contribuyente) Un **contribuyente** es la persona física o jurídica registrada ante la SET (Secretaría de Estado de Tributación) y la DNIT como facturador electrónico. Es la entidad que emite los documentos: la "razón social" que aparece en cada factura. En Sifende, todo documento electrónico se emite a nombre de un contribuyente. Sin un contribuyente configurado no se pueden emitir documentos. ## Datos básicos [#datos-básicos] Cada contribuyente en Sifende guarda estos datos: | Campo | Descripción | | ------------------------------------ | --------------------------------------- | | `ruc` | Número de RUC sin DV — ej. `"80012345"` | | `digitoVerificador` | Dígito verificador del RUC — ej. `"1"` | | `razonSocial` | Nombre o razón social registrado en SET | | `nombreFantasia` | Nombre comercial (opcional) | | `actividadEconomica` | Código CIIU principal (ej. `47190`) | | `email` | Email de contacto | | `direccion` | Dirección fiscal del contribuyente | | `departamento`, `distrito`, `ciudad` | Geografía paraguaya | El RUC se valida contra el padrón de SIFEN al crear el contribuyente. Si no existe o el dígito verificador no coincide, la creación falla con `404 ruc-not-found`. ## Componentes de un contribuyente [#componentes-de-un-contribuyente] Más allá de los datos básicos, un contribuyente necesita tres elementos para emitir documentos: ### 1. Certificado digital P12 [#1-certificado-digital-p12] El certificado digital es la identidad criptográfica del contribuyente ante SIFEN. Es un archivo `.p12` (PKCS#12) emitido por una autoridad certificadora habilitada en Paraguay (DOCUMENTA, eFirma, e-Forma, ID-Token, etc.). Sifende guarda el certificado cifrado y lo usa automáticamente para firmar cada documento. Vos solo lo subís una vez desde el panel. ``` Contribuyente └── Certificado P12 (cifrado en reposo) └── Usado por Sifende para firmar cada DE ``` Cuando el certificado está por vencer, recibís una notificación. Ver [Certificado Digital](/docs/solucion-problemas/certificado-digital) para detalles operativos. ### 2. CSC (Código de Seguridad del Contribuyente) [#2-csc-código-de-seguridad-del-contribuyente] El CSC es un código que genera e-kuatia (la plataforma oficial de la DNIT) y se usa para construir la URL del QR del KuDE. Configurá el IdCSC y el CSC de cada ambiente en el [panel](/docs/panel/certificado-y-csc). Guardá el CSC como una credencial y cargalo en el ambiente que corresponde. El certificado activo es el mismo para pruebas y producción. ### 3. Timbrado [#3-timbrado] El timbrado electrónico es la autorización numérica de la SET para emitir documentos. Cargá el número y las fechas de inicio y fin por ambiente. Los establecimientos y puntos se envían en cada emisión. Ver [Timbrado y Numeración](/docs/conceptos/timbrado-numeracion). ## Una cuenta, varios contribuyentes [#una-cuenta-varios-contribuyentes] Una sola cuenta de Sifende puede gestionar varios contribuyentes. Sirve para casos como: * Estudios contables que facturan a nombre de varios clientes. * Holdings con varias razones sociales bajo el mismo grupo. * Desarrolladores que integran Sifende para varias empresas. Cada contribuyente tiene su propio certificado, CSC, timbrado y API key. Son ambientes lógicamente independientes dentro de la misma cuenta. ``` Cuenta Sifende ├── Contribuyente A (RUC 80012345-0) │ ├── Certificado A.p12 │ ├── Timbrado 12345678 │ └── API key sk_live_aaa... ├── Contribuyente B (RUC 80098765-9) │ ├── Certificado B.p12 │ ├── Timbrado 87654321 │ └── API key sk_live_bbb... └── Contribuyente C ... ``` ## Crear un contribuyente [#crear-un-contribuyente] Desde el panel: Andá a Contribuyentes → Crear. Cargá los datos básicos (RUC, razón social, dirección, actividad económica). Subí el certificado P12 y su contraseña. Configurá el timbrado y el CSC del ambiente en el que vas a emitir. Generá una API key de pruebas ( `sk_test_` ) o producción ( `sk_live_` ), según el ambiente configurado. Una vez completados estos pasos, el contribuyente queda listo para emitir documentos electrónicos. ## Próximos pasos [#próximos-pasos] * [Timbrado y Numeración](/docs/conceptos/timbrado-numeracion): cómo se numeran los documentos. * [Autenticación](/docs/conceptos/autenticacion): cómo se vincula la API key al contribuyente. * [Inicio Rápido](/docs/inicio-rapido): emitir tu primer documento. # Documentos Electrónicos (/docs/conceptos/documentos-electronicos) Un **documento electrónico (DE)** es la versión digital, firmada y registrada en SIFEN de un comprobante tributario tradicional. Reemplaza al equivalente físico (factura preimpresa, nota de crédito en papel) y tiene el mismo valor legal, con la ventaja de que la DNIT lo puede auditar en tiempo real. Cada DE en Sifende se identifica por su **CDC** (Código de Control), un identificador único de 44 caracteres que SIFEN reconoce a nivel nacional. ## Tipos de documento [#tipos-de-documento] | Tipo | Código SIFEN | Estado | | ---------------------------------- | ------------ | ------------ | | Factura Electrónica (FE) | 1 | ✅ Disponible | | Nota de Crédito Electrónica (NCE) | 5 | ✅ Disponible | | Nota de Débito Electrónica (NDE) | 6 | ✅ Disponible | | Autofactura Electrónica (AFE) | 4 | ✅ Disponible | | Nota de Remisión Electrónica (NRE) | 7 | ✅ Disponible | Todos los tipos disponibles se emiten por el mismo endpoint polimórfico: `POST /api/v1/documento-electronico`. El campo `tipoDocumento` define el tipo. Ver [Emitir documento](/docs/referencia/documentos-electronicos/emitir). ## Tipos disponibles [#tipos-disponibles] ### Factura Electrónica (FE) [#factura-electrónica-fe] La FE es el documento más común. Equivale a la factura tradicional. Se emite cuando vendés un producto o servicio, y declara la operación gravada con IVA ante la DNIT. * Cuándo usarla: todas las ventas a clientes (B2B con RUC, B2C nominado o innominado). * Detalles: soporta condición de pago `CONTADO` o `CREDITO`, ítems con IVA al 10%, 5% o exento, descuentos por línea y globales. * Receptor: puede ser otro contribuyente con RUC, una persona física con cédula, o "Sin Nombre" (innominado, solo permitido en FE). Ver [Modelo: Factura Electrónica](/docs/referencia/modelos/factura-electronica). ### Nota de Crédito Electrónica (NCE) [#nota-de-crédito-electrónica-nce] La NCE se emite para anular o reducir una operación previamente facturada: devoluciones, descuentos posteriores o corrección de un error en la FE original. * Cuándo usarla: devoluciones de mercadería, bonificaciones aplicadas después de la venta, ajustes por errores en una FE ya aprobada. * Detalles: requiere obligatoriamente un documento asociado (la FE que está corrigiendo). El receptor no puede ser innominado: tiene que tener RUC o cédula identificada. * Motivo (`motivoEmision`): devolución, descuento, bonificación, etc. Ver [Modelo: Nota de Crédito](/docs/referencia/modelos/nota-credito). ### Nota de Débito Electrónica (NDE) [#nota-de-débito-electrónica-nde] La NDE se emite para incrementar el monto de una operación ya facturada: intereses por mora, cargos adicionales, ajustes que aumentan el importe original. * Cuándo usarla: intereses por pago tardío, recargos pactados después de la venta, ajustes al alza. * Detalles: igual que la NCE, requiere documento asociado y receptor identificado. La diferencia con la NCE es semántica: la NCE reduce el monto, la NDE lo aumenta. Ver [Modelo: Nota de Débito](/docs/referencia/modelos/nota-debito). ### Nota de Remisión Electrónica (NRE) [#nota-de-remisión-electrónica-nre] Documenta el traslado de mercadería, por ejemplo, una entrega por venta o un movimiento entre sucursales. No lleva precios ni IVA. Esperá el estado `APROBADO` o `APROBADO_OBSERVACION` antes de iniciar el traslado; el KuDE acompaña la mercadería. Ver [Modelo: Nota de remisión](/docs/referencia/modelos/nota-remision). ### Autofactura Electrónica (AFE) [#autofactura-electrónica-afe] La emite el contribuyente que compra un bien o contrata un servicio a una persona no contribuyente. Quien emite el documento es el comprador; los datos de quien vende se envían en `vendedor`. * Vendedor: persona local no contribuyente, identificada con cédula paraguaya. * Condiciones: operación en guaraníes y al contado, con el precio final por unidad, sin campos de IVA ni descuentos. * Receptor: no se envía; se completa con los datos del contribuyente que emite. Ver la [guía de autofactura](/docs/guias/autofactura) y el [Modelo: Autofactura Electrónica](/docs/referencia/modelos/autofactura). ## Características comunes [#características-comunes] Todos los DE en Sifende comparten: * CDC único de 44 caracteres, asignado al emitir. * Firma digital con el certificado del contribuyente, según el Manual Técnico de SIFEN. * Validación contra SIFEN dentro de los minutos siguientes a la emisión. * KuDE descargable (representación gráfica en PDF) una vez aprobado. * Cancelación mediante evento, dentro del plazo permitido por SIFEN (ver [Eventos SIFEN](/docs/conceptos/eventos-sifen)). ## Próximos pasos [#próximos-pasos] * [Ciclo de Vida](/docs/conceptos/ciclo-de-vida): qué pasa después de emitir. * [CDC](/docs/conceptos/cdc): el identificador único. * [Receptor](/docs/conceptos/receptor): B2B, B2C e innominado. # Eventos SIFEN (/docs/conceptos/eventos-sifen) Un **evento SIFEN** comunica una cancelación, una inutilización de numeración o la identificación del receptor de una factura innominada. Cada operación tiene sus propios requisitos. ## Qué es un evento [#qué-es-un-evento] A diferencia de un documento electrónico (que declara una operación comercial), un evento comunica un acontecimiento sobre un documento o numeración. Cada evento recibe su propio resultado de SIFEN. Podés enviar estos eventos: | Evento | Qué hace | Documento afectado | | ------------- | ------------------------------------------------ | -------------------------- | | Cancelación | Anula un DE ya aprobado | Un DE específico (por CDC) | | Inutilización | Marca un rango de numeración como no utilizable | Un rango (sin CDC) | | Nominación | Identifica al receptor de una factura innominada | Una factura aprobada | El evento de actualización de datos del transporte no se admite. ## Cancelación de documento [#cancelación-de-documento] Anula un documento que ya fue aprobado por SIFEN. Una vez cancelado, el documento queda registrado en SIFEN pero sin valor fiscal: como si nunca se hubiera emitido para fines tributarios. ### Cuándo usarlo [#cuándo-usarlo] * Emitiste una FE con datos incorrectos y ya está aprobada. * El cliente devolvió la mercadería antes de tomar posesión y querés anular en lugar de emitir una NCE. * Detectaste un duplicado emitido por error. ### Restricciones [#restricciones] * El documento tiene que estar `APROBADO` o `APROBADO_OBSERVACION`. No podés cancelar uno en `RECHAZADO` o `PENDIENTE`. * Plazo: 48 horas desde la aprobación para FE y 168 horas para NCE, NDE y NRE. Para ajustar una factura fuera de plazo, evaluá emitir una NCE. * El timbrado tiene que estar vigente al momento de enviar la cancelación. * Es irreversible: un documento cancelado no se puede "descancelar". ### Cómo emitirla [#cómo-emitirla] ```bash curl -X POST https://api.sifende.com.py/api/v1/documento-electronico/:cdc/cancelar \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "motivo": "Documento emitido con datos incorrectos del receptor" }' ``` El motivo es un texto libre de 5 a 500 caracteres que se registra ante SIFEN. Ver [Cancelar Documento](/docs/referencia/documentos-electronicos/cancelar) para detalles. ## Inutilización de numeración [#inutilización-de-numeración] Marca un rango de números no utilizados dentro de un timbrado como inutilizables. Sirve para documentar saltos de numeración que de otra forma quedarían como huecos en la secuencia ante SIFEN. ### Cuándo usarlo [#cuándo-usarlo-1] * Tu sistema reservó un número pero falló antes de emitir el documento. * Un cambio de software dejó números sin asignar. * Detectaste un hueco en la secuencia y necesitás cerrarlo formalmente. ### Restricciones [#restricciones-1] * Solo aplica a números nunca emitidos. No podés inutilizar un número que ya tiene un CDC en SIFEN. * El rango tiene que pertenecer a un mismo establecimiento + punto de expedición + tipo de documento. * El timbrado tiene que estar vigente al enviar la inutilización. * Es irreversible: los números inutilizados no se pueden reutilizar. ### Cómo emitirla [#cómo-emitirla-1] ```bash curl -X POST https://api.sifende.com.py/api/v1/documento-electronico/inutilizar \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "numeroTimbrado": 12557896, "establecimiento": "001", "puntoExpedicion": "001", "numeroInicio": "0000025", "numeroFin": "0000030", "tipoDocumento": 1, "motivo": "Números no utilizados por error de sistema" }' ``` Ver [Inutilizar Numeración](/docs/referencia/documentos-electronicos/inutilizar) para detalles. ## Nominación [#nominación] Identifica al receptor de una factura que se emitió como innominada. La nominación tiene su propio resultado; el CDC, el XML y el KuDE originales de la factura se conservan. ### Cuándo usarla [#cuándo-usarla] Cuando necesitás registrar un receptor identificado para una factura emitida con receptor innominado. ### Restricciones [#restricciones-2] * Sólo aplica a facturas electrónicas en estado `APROBADO` o `APROBADO_OBSERVACION`. * El receptor original debe ser `NO_CONTRIBUYENTE`, con `tipoDocumento: "INNOMINADO"` y `numeroDocumento: "0"`. * No está disponible en `SANDBOX`: la API responde **422**. ### Cómo emitirla [#cómo-emitirla-2] Enviá `POST /api/v1/documento-electronico/{cdc}/nominar` con los datos del receptor. Seguí la [guía de nominación](/docs/guias/nominar-factura) y consultá los campos y las respuestas en la [referencia del endpoint](/docs/referencia/documentos-electronicos/nominar). ## Diferencias entre eventos y NCE/NDE [#diferencias-entre-eventos-y-ncende] Hay una superposición conceptual entre cancelar un DE y emitir una nota de crédito. La diferencia: | Aspecto | Cancelación (evento) | Nota de Crédito (NCE) | | ----------------- | ----------------------------------------------- | ---------------------------------------- | | Tipo de operación | Evento SIFEN | Documento electrónico | | Plazo | 48 h desde aprobación (FE); 168 h (NCE/NDE/NRE) | Sin límite estricto | | Efecto contable | Documento "no existe" fiscalmente | Documento existe + reverso parcial/total | | Receptor | Cualquier tipo (incluso innominado) | Receptor identificado (no innominado) | | Cuándo elegirla | Errores tempranos, duplicados | Devoluciones, descuentos posteriores | Como regla práctica: * Si todavía estás en plazo y el cliente no recibió el comprobante, cancelá. * Si el cliente ya pagó o recibió el comprobante, emitís una NCE. ## Listado de eventos emitidos [#listado-de-eventos-emitidos] Podés consultar el historial de eventos enviados a SIFEN: ```bash curl https://api.sifende.com.py/api/v1/documento-electronico/eventos \ -H "Authorization: Bearer sk_live_..." ``` Ver [Listar Eventos](/docs/referencia/eventos/listar) para los parámetros de búsqueda. ## Próximos pasos [#próximos-pasos] * [Cancelar Documento](/docs/guias/cancelar-documento): guía paso a paso. * [Inutilizar Numeración](/docs/guias/inutilizar-numeracion): guía paso a paso. * [Nominar una factura innominada](/docs/guias/nominar-factura): guía paso a paso. * [Nota de Crédito](/docs/guias/nota-credito): alternativa a la cancelación. # Conceptos (/docs/conceptos) Esta sección explica los conceptos clave de la plataforma Sifende y del sistema SIFEN. Cada página es independiente: podés leerlas en orden o ir directo al concepto que necesitás. ## Orden recomendado [#orden-recomendado] Para desarrolladores que están integrando por primera vez: 1. [Cómo Funciona](/docs/conceptos/como-funciona): desde la emisión hasta el resultado. 2. [Autenticación](/docs/conceptos/autenticacion): cómo hablar con la API. 3. [Contribuyente](/docs/conceptos/contribuyente): la entidad emisora. 4. [Timbrado y Numeración](/docs/conceptos/timbrado-numeracion): la habilitación de la SET. 5. [Documentos Electrónicos](/docs/conceptos/documentos-electronicos): qué podés emitir. 6. [Receptor](/docs/conceptos/receptor): quién recibe el documento. 7. [Ítems e IVA](/docs/conceptos/items-iva): cómo se estructuran los productos. 8. [Ciclo de Vida](/docs/conceptos/ciclo-de-vida): qué pasa después de emitir. 9. [CDC](/docs/conceptos/cdc): el identificador único del documento. 10. [Ambientes](/docs/conceptos/ambientes): test vs producción. 11. [Eventos SIFEN](/docs/conceptos/eventos-sifen): cancelación, inutilización y nominación. Consultá también [Lotes](/docs/conceptos/lotes) para interpretar el estado de un envío y su relación con cada documento. # Ítems e IVA (/docs/conceptos/items-iva) Cada documento electrónico tiene un arreglo de **ítems**: los productos o servicios que se están facturando. Sifende calcula los totales, el IVA por tasa y los subtotales a partir de los ítems que envíes. ## Anatomía de un ítem [#anatomía-de-un-ítem] ```json { "codigo": "PROD-001", "descripcion": "Café molido tostado 500g", "unidadMedida": "UNI", "cantidad": 2, "precioUnitario": 25000, "afectacionTributaria": "GRAVADO", "tasaIVA": 10 } ``` | Campo | Descripción | | ---------------------- | -------------------------------------------------------------------------------------------- | | `codigo` | Código interno del producto (libre, para tu sistema) | | `descripcion` | Nombre legible del producto/servicio que aparece en el KuDE | | `unidadMedida` | Unidad — `UNI`, `kg`, `LT`, `Hs`, etc. (ver [Enumeraciones](/docs/referencia/enumeraciones)) | | `cantidad` | Cantidad numérica (acepta decimales) | | `precioUnitario` | Precio por unidad con IVA incluido (en PYG, entero) | | `afectacionTributaria` | Cómo aplica el IVA (ver abajo) | | `tasaIVA` | Tasa de IVA — `10`, `5` o `0` | ## Tasas de IVA en Paraguay [#tasas-de-iva-en-paraguay] El sistema tributario paraguayo tiene tres tasas de IVA: | Tasa | Aplica a | | ------------- | -------------------------------------------------------------------------------------------------------- | | 10% (general) | La mayoría de productos y servicios: ropa, electrónicos, software, servicios profesionales, combustibles | | 5% (reducida) | Alimentos de la canasta básica, productos farmacéuticos, productos agropecuarios, libros | | 0% (exento) | Exportaciones, servicios financieros, alquiler de inmuebles para vivienda, salud, educación | ## Afectación tributaria [#afectación-tributaria] El campo `afectacionTributaria` indica cómo se trata fiscalmente cada ítem. Combinalo con `tasaIVA` para indicar la tasa aplicable: | Valor | `tasaIVA` | Descripción | | ----------------- | ---------- | -------------------------------------------------------------------------------- | | `GRAVADO` | `10` o `5` | Operación gravada con IVA. La tasa se indica en `tasaIVA` | | `EXENTO` | `0` | Operación exenta (sin IVA) | | `EXONERADO` | `0` | Operación exonerada por ley específica | | `GRAVADO_PARCIAL` | `10` o `5` | Solo una porción de la operación está gravada. La porción se indica en `propIVA` | En `GRAVADO_PARCIAL` el campo `propIVA` es obligatorio y va entre `0` y `100` sin incluirlos: `propIVA: 30` grava el 30% del ítem y deja el 70% como exento. Las demás afectaciones no lo necesitan — Sifende deriva la proporción de `afectacionTributaria`. Un solo documento puede mezclar ítems con afectaciones distintas. Por ejemplo, una farmacia que vende medicamentos (`GRAVADO` con `tasaIVA: 5`) y cosméticos (`GRAVADO` con `tasaIVA: 10`) en la misma factura. ## Cálculo de IVA [#cálculo-de-iva] En Paraguay, el `precioUnitario` siempre incluye el IVA. No se agrega IVA encima del precio: el IVA ya está adentro. El cálculo del componente de IVA dentro de un precio total es: ``` IVA = precio × tasa / (100 + tasa) Base = precio × 100 / (100 + tasa) ``` ### Ejemplo — IVA al 10% [#ejemplo--iva-al-10] Producto a `25000` PYG con IVA al 10% (`afectacionTributaria: "GRAVADO"`, `tasaIVA: 10`): ``` IVA = 25000 × 10 / 110 = 2272.73 → 2273 PYG Base = 25000 × 100 / 110 = 22727.27 → 22727 PYG Verificación: 22727 + 2273 = 25000 ✓ ``` ### Ejemplo — IVA al 5% [#ejemplo--iva-al-5] Producto a `21000` PYG con IVA al 5% (`afectacionTributaria: "GRAVADO"`, `tasaIVA: 5`): ``` IVA = 21000 × 5 / 105 = 1000 PYG Base = 21000 × 100 / 105 = 20000 PYG Verificación: 20000 + 1000 = 21000 ✓ ``` No tenés que hacer estos cálculos a mano. Sifende los aplica solo a partir de `precioUnitario`, `cantidad`, `afectacionTributaria` y `tasaIVA`. La fórmula está acá para que entiendas el modelo. ## Reglas de redondeo en PYG [#reglas-de-redondeo-en-pyg] El guaraní no tiene decimales. Los totales se redondean a entero usando "half-up" (medio hacia arriba): | Valor calculado | Valor en factura | | --------------- | ---------------- | | `2272.73` | `2273` | | `2272.49` | `2272` | | `2272.50` | `2273` | Si tu sistema interno trabaja con decimales (por ejemplo, tu ERP guarda `precio = 22727.27`), redondeá antes de enviar a Sifende. Mandar `precioUnitario: 22727.27` con `monedaOperacion: "PYG"` te va a dar error de validación. ## Cálculo de totales [#cálculo-de-totales] Sifende deriva estos totales del arreglo de ítems: ``` subtotal_item = cantidad × precioUnitario total_documento = Σ subtotal_item (todos los ítems) total_iva_10 = Σ iva calculado de ítems con afectacionTributaria=GRAVADO y tasaIVA=10 total_iva_5 = Σ iva calculado de ítems con afectacionTributaria=GRAVADO y tasaIVA=5 total_iva = total_iva_10 + total_iva_5 total_gravado_10 = Σ base de ítems con afectacionTributaria=GRAVADO y tasaIVA=10 total_gravado_5 = Σ base de ítems con afectacionTributaria=GRAVADO y tasaIVA=5 total_exento = Σ subtotales de ítems con afectacionTributaria=EXENTO o EXONERADO ``` Estos totales aparecen en los totales del documento y se imprimen en el KuDE. ## Descuentos [#descuentos] Cada ítem puede informar `descuentoParticular` como importe por unidad. El documento puede informar una sola vez `descuentoGlobalPorcentaje`; Sifende aplica ese porcentaje al precio unitario de todos los ítems, aunque también tengan descuento particular. No envíes el importe global calculado por ítem: Sifende deriva los importes del documento y multiplica ambos descuentos unitarios por la cantidad para obtener los totales. La suma de ambos descuentos no puede superar el precio unitario. En PYG, el importe global derivado se redondea a entero con `half-up`; en moneda extranjera se calcula con hasta 8 decimales. ```json { "descuentoGlobalPorcentaje": 10, "items": [ { "codigo": "A", "cantidad": 2, "precioUnitario": 48000, "descuentoParticular": 6000 }, { "codigo": "B", "cantidad": 1, "precioUnitario": 20000 } ] } ``` En este ejemplo el descuento particular total es G. 12.000, el global total es G. 11.600 y el neto de ambos ítems es G. 92.400. Los demás campos obligatorios del documento se omitieron para enfocar el cálculo. En el KuDE, la columna «Desc.» de cada fila muestra la suma de ambos descuentos multiplicada por la cantidad, y la columna «Total» es el neto del ítem: `P. Unitario x Cantidad - Desc.`. El bloque de totales agrega una fila «Descuento global (X%)» cuando se informó `descuentoGlobalPorcentaje` y otra «Total descuentos» con la suma de los dos conceptos. Sin descuentos, ninguna de esas filas se imprime. ## Próximos pasos [#próximos-pasos] * [Modelo: Item](/docs/referencia/modelos/item): schema completo. * [Enumeraciones](/docs/referencia/enumeraciones): unidades de medida y afectaciones. * [Convenciones — Moneda PYG](/docs/referencia/convenciones): reglas de redondeo. # Lotes (/docs/conceptos/lotes) Sifende agrupa los documentos en **lotes** para enviarlos a SIFEN. Como integrador, consultá cada documento por su CDC: el estado del lote no sustituye el resultado individual. Podés ver el lote en **Documentos electrónicos → Lotes** del panel y recibir el webhook [`lote.procesado`](/docs/referencia/webhooks). En SANDBOX no hay envío a SIFEN ni lotes. ## Ciclo de vida del lote [#ciclo-de-vida-del-lote] ```text ┌─────────────┐ Documentos ──► │ Preparado │ ◄───────────────────────────────┐ └──────┬──────┘ │ ▼ │ ┌─────────────┐ │ │ Intentando │ ◄─────────────────┐ │ └──────┬──────┘ │ │ ┌─────────────┴─────────────┐ │ Reintento │ ▼ ▼ │ programado │ ┌───────────────┐ ┌─────────────┐ │ │ │ Enviado │ │ Error │─────┘ │ └───┬───────┬───┘ └──────┬──────┘ │ ▼ │ │ Reintentos agotados │ ┌───────────┐ │ ▼ │ │ Procesado │ │ ┌─────────────┐ │ └───────────┘ └───────────────►│ Fallido │───────────────────┘ └─────────────┘ Reintentar Lote Falla la consulta del resultado desde el panel ``` Un error permanente puede pasar de Intentando a Fallido sin pasar por Error. La acción [Reintentar Lote](/docs/panel/lotes) sólo está disponible para lotes Fallidos. ## Estados del lote [#estados-del-lote] | Lote en el panel | Qué significa | Sus documentos | | ---------------------- | ------------------------------------------ | --------------------------------------------------------------------------------- | | Preparado / Intentando | Listo o enviándose | `EN_LOTE` | | Enviado | SIFEN recibió el envío; falta el resultado | Siguen en `EN_LOTE` | | Procesado | SIFEN respondió | Cada uno con su resultado | | Error | Sifende reintenta solo | Sin cambios | | Fallido | No se reintenta solo | `ERROR` si falló el envío; siguen en `EN_LOTE` si falló la consulta del resultado | **Procesado** no significa que todos los documentos estén aprobados. Consultá el resultado de cada CDC o los resultados incluidos en el webhook. ## Si el lote está Fallido [#si-el-lote-está-fallido] Revisá el motivo y seguí la [guía para reintentar un envío fallido](/docs/panel/lotes). Conservá los CDC originales y retomá sus consultas después del reintento; no vuelvas a emitir esos documentos. Para interpretar cada resultado, consultá el [ciclo de vida del documento](/docs/conceptos/ciclo-de-vida). # Receptor (/docs/conceptos/receptor) El **receptor** es el destinatario del documento electrónico: la persona o empresa a la que le emitís la factura. Cómo se llena el bloque de receptor depende de si el destinatario es otro contribuyente (B2B) o un consumidor final (B2C). ## Campos del receptor [#campos-del-receptor] El bloque `receptor` usa siempre los mismos nombres de campo, sin importar el tipo de operación: | Campo | Descripción | | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `tipoOperacion` | Tipo de operación — `B2B`, `B2C`, `B2G`, `B2F` | | `tipoContribuyente` | Naturaleza del receptor — `CONTRIBUYENTE` o `NO_CONTRIBUYENTE`. Siempre obligatorio | | `tipoContribuyenteReceptor` | Si el receptor es persona física o jurídica — `PERSONA_FISICA` o `PERSONA_JURIDICA`. Obligatorio cuando `tipoContribuyente = CONTRIBUYENTE`, y solo en ese caso | | `tipoDocumento` | Tipo de identificación — `CEDULA_PARAGUAYA`, `PASAPORTE`, `CEDULA_EXTRANJERA`, `CARNET_DE_RESIDENCIA`, `INNOMINADO`, `TARJETA_DIPLOMATICA`, `OTRO`. Solo cuando `tipoContribuyente = NO_CONTRIBUYENTE` | | `numeroDocumento` | El RUC (parte numérica), cédula o número de pasaporte. Siempre obligatorio | | `digitoVerificador` | DV del RUC. Obligatorio cuando `tipoContribuyente = CONTRIBUYENTE` | | `nombreRazonSocial` | Nombre completo o razón social del receptor. Siempre obligatorio | | `direccion` | Dirección del receptor (opcional según operación) | ## Ejemplos [#ejemplos] Receptor innominado para venta mostrador sin identificar al cliente. El caso más simple: ```json { "receptor": { "tipoOperacion": "B2C", "tipoContribuyente": "NO_CONTRIBUYENTE", "tipoDocumento": "INNOMINADO", "numeroDocumento": "0", "nombreRazonSocial": "Sin Nombre" } } ``` Receptor contribuyente con RUC, venta a otra empresa: ```json { "receptor": { "tipoOperacion": "B2B", "tipoContribuyente": "CONTRIBUYENTE", "tipoContribuyenteReceptor": "PERSONA_JURIDICA", "numeroDocumento": "80098765", "digitoVerificador": "9", "nombreRazonSocial": "Comercial Guaraní S.A.", "direccion": "Av. España 1234" } } ``` ## B2B — Receptor contribuyente [#b2b--receptor-contribuyente] Cuando el destinatario es otra empresa o persona con RUC, la operación es B2B y `tipoContribuyente = CONTRIBUYENTE`. El receptor se identifica por `numeroDocumento` (parte numérica del RUC) y `digitoVerificador`, y hay que declarar si es persona física o jurídica en `tipoContribuyenteReceptor`. No se envía `tipoDocumento` para B2B. SIFEN valida el RUC contra su padrón. Si el RUC no existe o el DV no coincide, el documento se rechaza con error 1302–1306. ## B2C — Receptor consumidor final [#b2c--receptor-consumidor-final] Cuando el destinatario es una persona física que no es contribuyente del IVA, la operación es B2C y `tipoContribuyente = NO_CONTRIBUYENTE`. Sobre esa base tenés dos modalidades, y lo único que cambia entre ellas es el `tipoDocumento`. ### Receptor identificado [#receptor-identificado] ```json { "receptor": { "tipoOperacion": "B2C", "tipoContribuyente": "NO_CONTRIBUYENTE", "tipoDocumento": "CEDULA_PARAGUAYA", "numeroDocumento": "1234567", "nombreRazonSocial": "María González" } } ``` Para extranjeros, el `tipoContribuyente` sigue siendo `NO_CONTRIBUYENTE`: lo que cambia es el `tipoDocumento` (`PASAPORTE`, `CEDULA_EXTRANJERA`, `CARNET_DE_RESIDENCIA` o `TARJETA_DIPLOMATICA`, según corresponda). Si además el receptor reside fuera del país, la operación es `B2F` y agregás `pais` con el código ISO y la `direccion` del exterior. ### Receptor innominado [#receptor-innominado] Para ventas de bajo monto en mostrador donde no se identifica al cliente, usá `tipoDocumento: "INNOMINADO"` sobre `tipoContribuyente: "NO_CONTRIBUYENTE"`. `numeroDocumento` y `nombreRazonSocial` siguen siendo obligatorios aunque el cliente sea anónimo. El Manual Técnico de SIFEN define para este caso los literales `"0"` y `"Sin Nombre"`, y hay que enviarlos tal cual. El receptor innominado solo es válido en Factura Electrónica (FE). SIFEN rechaza notas de crédito y notas de débito con receptor innominado. Para emitir una NCE o NDE, el receptor tiene que estar identificado con RUC, cédula o pasaporte. En una FE, B2F exige `tipoTransaccion: "PRESTACION_SERVICIOS"`: no admite `VENTA_MERCADERIA`. El receptor debe informar un país distinto de `PRY`, dirección y número de casa, y omitir `departamento`, `ciudad` y `codigoDistrito`. Consultá las [reglas del receptor](/docs/referencia/modelos/receptor#reglas-clave). ## Resumen — cuándo usar cada modo [#resumen--cuándo-usar-cada-modo] | Caso | `tipoOperacion` | `tipoContribuyente` | `tipoDocumento` | | ----------------------------------------------- | --------------------- | --------------------- | ---------------------------------------------------------------------- | | Vendés a otra empresa con RUC | `B2B` | `CONTRIBUYENTE` | — (RUC va en `numeroDocumento` + `digitoVerificador`) | | Vendés a un cliente final con cédula | `B2C` | `NO_CONTRIBUYENTE` | `CEDULA_PARAGUAYA` | | Vendés a un extranjero residente | `B2C` | `NO_CONTRIBUYENTE` | `PASAPORTE` o `CARNET_DE_RESIDENCIA` | | Venta de bajo monto sin identificar | `B2C` | `NO_CONTRIBUYENTE` | `INNOMINADO` (con `"0"` y `"Sin Nombre"`) | | Venta a institución pública | `B2G` | `CONTRIBUYENTE` | — (RUC va en `numeroDocumento` + `digitoVerificador`) | | Prestación de servicios a receptor del exterior | `B2F` | `NO_CONTRIBUYENTE` | `PASAPORTE` u `OTRO` (+ `pais` extranjero, `direccion` y `numeroCasa`) | | Emitís una NCE o NDE | igual al doc original | igual al doc original | Cualquiera menos `INNOMINADO` | | Emitís una NRE | Según el receptor | Según el receptor | Cualquiera menos `INNOMINADO`; se omite para contribuyentes | La NRE requiere `direccion` y `numeroCasa` del receptor; para un receptor nacional, también `departamento` y `ciudad`. En `TRASLADO_ENTRE_LOCALES`, el receptor debe ser contribuyente con el RUC del emisor. Ver la [guía de nota de remisión](/docs/guias/nota-remision). ## Próximos pasos [#próximos-pasos] * [Modelo: Receptor](/docs/referencia/modelos/receptor): schema completo. * [Guía: Receptor B2B vs B2C](/docs/guias/receptor-b2b-b2c): paso a paso con ejemplos. * [Documentos Electrónicos](/docs/conceptos/documentos-electronicos): qué tipos podés emitir. # Timbrado y Numeración (/docs/conceptos/timbrado-numeracion) El **timbrado** autoriza al contribuyente a emitir documentos desde su fecha de inicio de vigencia. El timbrado electrónico no tiene fecha de fin. En Sifende lo cargás por ambiente: pruebas y producción tienen su propia configuración. ## Cargar el timbrado [#cargar-el-timbrado] Desde **Contribuyente → Timbrado**, elegí el **Ambiente del timbrado** y completá: | Dato | Qué cargar | | ------------------ | ------------------------------------ | | Número de timbrado | El número asignado para ese ambiente | | Fecha de inicio | La fecha exacta registrada en la SET | Los establecimientos y puntos de expedición se envían en cada emisión. No forman parte de los datos que cargás con el timbrado. Seguí la [guía del panel](/docs/panel/timbrado) para cargarlo o actualizarlo. ## Establecimiento y punto de expedición [#establecimiento-y-punto-de-expedición] El establecimiento identifica la sucursal. El punto de expedición identifica la caja o canal dentro de esa sucursal. En la solicitud de emisión enviá `numeroEstablecimiento` y `puntoExpedicion` como enteros. Por ejemplo, para la segunda sucursal y su primera caja: ```json { "numeroEstablecimiento": 2, "puntoExpedicion": 1 } ``` Este fragmento se agrega a los demás campos del [documento que vas a emitir](/docs/referencia/documentos-electronicos/emitir). Ambos campos son obligatorios. ## Numeración automática [#numeración-automática] Sifende asigna el siguiente número al emitir. La secuencia es independiente por contribuyente, ambiente, tipo de documento, establecimiento y punto de expedición. El número formateado tiene tres partes: ```text 002-001-0000025 │ │ └─ Número del documento: 7 dígitos │ └─ Punto de expedición: 3 dígitos └─ Establecimiento: 3 dígitos ``` La respuesta de emisión incluye `numeroFormateado`. La consulta de estado devuelve `numeroDocumento` como un número entero. ## Rechazos y números sin utilizar [#rechazos-y-números-sin-utilizar] Si corregís y volvés a emitir un documento rechazado, Sifende asigna un número y un CDC nuevos. El número del rechazado queda libre y se puede [inutilizar](/docs/guias/inutilizar-numeracion). No reemitas un documento que sigue en proceso o está en `ERROR`. Consultá el [ciclo de vida](/docs/conceptos/ciclo-de-vida) antes de decidir qué hacer. Si migrás desde otro sistema, [fijá el próximo número antes de emitir](/docs/panel/numeracion). ## Próximos pasos [#próximos-pasos] * [Timbrado en el panel](/docs/panel/timbrado). * [Múltiples establecimientos](/docs/guias/multiples-establecimientos). * [CDC](/docs/conceptos/cdc). # Autofactura (/docs/guias/autofactura) Usá una **Autofactura Electrónica (AFE)** cuando tu empresa compra un bien o contrata un servicio a una persona local que no es contribuyente, por ejemplo un productor que vende su cosecha. Quien emite la AFE es el comprador. La AFE no lleva `receptor`: Sifende completa el comprador con los datos de tu contribuyente. Los datos de quien vende van en `vendedor`. ## Paso 1: Armá la solicitud [#paso-1-armá-la-solicitud] Este ejemplo registra la compra de 200 kg de mandioca a un productor de Caaguazú, pagada en efectivo. Reemplazá las identidades, las fechas, las direcciones y los importes por los de tu operación y guardalo como `autofactura.json`. ```json { "tipoDocumento": "AUTOFACTURA_ELECTRONICA", "fechaEmision": "2026-10-03T09:30:00", "numeroEstablecimiento": 1, "puntoExpedicion": 1, "tipoTransaccion": "COMPRA_PRODUCTOS", "vendedor": { "naturaleza": "NO_CONTRIBUYENTE", "tipoDocumento": "CEDULA_PARAGUAYA", "numeroDocumento": "3456789", "nombre": "Ramón Benítez", "numeroCasa": 0, "domicilio": { "direccion": "Compañía Yhovy, camino vecinal", "departamento": "6", "ciudad": "2988" } }, "lugarOperacion": { "direccion": "Compañía Yhovy, camino vecinal", "departamento": "6", "ciudad": "2988" }, "constancia": { "tipo": "CONSTANCIA_NO_CONTRIBUYENTE" }, "items": [ { "codigo": "MAN-001", "descripcion": "Mandioca fresca", "cantidad": 200, "unidadMedida": "kg", "precioUnitario": 2500 } ], "condicionPago": { "tipo": "CONTADO", "tipoPago": "EFECTIVO", "monedaPago": "PYG", "montoPago": 500000 } } ``` `departamento` y `ciudad` llevan códigos SIFEN, no nombres. Buscalos en el [catálogo de geografía](/docs/referencia/catalogos/geografia). Consultá el [modelo de autofactura](/docs/referencia/modelos/autofactura) para todos los campos y sus límites. ## Paso 2: Enviá la autofactura [#paso-2-enviá-la-autofactura] ```bash curl -X POST https://api.sifende.com.py/api/v1/documento-electronico \ -H "Authorization: Bearer $SIFENDE_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: compra-mandioca-0001" \ --data-binary @autofactura.json ``` Antes de aceptar la solicitud, Sifende verifica en el padrón que el vendedor no tenga un RUC vigente. La API responde `202 Accepted` con el CDC y las URLs de seguimiento. Para recuperar una respuesta perdida, repetí la solicitud con la misma `Idempotency-Key` y el mismo contenido; ver la [guía de idempotencia](/docs/guias/idempotencia). ## Paso 3: Esperá la aprobación y descargá el KuDE [#paso-3-esperá-la-aprobación-y-descargá-el-kude] [Consultá el estado](/docs/guias/consultar-estado) hasta obtener `APROBADO` o `APROBADO_OBSERVACION`. Después, [descargá el KuDE](/docs/guias/descargar-kude) como comprobante de la compra. Si queda `RECHAZADO`, revisá el motivo y corregí los datos antes de emitir otra autofactura. Si queda `ERROR` o sigue en `EN_LOTE` después de varias horas, revisá el [lote en el panel](/docs/panel/lotes) y continuá el seguimiento con el mismo CDC. ## Errores frecuentes [#errores-frecuentes] | Respuesta | Qué revisar | | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | `400` en `vendedor.numeroDocumento` | Revisá que la cédula tenga de 5 a 12 dígitos, sin puntos, espacios ni guiones. La AFE sólo admite personas sin RUC o con RUC cancelado | | `502 padron-no-disponible` | No se pudo consultar el padrón. Reintentá más tarde con la misma `Idempotency-Key` | | `400` en `ciudad` o `codigoDistrito` | La ciudad no pertenece al departamento, o el código es ambiguo: informá `codigoDistrito` | | `400` en `condicionPago.montoPago` | El pago no coincide con el total. Sifende redondea el total al múltiplo inferior de 50 guaraníes | | `400` en `receptor`, `monedaOperacion` o `condicionOperacion` | La AFE no admite receptor y sólo admite `PYG` y `CONTADO` | | `400 invalid-format` | La solicitud incluye un campo que la AFE no admite | | `403 plan-operation-not-allowed` | La modalidad packs no permite emitir por API | Las demás respuestas de error están en la [referencia de errores](/docs/referencia/errores). # Cancelar un Documento (/docs/guias/cancelar-documento) Si emitiste un DE con datos incorrectos y querés invalidarlo legalmente, tenés que cancelarlo enviando un evento a SIFEN. ## Cuándo cancelar [#cuándo-cancelar] Cancelá un documento cuando: * El documento está en estado `APROBADO` o `APROBADO_OBSERVACION` (los dos quedaron registrados en SIFEN) * Detectaste un error en datos del receptor, items o montos * El receptor **aún no lo declaró** ante la SET para deducir IVA * Estás dentro de las 48 horas desde la aprobación para FE o de las 168 horas para NCE, NDE y NRE La cancelación es **irreversible**. Cuando SIFEN aprueba el evento, el documento queda en estado `CANCELADO` permanentemente y no se puede revertir. ## Cuándo NO podés cancelar [#cuándo-no-podés-cancelar] | Estado del DE | Acción correcta | | ---------------------- | --------------------------------------------------------------- | | `RECHAZADO` | No requiere cancelación, ya es legalmente nulo. Emití uno nuevo | | `CANCELADO` | Ya está cancelado | | `PENDIENTE` | Esperá a que SIFEN procese el documento antes de decidir | | Receptor ya lo declaró | Solo podés emitir una **Nota de Crédito** para anularlo | ## Cómo cancelar [#cómo-cancelar] **Identificá el CDC** del documento a cancelar (44 dígitos). **Enviá el evento de cancelación** con un motivo descriptivo (5-500 caracteres): ```bash curl -X POST "https://api.sifende.com.py/api/v1/documento-electronico/01800123451001001000000122026042710000000006/cancelar" \ -H "Authorization: Bearer sk_live_..." \ -H "Idempotency-Key: $IDEMPOTENCY_KEY" \ -H "Content-Type: application/json" \ -d '{ "motivo": "Error en datos del receptor" }' ``` | Campo | Tipo | Req. | Restricción | | -------- | -------- | ---- | ---------------- | | `motivo` | `string` | Sí | 5-500 caracteres | **Revisá el resultado.** Si `estadoEvento` es `APROBADO`, el documento queda `CANCELADO`. Un HTTP `200` también puede contener un evento `RECHAZADO`; revisá `codigoRespuesta` y `mensajeRespuesta`. **Verificá el estado** consultando `GET /api/v1/documento-electronico/status/:cdc`. ## Ejemplo en TypeScript [#ejemplo-en-typescript] ```typescript async function cancelarDocumento(cdc: string, motivo: string, idempotencyKey: string) { const response = await fetch( `https://api.sifende.com.py/api/v1/documento-electronico/${cdc}/cancelar`, { method: "POST", headers: { "Authorization": `Bearer ${process.env.SIFENDE_API_KEY}`, "Content-Type": "application/json", "Idempotency-Key": idempotencyKey, }, body: JSON.stringify({ motivo }), } ); if (!response.ok) { const error = await response.json(); throw new Error(`Cancelación fallida: ${error.detail}`); } const evento = await response.json(); if (evento.estadoEvento !== "APROBADO") { throw new Error(`Cancelación sin confirmar: ${evento.estadoEvento}. ${evento.mensajeRespuesta ?? ''}`); } return evento; } const cdc = "01800123451001001000000122026042710000000006"; const idempotencyKey = await obtenerOCrearClaveDeCancelacion(cdc); await cancelarDocumento( cdc, "Error en RUC del receptor", idempotencyKey ); ``` ## Después de cancelar [#después-de-cancelar] * El número de documento **no se libera**: queda registrado como cancelado en SIFEN * Si necesitás facturar nuevamente, emití un **nuevo DE** con el siguiente número de la secuencia * El KuDE original queda invalidado y no debe entregarse al cliente La cancelación NO consume un nuevo número de timbrado. Solo afecta al documento existente. ## Errores comunes [#errores-comunes] | Error | Causa | Solución | | ------------------------------------- | ----------------------------------------------- | ------------------------------------------------------------------------- | | `400 evento-cancelacion-error` | Plazo de cancelación vencido | Emití una Nota de Crédito en su lugar | | `404 documento-electronico-not-found` | CDC no existe | Verificá los 44 dígitos del CDC | | `400 evento-cancelacion-error` | El documento no está aprobado o venció el plazo | Revisá el estado y el detalle | | `409 evento-cancelacion-error` | Hay una cancelación activa para ese documento | Consultá el evento existente; no uses otra clave para evitar el conflicto | ## Recuperar una respuesta perdida [#recuperar-una-respuesta-perdida] El procedimiento de recuperación está en [Idempotencia y Reintentos Seguros](/docs/guias/idempotencia). En cancelación, el reintento reutiliza y, si corresponde, reenvía el evento original; no crea otro evento. Si el primer envío ya llegó a SIFEN, el reintento puede recibir `4003`: el CDC ya tiene registrada una cancelación. Sifende lo trata como éxito equivalente, deja el documento `CANCELADO`, conserva el código y mensaje para auditoría y puede devolver `protocoloAutorizacion: null`. Los reintentos posteriores reproducen esa respuesta sin volver a enviar. ## Próximos pasos [#próximos-pasos] * [Inutilizar Numeración](/docs/guias/inutilizar-numeracion): para números no emitidos * [Nota de Crédito](/docs/guias/nota-credito): alternativa cuando ya pasó el plazo * [Referencia: Cancelar](/docs/referencia/documentos-electronicos/cancelar) # Consultar Estado de un Documento (/docs/guias/consultar-estado) Guardá el CDC que recibiste al emitir y consultalo con la misma clave o con otra del mismo contribuyente y ambiente: ```bash curl "https://api.sifende.com.py/api/v1/documento-electronico/status/$CDC" \ -H "Authorization: Bearer $SIFENDE_API_KEY" ``` ## Respuesta [#respuesta] ```json { "cdc": "01800123451001001000000122026042710000000006", "estado": "APROBADO", "ambiente": "DEV", "iTiDe": 1, "numeroDocumento": 1, "fechaCreacion": "2026-04-27T10:30:00", "protocoloAutorizacion": "01202604150000123456", "mensajeRechazo": null } ``` | Campo | Tipo | Descripción | | ----------------------- | ---------------- | -------------------------------------------------------------------------------------------- | | `cdc` | `string` | Identificador de 44 dígitos del documento | | `estado` | `string` | Estado de procesamiento | | `ambiente` | `string` | Ambiente en que se emitió el documento: `DEV`, `PROD` o `SANDBOX`. No cambia | | `iTiDe` | `integer` | Tipo de documento: 1 para FE, 5 para NCE, 6 para NDE y 7 para NRE | | `numeroDocumento` | `integer` | Número correlativo del documento | | `fechaCreacion` | `datetime` | Fecha y hora de creación, sin zona horaria | | `protocoloAutorizacion` | `string \| null` | Protocolo de SIFEN en DEV/PROD; en SANDBOX, `SBX-` seguido del CDC | | `mensajeRechazo` | `string \| null` | Rechazos u observaciones, en formato `[código] mensaje`; varias entradas se separan por `\|` | El número con formato `001-001-0000001` se obtiene de `numeroFormateado` en la respuesta de emisión. En [SANDBOX](/docs/conceptos/ambientes#sandbox-de-sifende), la consulta puede pasar de `PENDIENTE` a `APROBADO` sin envío a SIFEN. El protocolo es `SBX-` seguido del CDC y no tiene validez fiscal. Los estados de envío y respuestas de SIFEN de esta tabla corresponden a DEV y PROD. ## Qué hacer con cada estado [#qué-hacer-con-cada-estado] | Estado | Qué significa | Qué hacer | | ---------------------- | -------------------------------------------------------- | ------------------------------------------------------------------ | | `PENDIENTE` | Sifende recibió el documento y está preparando su envío | Seguí consultando | | `EN_LOTE` | En proceso de envío o a la espera del resultado de SIFEN | Seguí consultando | | `APROBADO` | SIFEN aceptó el documento | Detené las consultas; guardá el protocolo | | `APROBADO_OBSERVACION` | SIFEN aceptó el documento con observaciones | Detené las consultas y revisá `mensajeRechazo`; no lo reemitas | | `RECHAZADO` | SIFEN rechazó el documento | Detené las consultas y corregí el motivo antes de emitir uno nuevo | | `CANCELADO` | Se confirmó la cancelación de un documento aprobado | Detené las consultas | | `ERROR` | El envío falló de forma definitiva | Detené las consultas y revisá el panel; no lo reemitas | Si después de varias horas sigue en `EN_LOTE`, puede pertenecer a un lote **Fallido**. Revisá **Historial de Lotes** en el detalle del documento y, si el lote está **Fallido**, seguí la [guía de reintento](/docs/panel/lotes). Conservá el mismo CDC. En `ERROR`, el documento no se reintenta solo. Pedí el reintento a [soporte](/docs/solucion-problemas/soporte) o seguí la [guía para reintentar el lote](/docs/panel/lotes). Al reintentarlo vuelve a `EN_LOTE` y podés retomar las consultas con el mismo CDC. ## Automatizar la consulta [#automatizar-la-consulta] Consultá cada **5 segundos** durante un máximo de **5 minutos**. Si sigue en proceso, guardá el CDC y retomá después. No reemitas por haber agotado el tiempo de espera. La guía de [Polling de resultados](/docs/guias/polling-resultados) incluye un ejemplo completo en TypeScript. También podés recibir [webhooks](/docs/referencia/webhooks). ## Rechazos y observaciones [#rechazos-y-observaciones] `mensajeRechazo` contiene el código y el mensaje de SIFEN. En un documento `RECHAZADO`, corregí la causa y [emití uno nuevo](/docs/guias/reintentar-rechazados). Si está `APROBADO_OBSERVACION`, guardá la observación: el documento ya quedó aceptado y no hay que reemitirlo. # Descargar KuDE (/docs/guias/descargar-kude) El **KuDE** (*Kuatia'i Documento Electrónico*) es la representación gráfica del documento electrónico: el PDF imprimible o adjuntable por email que entregás al cliente. No es el documento legal en sí mismo, pero es la versión legible para humanos. **El documento legal es el XML firmado**, no el KuDE. El cliente puede validar su factura escaneando el QR del KuDE, que apunta al portal SIFEN. En una NRE, el KuDE debe acompañar la mercadería durante el traslado. El KuDE de SANDBOX lleva el rótulo **SANDBOX — SIN VALIDEZ FISCAL**. Descargalo con una clave del mismo contribuyente y ambiente; el CDC y la ruta de descarga se usan igual que en los otros ambientes. ## Requisitos [#requisitos] * Para NRE, la descarga requiere `APROBADO` o `APROBADO_OBSERVACION`. Para los demás tipos, esperá la aprobación antes de entregar el comprobante al cliente. * Necesitás el **CDC** del documento. * Aplica a los tipos soportados: FE, AFE, NCE, NDE y NRE. ## El endpoint [#el-endpoint] ``` GET /api/v1/documento-electronico/:cdc/kude ``` Puede responder: * `200 application/pdf`: el body es el PDF. Guardalo o streamealo. * `202 application/json`: el PDF todavía está en preparación. Seguí el header `Location`, que apunta a la misma ruta con `soloConsulta=true`, y esperá al menos `Retry-After` segundos. * `500/503 application/problem+json`: error técnico clasificado por causa. `503 kude-unavailable` significa que el PDF no se pudo obtener en este intento. Seguí el `Location`; consultar no acelera la preparación. Si sigue en `202` después de 2 minutos, repetí una vez la descarga sin `soloConsulta`: el `Location` sólo consulta y no vuelve a pedir la preparación. Si después de otros 2 minutos sigue pendiente, dejá de consultar y contactá a soporte con el CDC. ## Descargar y guardar a disco (cURL) [#descargar-y-guardar-a-disco-curl] ```bash api_origin="https://api.sifende.com.py" url_inicial="$api_origin/api/v1/documento-electronico/$CDC/kude" url="$url_inicial" limite=$((SECONDS + 120)) volvio_a_pedir=0 while true; do status=$(curl -sS -D headers.txt -o respuesta.bin -w '%{http_code}' \ "$url" \ -H "Authorization: Bearer $SIFENDE_API_KEY") if [ "$status" = "200" ]; then mv respuesta.bin factura.pdf break fi if [ "$status" = "202" ]; then location=$(awk 'tolower($1)=="location:" {print $2}' headers.txt | tr -d '\r') sleep "$(awk 'tolower($1)=="retry-after:" {print $2}' headers.txt | tr -d '\r')" if [ "$SECONDS" -lt "$limite" ]; then url="$api_origin$location" elif [ "$volvio_a_pedir" = 0 ]; then volvio_a_pedir=1 url="$url_inicial" limite=$((SECONDS + 120)) else echo "KuDE pendiente por más de 4 minutos; contactá a soporte" >&2 exit 1 fi continue fi cat respuesta.bin >&2 exit 1 done ``` No uses `curl -o factura.pdf` sin revisar el status: si la API responde `202`, guardarías un JSON como si fuera PDF. ## Descargar desde Node.js / TypeScript [#descargar-desde-nodejs--typescript] Guardar el PDF en disco usando `fs/promises` sólo cuando la API devuelve `200 application/pdf`: ```typescript import { writeFile } from 'node:fs/promises'; type ProblemDetail = { type: string; title: string; status: number; detail: string; traceId?: string; }; async function esperar(ms: number): Promise { await new Promise(resolve => setTimeout(resolve, ms)); } async function descargarKuDE(cdc: string, destino: string): Promise { const urlInicial = `https://api.sifende.com.py/api/v1/documento-electronico/${cdc}/kude`; let url = urlInicial; let limite = Date.now() + 2 * 60_000; let volvioAPedir = false; for (;;) { const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.SIFENDE_API_KEY}` }, }); if (res.status === 200 && res.headers.get('content-type')?.includes('application/pdf')) { const buffer = Buffer.from(await res.arrayBuffer()); await writeFile(destino, buffer); return; } if (res.status === 202) { const location = res.headers.get('location'); if (!location) throw new Error('KuDE pendiente sin Location'); await res.json(); await esperar(Number(res.headers.get('retry-after') ?? '5') * 1000); if (Date.now() < limite) { url = new URL(location, url).toString(); } else if (!volvioAPedir) { volvioAPedir = true; url = urlInicial; limite = Date.now() + 2 * 60_000; } else { throw new Error('KuDE pendiente por más de 4 minutos; contactá a soporte'); } continue; } const problem = await res.json() as ProblemDetail; throw new Error(`No se pudo descargar KuDE (${problem.status}): ${problem.type}`); } } await descargarKuDE( '01800123451001001000000122026042710000000006', './kude/factura-001.pdf' ); ``` ## Stream a una respuesta HTTP (Express) [#stream-a-una-respuesta-http-express] Si tu servidor está sirviendo el KuDE al frontend o al cliente directamente, no streamees un `202` como PDF. Respondé `202` a tu propio cliente, o seguí el `Location` hasta obtener el `200`. ```typescript import express from 'express'; const app = express(); app.get('/facturas/:cdc/kude', async (req, res) => { let url = `https://api.sifende.com.py/api/v1/documento-electronico/${req.params.cdc}/kude`; const limite = Date.now() + 2 * 60_000; for (;;) { const upstream = await fetch(url, { headers: { Authorization: `Bearer ${process.env.SIFENDE_API_KEY}` }, }); if (upstream.status === 200 && upstream.headers.get('content-type')?.includes('application/pdf')) { res.setHeader('Content-Type', 'application/pdf'); res.setHeader('Content-Disposition', `inline; filename="factura-${req.params.cdc}.pdf"`); const reader = upstream.body!.getReader(); while (true) { const { value, done } = await reader.read(); if (done) break; res.write(value); } res.end(); return; } if (upstream.status === 202) { const location = upstream.headers.get('location'); if (!location) return res.status(502).json({ error: 'KuDE pendiente sin Location' }); await upstream.json(); if (Date.now() >= limite) return res.status(503).json({ error: 'KuDE todavía en preparación; reintentá más tarde' }); await new Promise(resolve => setTimeout(resolve, Number(upstream.headers.get('retry-after') ?? '5') * 1000)); url = new URL(location, url).toString(); continue; } return res.status(upstream.status).json(await upstream.json()); } }); ``` Usá `Content-Disposition: inline` para que se muestre embebido en el navegador, o `attachment; filename="..."` para forzar descarga. ## Adjuntar el KuDE a un email al cliente [#adjuntar-el-kude-a-un-email-al-cliente] Adjuntá sólo bytes obtenidos con `200 application/pdf`. Si el primer intento responde `202`, seguí el `Location`; si responde `500` o `503`, no envíes un correo sin adjunto y registrá el `traceId` para soporte. ## Errores frecuentes [#errores-frecuentes] | Status | Tipo | Causa | Solución | | ------ | --------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------- | | 403 | — (sin Problem Details) | La NRE no está en `APROBADO` ni `APROBADO_OBSERVACION` | Consultá su estado y esperá la aprobación sólo si sigue en proceso | | 404 | `documento-electronico-not-found` | Documento no encontrado o no accesible para esta clave | Verificá el CDC y el contribuyente | | 500 | `kude-generation-error` | Error técnico interno al preparar u obtener el PDF | No lo trates como problema del payload; contactá soporte con el `traceId` si persiste | | 501 | `kude-not-supported` | El tipo de documento no admite KuDE | Revisá el tipo; FE, AFE, NCE, NDE y NRE admiten KuDE | | 503 | `kude-unavailable` | No se pudo obtener el PDF en este intento | Reintentá más tarde si corresponde; ver [KuDE no disponible](/docs/solucion-problemas/kude-unavailable) | ## Buenas prácticas [#buenas-prácticas] * **No guardes un 202 como PDF.** Es JSON de estado pendiente. * **Seguí el `Location` recibido.** Ya incluye `soloConsulta=true` y conserva la ruta correcta. * **Poné un límite a la espera.** Si sigue pendiente después de 2 minutos, volvé a pedir la descarga sin `soloConsulta` una sola vez. * **No descargues KuDE en cada solicitud del cliente.** Conservá una copia después de recibir `200 application/pdf`. * **No mostrés KuDE de documentos no aprobados.** Pueden cambiar, y al cliente le confunde. * **Cacheá** el KuDE: una vez que el DE quedó registrado en SIFEN y el PDF existe, el contenido no cambia. * Si el QR del KuDE no resuelve en SIFEN, verificá que estés en el ambiente correcto (test vs producción). ## Próximos pasos [#próximos-pasos] * ¿Todavía no aprobaron tu DE? → [Consultar Estado](/docs/guias/consultar-estado). * Si tu cliente reporta problemas con el QR del KuDE, ver [FAQ](/docs/solucion-problemas/faq). * Detalles de la API → [Referencia: Descargar KuDE](/docs/referencia/documentos-electronicos/descargar-kude). # Factura Electrónica (/docs/guias/factura-electronica) Esta guía cubre la emisión de una Factura Electrónica (FE) paso a paso, desde el armado de la solicitud hasta el seguimiento del estado en SIFEN. ## Antes de empezar [#antes-de-empezar] Verificá que tenés los tres elementos imprescindibles configurados: * **Timbrado activo** y vigente, cargado en el panel de Sifende para tu contribuyente. * **Certificado digital** subido: `.p12` válido y en vigencia. * **API key** generada desde el panel y disponible como variable de entorno. Si te falta alguno, volvé a [Inicio Rápido: Requisitos previos](/docs/inicio-rapido/requisitos-previos). ## Paso 1: Armá la solicitud [#paso-1-armá-la-solicitud] La FE usa el endpoint polimórfico `POST /api/v1/documento-electronico` con `tipoDocumento: "FACTURA_ELECTRONICA"`. Los datos del **emisor** los completa Sifende automáticamente desde el contribuyente y el timbrado configurados. Vos solo pasás los datos del receptor, los ítems y la condición de pago. Ejemplo de FE B2C **innominada** (consumo final menos de Gs. 7.000.000) con un solo ítem gravado al 10%. El caso innominado se arma con `tipoContribuyente: "NO_CONTRIBUYENTE"` + `tipoDocumento: "INNOMINADO"`, y con los valores literales `"0"` en `numeroDocumento` y `"Sin Nombre"` en `nombreRazonSocial`: ```json { "tipoDocumento": "FACTURA_ELECTRONICA", "fechaEmision": "2026-04-27T10:30:00", "tipoEmision": "NORMAL", "numeroEstablecimiento": 1, "puntoExpedicion": 1, "tipoTransaccion": "VENTA_MERCADERIA", "monedaOperacion": "PYG", "receptor": { "tipoContribuyente": "NO_CONTRIBUYENTE", "tipoOperacion": "B2C", "tipoDocumento": "INNOMINADO", "numeroDocumento": "0", "nombreRazonSocial": "Sin Nombre" }, "condicionOperacion": "CONTADO", "condicionPago": { "tipo": "CONTADO", "tipoPago": "EFECTIVO", "monedaPago": "PYG", "montoPago": 150000 }, "items": [ { "codigo": "PROD-A4-75", "descripcion": "Resma de papel A4 75g", "cantidad": 10, "unidadMedida": "UNI", "precioUnitario": 15000, "afectacionTributaria": "GRAVADO", "tasaIVA": 10 } ] } ``` Los montos en guaraníes son **enteros sin decimales**. `15000` representa Gs. 15.000. Ver [Convenciones](/docs/referencia/convenciones). ## Paso 2: Enviá la solicitud [#paso-2-enviá-la-solicitud] ```bash curl -X POST https://api.sifende.com.py/api/v1/documento-electronico \ -H "Authorization: Bearer $SIFENDE_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $IDEMPOTENCY_KEY" \ -d @factura.json ``` ```typescript const idempotencyKey = await obtenerOCrearClaveDeEmision(ventaId); const response = await fetch( 'https://api.sifende.com.py/api/v1/documento-electronico', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.SIFENDE_API_KEY}`, 'Content-Type': 'application/json', 'Idempotency-Key': idempotencyKey, }, body: JSON.stringify(facturaPayload), } ); if (!response.ok) { const problem = await response.json(); throw new Error(`${problem.title}: ${problem.detail}`); } const { id, cdc, estado, statusUrl, kudeUrl } = await response.json(); console.log('CDC emitido:', cdc, ', estado inicial:', estado); ``` No generes una clave dentro de cada intento: otra clave representa una emisión nueva y puede reservar otro correlativo. Para recuperar una respuesta perdida, reutilizá la clave y el body persistidos. ## Paso 3: Guardá la respuesta [#paso-3-guardá-la-respuesta] La respuesta exitosa es **`202 Accepted`** con un body que incluye los identificadores del DE creado: ```json { "id": "550e8400-e29b-41d4-a716-446655440000", "cdc": "01800123451001001000000122026042710000000006", "estado": "PENDIENTE", "ambiente": "DEV", "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" } ``` **`estado: "PENDIENTE"` es lo esperado.** SIFEN procesa el documento de forma asíncrona: el CDC ya es válido, pero la aprobación llega en segundos a minutos. Pasá al Paso 4 para verificar. Guardá `id`, `cdc`, `numeroFormateado` y la `Idempotency-Key` asociados a tu venta. * Consultar el estado de procesamiento en SIFEN (usá `statusUrl` o el `cdc`). * Descargar el KuDE (PDF) cuando esté aprobado (usá `kudeUrl`). * Cancelar el documento si fuera necesario. ## Paso 4: Esperá el resultado de SIFEN [#paso-4-esperá-el-resultado-de-sifen] SIFEN procesa los documentos de forma **asíncrona**. Apenas recibís el CDC, el estado es `PENDIENTE` o `EN_LOTE`. El procesamiento tarda habitualmente entre 15 y 60 segundos, pero puede superar los 2 minutos en el ambiente de QA. Implementá polling con timeout de al menos 5 minutos. Los detalles de la estrategia de polling están en [Consultar Estado de un Documento](/docs/guias/consultar-estado). ## Más allá de la factura simple [#más-allá-de-la-factura-simple] La solicitud de este ejemplo cubre una venta al contado con un solo medio de pago. La misma factura admite, sin cambiar de endpoint: * **Varios medios de pago**, datos de tarjeta o cheque y medios `OTRO` descritos: usá [`pagos`](/docs/referencia/modelos/condicion-pago#forma-completa-pagos-y-credito). Al contado, los pagos deben cubrir exactamente el total. * **Crédito con cuotas o plazo**, en cualquier moneda, con entrega inicial. Las cuotas deben sumar el saldo financiado. * **Notas de remisión y facturas de anticipo asociadas**, con el anticipo aplicado global o por ítem: ver [Documentos asociados y anticipos](/docs/referencia/modelos/factura-electronica#documentos-asociados-y-anticipos). * **Datos del ítem** como GTIN, NCM, lote o vencimiento, ítems gravados parcialmente y vehículos nuevos: ver [Ítem](/docs/referencia/modelos/item). * **Presencia del comprador, datos comerciales, sectores** (energía, seguros, supermercado), **transporte y carga**: ver [Factura Electrónica](/docs/referencia/modelos/factura-electronica#campos-específicos-de-fe). Todo campo opcional que no aplica a tu operación se omite. ## Errores frecuentes en este flujo [#errores-frecuentes-en-este-flujo] | Status | Tipo | Causa más común | Cómo resolverlo | | ------ | -------------------------- | ---------------------------------------------------------------- | -------------------------------------------------- | | 400 | `validation-error` | Falta un campo obligatorio o un valor está mal formateado | Revisá `errores` en la respuesta | | 400 | `invalid-enum-value` | Valor de enum no reconocido (ej: `"INVOICE"` en `tipoDocumento`) | Revisá `valoresAceptados` en la respuesta | | 401 | JSON de autenticación | API key inválida o revocada | Rotá la credencial desde el panel, en **API Keys** | | 422 | `configuracion-incompleta` | No hay timbrado configurado para este contribuyente | Cargá el timbrado en el panel | Para recuperar un timeout o interpretar errores de idempotencia, ver [Idempotencia y Reintentos Seguros](/docs/guias/idempotencia). Para el listado completo, ver [Manejar Errores](/docs/guias/manejar-errores) y [Rechazos SIFEN](/docs/solucion-problemas/rechazos-sifen). ## Próximos pasos [#próximos-pasos] * ¿Estás facturando a una empresa con RUC? → [Receptor B2B y B2C](/docs/guias/receptor-b2b-b2c). * ¿Necesitás anular o ajustar una FE aprobada? → [Nota de Crédito](/docs/guias/nota-credito). * ¿Querés entregar el comprobante al cliente? → [Descargar KuDE](/docs/guias/descargar-kude). # Idempotencia y Reintentos Seguros (/docs/guias/idempotencia) `Idempotency-Key` identifica una intención tributaria. Permite repetir una emisión, cancelación, inutilización o nominación después de perder la respuesta sin crear una operación distinta. Una clave ya registrada siempre devuelve la operación original, aunque cambies el body o el CDC. Si reutilizás una clave por error, no recibís un error: recibís el documento anterior. Generá una clave nueva para cada intención. ## Operaciones soportadas [#operaciones-soportadas] | Operación | Endpoint | | ------------- | -------------------------------------------------- | | Emisión | `POST /api/v1/documento-electronico` | | Cancelación | `POST /api/v1/documento-electronico/:cdc/cancelar` | | Inutilización | `POST /api/v1/documento-electronico/inutilizar` | | Nominación | `POST /api/v1/documento-electronico/:cdc/nominar` | El header es opcional. Incluilo para obtener estas garantías. La clave se identifica por contribuyente y ambiente y se comparte entre estas operaciones: una misma clave conserva la operación original. Usarla para otro tipo de operación produce `422 idempotency-key-reused` (por ejemplo, emitir y después cancelar). En SANDBOX podés usar idempotencia para emitir. Cancelación, inutilización y nominación devuelven [`422 sandbox-operation-not-supported`](/docs/solucion-problemas/sandbox-operation-not-supported); cambiar la clave no habilita esas operaciones. ## Antes del primer intento [#antes-del-primer-intento] 1. Generá un UUID v4 por intención. 2. Persistí la clave junto con la operación, la URL y el body exacto **antes** del primer `POST`. 3. Enviá la clave en `Idempotency-Key`. 4. Guardá la respuesta y los identificadores tributarios asociados. ```http Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000 ``` Para recuperar la operación, leé esos valores guardados: no reconstruyas la solicitud desde datos que pudieron cambiar. ## Qué ocurre si cambia el reintento [#qué-ocurre-si-cambia-el-reintento] Si una factura de ₲100.000 se registró con `abc`, enviar otra de ₲200.000 con `abc` recupera la operación de ₲100.000: no modifica el documento ni consume otro correlativo. En cancelación o nominación, cambiar el CDC tampoco cambia el documento de la operación original; los eventos pendientes se recuperan con sus datos guardados. Si la respuesta trae un CDC o un número que no esperabas, la clave ya estaba usada: revisá cómo generás las claves. Sifende sigue verificando la autenticación, el contribuyente, el ambiente y el tipo de operación. Con una clave ya registrada, el body sólo tiene que ser JSON válido con los tipos correctos (si no, `400`); no se revalidan campos obligatorios ni formatos. Con una clave nueva o sin clave, la validación es completa. ## Cuándo repetir la solicitud [#cuándo-repetir-la-solicitud] Repetí exactamente la misma solicitud con la misma clave en estos casos: * Timeout, reset o conexión cortada sin respuesta HTTP * `409 idempotency-in-progress` * `503 idempotency-upstream-unknown` En los errores de idempotencia, `Retry-After` aparece en `idempotency-in-progress` e `idempotency-upstream-unknown`. La nominación también puede devolver `503 evento-nominacion-error` con `Retry-After: 2`. Esperá ese intervalo antes del reintento. ## Cuándo detenerse [#cuándo-detenerse] | Respuesta | Acción | | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | `409 idempotency-outcome-unknown` | Detené el flujo. El resultado es indeterminado y terminal; no reenvíes ni cambies la clave | | `409 idempotency-key-expired` | Detené el flujo. El replay venció, pero la clave sigue reservada | | `422 idempotency-key-reused` | La clave ya se usó para otro tipo de operación. Para recuperar esa operación, usá su endpoint. Para una operación nueva, generá otra clave | No generes otra clave para recuperar la misma intención: una clave nueva representa una operación nueva. ## Resultado según la operación [#resultado-según-la-operación] | Operación | Garantía del reintento | | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Emisión | Reproduce el mismo `202`, documento, CDC, correlativo y `Location`; no consume otro número | | Cancelación | Reutiliza el evento original. `0600` confirma la cancelación; `4003` se acepta como éxito equivalente porque el CDC ya tiene una cancelación registrada | | Nominación | Recupera el evento, documento, motivo y receptor originales; no sustituye el receptor con el del reintento | | Inutilización | Reutiliza el evento original. `0600` confirma la inutilización; `4066` deja el evento `INDETERMINADA` porque sólo prueba que el rango contiene números ya inutilizados, no que todo el rango coincida con esta intención | En cancelación, un reintento que recibe `4003` deja el documento `CANCELADO`, conserva el código y mensaje para auditoría y puede responder `protocoloAutorizacion: null`. Los reintentos siguientes reproducen ese resultado sin volver a enviar el evento. En inutilización, `4066` produce `409 idempotency-outcome-unknown`. No reenvíes con la misma clave ni con otra: el evento queda `INDETERMINADA` y el rango permanece protegido. ## Cuánto dura una clave [#cuánto-dura-una-clave] Sifende guarda el replay durante 7 días desde la finalización: status, body y headers como `Location`. Dentro de ese plazo, la misma clave y tipo de operación reciben la respuesta original. Después de 7 días, el replay deja de estar disponible, pero la clave sigue reservada: el mismo tipo de operación devuelve `409 idempotency-key-expired` aunque cambie el contenido. Otro tipo de operación sigue devolviendo `422 idempotency-key-reused`. Un documento archivado no bloquea el replay ni la recuperación de un evento pendiente ya registrado. Cuando termina la [conservación del documento](/docs/plataforma/planes), su clave se libera y una solicitud con esa clave se trata como nueva. Por eso nunca recicles claves. ## Fallos sin clave [#fallos-sin-clave] Un 5xx en un `POST` sin `Idempotency-Key` no demuestra que la operación haya fallado sin efectos. No reenvíes a ciegas: investigá primero el estado del recurso. Para el catálogo general y el campo `resultadoIndeterminado`, ver [Manejar Errores](/docs/guias/manejar-errores). ## Guías por operación [#guías-por-operación] * [Emitir una Factura Electrónica](/docs/guias/factura-electronica) * [Cancelar un Documento](/docs/guias/cancelar-documento) * [Inutilizar Numeración](/docs/guias/inutilizar-numeracion) # Guías (/docs/guias) Cada guía está orientada a una tarea concreta. Seguí el orden si estás integrando por primera vez, o saltá a la que necesités. Muchas de estas operaciones también están disponibles vía la [Sifende CLI](/docs/herramientas/sifende-cli), útil para pruebas rápidas. ## Flujo principal [#flujo-principal] 1. [Factura Electrónica](/docs/guias/factura-electronica): emitir una FE completa 2. [Idempotencia y Reintentos Seguros](/docs/guias/idempotencia): persistir una intención y recuperar respuestas perdidas 3. [Receptor B2B / B2C](/docs/guias/receptor-b2b-b2c): facturar a otro contribuyente 4. [Consultar Estado](/docs/guias/consultar-estado): verificar aprobación SIFEN 5. [Manejar Errores](/docs/guias/manejar-errores): qué hacer cuando algo falla ## Documentos adicionales [#documentos-adicionales] * [Nota de Crédito](/docs/guias/nota-credito) * [Nota de Débito](/docs/guias/nota-debito) * [Nota de Remisión](/docs/guias/nota-remision) * [Autofactura](/docs/guias/autofactura) ## Operaciones avanzadas [#operaciones-avanzadas] * [Descargar KuDE](/docs/guias/descargar-kude) * [Cancelar Documento](/docs/guias/cancelar-documento) * [Nominar una factura innominada](/docs/guias/nominar-factura) * [Inutilizar Numeración](/docs/guias/inutilizar-numeracion) * [Polling de Resultados](/docs/guias/polling-resultados) * [Moneda Extranjera](/docs/guias/moneda-extranjera) * [Múltiples Establecimientos](/docs/guias/multiples-establecimientos) * [Reintentar Rechazados](/docs/guias/reintentar-rechazados) * [Ir a Producción](/docs/guias/ir-a-produccion) ## Configurar desde el panel [#configurar-desde-el-panel] Consultá las [guías del panel](/docs/panel) para administrar las API keys, el certificado, el CSC, el timbrado y el acceso de tu equipo. # Inutilizar Numeración (/docs/guias/inutilizar-numeracion) SIFEN exige que la numeración de documentos sea **secuencial y sin huecos**. Cuando se generan brechas (por errores de sistema, pruebas, fallos de emisión), debés inutilizar formalmente esos números para mantener la integridad del timbrado. ## Cuándo inutilizar [#cuándo-inutilizar] Inutilizá una numeración cuando: * Tenés un hueco en la secuencia de un timbrado activo * Un documento fue rechazado y su número quedó sin utilizar * Cambiaste de timbrado y querés cerrar el rango anterior La inutilización es **irreversible**. Los números marcados como inutilizados quedan registrados en SIFEN para siempre y no podrán reutilizarse. ## Cómo inutilizar un rango [#cómo-inutilizar-un-rango] **Identificá el rango** que querés inutilizar: desde qué número hasta qué número, dentro de un mismo establecimiento y punto de expedición. **Enviá el evento de inutilización** con el rango y motivo: ```bash curl -X POST "https://api.sifende.com.py/api/v1/documento-electronico/inutilizar" \ -H "Authorization: Bearer sk_live_..." \ -H "Idempotency-Key: $IDEMPOTENCY_KEY" \ -H "Content-Type: application/json" \ -d '{ "numeroTimbrado": 12557896, "establecimiento": "001", "puntoExpedicion": "001", "numeroInicio": "0000025", "numeroFin": "0000030", "tipoDocumento": 1, "motivo": "Números no utilizados por error de sistema" }' ``` | Campo | Tipo | Req. | Restricción | | ----------------- | --------- | ---- | ------------------------------------- | | `numeroTimbrado` | `integer` | Sí | Número de timbrado SET | | `establecimiento` | `string` | Sí | Código de 3 caracteres (ej.: `"001"`) | | `puntoExpedicion` | `string` | Sí | Código de 3 caracteres (ej.: `"001"`) | | `numeroInicio` | `string` | Sí | 1-7 caracteres | | `numeroFin` | `string` | Sí | 1-7 caracteres | | `tipoDocumento` | `integer` | Sí | Código numérico del tipo de documento | | `motivo` | `string` | Sí | 5-500 caracteres | | `serie` | `string` | No | Máximo 2 caracteres | **Revisá la respuesta del evento.** Un HTTP `200` también puede contener `estadoEvento: "RECHAZADO"`. Sólo `APROBADO` confirma la inutilización. **Conservá el resultado.** Guardá la confirmación del evento junto con el rango inutilizado. ## Ejemplo en TypeScript [#ejemplo-en-typescript] ```typescript async function inutilizarNumeracion(rango: { numeroTimbrado: number; establecimiento: string; puntoExpedicion: string; numeroInicio: string; numeroFin: string; motivo: string; }, idempotencyKey: string) { const response = await fetch( "https://api.sifende.com.py/api/v1/documento-electronico/inutilizar", { method: "POST", headers: { "Authorization": `Bearer ${process.env.SIFENDE_API_KEY}`, "Content-Type": "application/json", "Idempotency-Key": idempotencyKey, }, body: JSON.stringify({ tipoDocumento: 1, // 1 = FACTURA_ELECTRONICA ...rango, }), } ); if (!response.ok) { const error = await response.json(); throw new Error(`Inutilización fallida: ${error.detail}`); } const evento = await response.json(); if (evento.estadoEvento !== "APROBADO") { throw new Error(`Inutilización sin confirmar: ${evento.estadoEvento}. ${evento.mensajeRespuesta ?? ''}`); } return evento; } const idempotencyKey = await obtenerOCrearClaveDeInutilizacion(solicitudId); await inutilizarNumeracion({ numeroTimbrado: 12557896, establecimiento: "001", puntoExpedicion: "001", numeroInicio: "0000025", numeroFin: "0000030", motivo: "Números no utilizados por error de sistema", }, idempotencyKey); ``` ## Buenas prácticas [#buenas-prácticas] * **Inutilizá pronto.** No dejes huecos abiertos por más de unos días, dificulta auditorías. * **Documentá el motivo internamente.** El campo `motivo` queda en SIFEN, pero también guardá un registro propio. * **Verificá antes de inutilizar.** Confirmá que los números efectivamente no se emitieron. Si ya hay un DE con ese número, la inutilización fallará. ## Restricciones [#restricciones] | Restricción | Detalle | | ----------------------------- | -------------------------------------------------------------------------- | | Solo números no emitidos | No podés inutilizar un número ya usado en un DE existente | | Mismo establecimiento + punto | El rango debe estar dentro del mismo `establecimiento` y `puntoExpedicion` | | Timbrado activo | El timbrado al que pertenecen los números debe seguir vigente | ## Errores comunes [#errores-comunes] | Error | Causa | Solución | | -------------------------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------- | | `400 evento-inutilizacion-error` | `numeroFin` no es mayor que `numeroInicio`, o su diferencia supera 1.000 | Verificá el orden del rango | | `400 evento-inutilizacion-error` | Tipo de documento inválido | Usá el código numérico del tipo de documento | | `409 evento-inutilizacion-error` | Hay una inutilización activa para el mismo rango | Consultá el evento existente; no uses otra clave para evitar el conflicto | ## Recuperar una respuesta perdida [#recuperar-una-respuesta-perdida] El procedimiento de recuperación está en [Idempotencia y Reintentos Seguros](/docs/guias/idempotencia). En inutilización, `0600` confirma el resultado; `4066` deja el evento `INDETERMINADA` y exige detener los envíos. ## Próximos pasos [#próximos-pasos] * [Cancelar Documento](/docs/guias/cancelar-documento): para documentos ya emitidos * [Reintentar Rechazados](/docs/guias/reintentar-rechazados): flujo después de un rechazo * [Referencia: Inutilizar](/docs/referencia/documentos-electronicos/inutilizar) # Ir a Producción (/docs/guias/ir-a-produccion) Para emitir documentos con validez fiscal, prepará la configuración de producción y creá una API key `sk_live_`. La URL base sigue siendo `https://api.sifende.com.py`. Si probaste en SANDBOX, verificá también la integración en DEV con una clave `sk_test_`: la aprobación de Sandbox no es una respuesta de SIFEN. ## Preparar las credenciales [#preparar-las-credenciales] 1. Verificá la habilitación del contribuyente para producción. El panel ofrece **Pasar a Producción** y muestra los requisitos antes de **Activar producción**. 2. En **Contribuyente → Certificado digital**, verificá que el certificado esté activo y vigente. Es el mismo que usaste en pruebas; lo emite un prestador de servicios de certificación autorizado. 3. Configurá el **CSC de producción** y su **ID CSC** en esa pantalla. Los valores de pruebas y producción se guardan por separado. 4. En **Contribuyente → Timbrado**, elegí producción y cargá **Número de Timbrado** y **Fecha de Inicio**, exactamente como figuran ante la SET. 5. En **API Keys → Crear API Key**, elegí **PROD — Documentos con validez fiscal**. El panel no crea la clave si falta la habilitación, el timbrado vigente, el CSC de producción o el certificado activo. 6. Copiá la clave y reemplazá la variable `SIFENDE_API_KEY` de tu integración. ```bash SIFENDE_API_KEY=sk_live_... ``` El cambio de ambiente no requiere cambiar la URL ni el código de integración. Los establecimientos y puntos se envían en cada emisión. ## Checklist de integración [#checklist-de-integración] * [ ] Probaste los flujos que usás con una clave `sk_test_`. * [ ] Guardás el CDC y el resultado de cada emisión. * [ ] Consultás el estado o procesás webhooks sin emitir otra vez por un timeout. * [ ] Usás [Idempotency-Key](/docs/guias/idempotencia) para reintentar una operación con la misma clave y contenido. * [ ] Respetás `Retry-After` y distinguís errores de validación de resultados indeterminados. * [ ] Revisás los rechazos y las observaciones de SIFEN. * [ ] Descargás el KuDE y verificás los datos del documento. * [ ] Protegés las claves y tenés previsto cómo reemplazarlas. Las facturas a crédito están disponibles en PYG, con modalidades `PLAZO` y `CUOTA`. Consultá [Condición de pago](/docs/referencia/modelos/condicion-pago). ## Flujos a probar [#flujos-a-probar] En DEV, probá cada flujo que use tu integración: * [ ] Factura B2C, incluida la modalidad innominada cuando corresponda. * [ ] Factura B2B con RUC y datos completos del receptor. * [ ] Nota de Crédito sobre una factura aprobada. * [ ] Nota de Débito sobre una factura aprobada. * [ ] Cancelación de un documento aprobado dentro del plazo permitido. * [ ] Inutilización de numeración no utilizada. * [ ] Corrección y reemisión después de un rechazo. * [ ] Descarga y revisión del KuDE PDF. Si usás crédito, NRE o nominación, incluí también esos flujos en las pruebas. ## Comprobar la primera operación [#comprobar-la-primera-operación] Emití una operación real, verificá que termine en `APROBADO` o `APROBADO_OBSERVACION` y revisá su KuDE. Verificá también que el documento aparezca en el portal e-Kuatia del ambiente correspondiente. Los documentos enviados con `sk_live_` tienen efecto fiscal: hacé las pruebas de integración con `sk_test_`. Si recibís rechazos, revisá `mensajeRechazo` antes de continuar. Ante un resultado incierto, conservá el CDC y consultá su estado. Si necesitás ayuda, [contactá a soporte](/docs/solucion-problemas/soporte). ## Monitorear las primeras emisiones [#monitorear-las-primeras-emisiones] Durante las primeras **24 a 48 horas**, revisá activamente los resultados, los rechazos, las observaciones y el tiempo hasta la aprobación. Es una recomendación de seguimiento de tu integración, no un plazo de procesamiento de SIFEN. ## Si algo sale mal [#si-algo-sale-mal] * Ante rechazos masivos, frená las nuevas emisiones del flujo afectado y revisá el código y el texto de `mensajeRechazo` antes de continuar. * Si hay un timeout o un resultado incierto, conservá la intención de emisión y el CDC que hayas recibido. Seguí la [guía de idempotencia](/docs/guias/idempotencia); no generes otra emisión para intentar obtener una respuesta. * Si el documento está `ERROR` o sigue en `EN_LOTE` después de varias horas, revisá la [guía de reintento de lotes](/docs/panel/lotes). * Si necesitás ayuda, contactá a [soporte](/docs/solucion-problemas/soporte) con el CDC y el error recibido, sin compartir claves ni contraseñas. ## Guías del panel [#guías-del-panel] * [Certificado y CSC](/docs/panel/certificado-y-csc) * [Timbrado](/docs/panel/timbrado) * [API keys y cambio sin corte](/docs/panel/api-keys) * [Personalización del correo](/docs/panel/personalizacion) # Manejar Errores (/docs/guias/manejar-errores) Esta guía explica cómo distinguir los distintos tipos de error que recibís de Sifende, qué hacer con cada uno y cuándo (no) reintentar. ## Dos fuentes de error muy distintas [#dos-fuentes-de-error-muy-distintas] Mezclarlas en un mismo `catch` es una de las primeras causas de bugs en integraciones SIFEN. | Fuente | Cuándo aparece | Cómo se ve | | ----------------------------- | ------------------------------------------------------ | --------------------------------------------------------- | | **API Sifende** | Inmediato, en el HTTP response | Status 400/401/403/404/422 + Problem Details JSON | | **SIFEN (rechazo asíncrono)** | Después del polling, cuando SIFEN procesa el documento | `estado: "RECHAZADO"` + `mensajeRechazo` con código SIFEN | ## Errores de la API Sifende (síncronos) [#errores-de-la-api-sifende-síncronos] Sigan el formato **RFC 9457 Problem Details** (excepto autenticación): ```json { "type": "https://sifende.com.py/docs/solucion-problemas/validation-error", "title": "Error de validación", "status": 400, "detail": "La solicitud contiene 2 error(es) de validación", "errores": { "receptor.numeroDocumento": "Número de documento es obligatorio", "items[0].precioUnitario": "El precio no puede ser negativo" } } ``` ### Cómo manejarlos en código [#cómo-manejarlos-en-código] ```typescript const idempotencyKey = await obtenerOCrearClaveIdempotencia(ventaId); const DOCUMENT_QUOTA_EXCEEDED = 'https://sifende.com.py/docs/solucion-problemas/document-quota-exceeded'; const res = await fetch('https://api.sifende.com.py/api/v1/documento-electronico', { method: 'POST', headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json', 'Idempotency-Key': idempotencyKey, }, body: JSON.stringify(payload), }); if (!res.ok) { const problem = await res.json(); if (problem.type === DOCUMENT_QUOTA_EXCEEDED) { console.error('Sin cupo disponible:', { confirmados: problem.consumoConfirmado, reservas: problem.reservasActivas, finPeriodo: problem.finPeriodo, }); throw new CupoAgotadoError(problem); } if (problem.type?.includes('validation-error')) { for (const [campo, mensaje] of Object.entries(problem.errores ?? {})) { console.error(`Campo inválido: ${campo} → ${mensaje}`); } throw new ValidacionError(problem); } if (problem.type?.includes('invalid-enum-value')) { console.error(`Valor inválido en ${problem.campo}. Aceptados:`, problem.valoresAceptados); throw new EnumError(problem); } throw new ApiError(problem); } const { cdc } = await res.json(); ``` ### Tabla rápida de tipos [#tabla-rápida-de-tipos] | Status | Tipo | Acción | | ------ | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | 400 | `validation-error` | Revisar `errores` por campo, corregir y reenviar | | 400 | `invalid-enum-value` | Usar uno de `valoresAceptados` | | 400 | `invalid-format` | Corregir el campo indicado en `campo` — mirá `tipoEsperado` y `valorRecibido` | | 401 | JSON de autenticación | API key inválida/expirada. Rotá la credencial desde el panel | | 403 | `document-quota-exceeded` | La emisión no se ejecutó. No reintentes en un loop; esperá a liberar capacidad, al siguiente período o cambiá de plan | | 403 | Sin `type` de operación | Revisá los permisos y el ambiente de la clave | | 404 | `*-not-found` | Recurso inexistente. Verificar IDs | | 405 | `method-not-allowed` | Método HTTP incorrecto para ese endpoint | | 409 | `idempotency-in-progress` | Esperá `Retry-After` y repetí exactamente la misma solicitud con la misma clave | | 409 | `idempotency-outcome-unknown` | Resultado terminal indeterminado. Detenete: no reenvíes ni cambies la clave | | 409 | `idempotency-key-expired` | Venció el replay de 7 días. La clave sigue reservada y no puede reutilizarse | | 415 | `unsupported-media-type` | Mandá `Content-Type: application/json` | | 422 | `configuracion-incompleta` | Falta configuración de la cuenta (`campo` + `accion` dicen cuál). Reintentar no ayuda | | 422 | `documento-electronico-generation-error` | El documento no cumple una regla fiscal | | 422 | `idempotency-key-reused` | La clave ya pertenece a otro tipo de operación. No la recicles | | 503 | `idempotency-upstream-unknown` | Esperá `Retry-After` y repetí exactamente la misma solicitud con la misma clave | Catálogo completo en [Errores](/docs/referencia/errores). ## Rechazos SIFEN (asíncronos) [#rechazos-sifen-asíncronos] Después de emitir, el documento queda en `PENDIENTE` o `EN_LOTE`. Una vez procesado, SIFEN devuelve un código con la respuesta. Los más frecuentes en producción: | Código SIFEN | Significado | Cómo corregirlo | | ------------ | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 1107 | Fecha de inicio de vigencia del timbrado incorrecta | Cargá en Sifende la `fechaInicio` exacta registrada en la SET | | 1302 | Falta `tipoContribuyente` del receptor para B2B | Completar `tipoContribuyente: "CONTRIBUYENTE"` | | 1303 | Se informó `tipoContribuyenteReceptor` cuando el receptor es `NO_CONTRIBUYENTE` | Sacá `tipoContribuyenteReceptor`; `tipoContribuyente` va siempre | | 1304 | Falta `numeroDocumento` (RUC) para receptor contribuyente | Completar el RUC del receptor | | 1305 | Se informó el RUC del receptor cuando el receptor es `NO_CONTRIBUYENTE` | `numeroDocumento` no se elimina: es obligatorio y en B2C viaja como CI/pasaporte. Verificá que no estés mandando datos de RUC/contribuyente para un receptor no contribuyente | | 1306 | RUC del receptor inexistente en Marangatu (RUC no registrado en SET) | Confirmar el RUC con tu cliente | | 1309 | DV del RUC del receptor incorrecto | Verificar `digitoVerificador` | | 2026 | CDC asociado no existe o no está aprobado | Solo emitir NCE/NDE sobre FE en estado `APROBADO` o `APROBADO_OBSERVACION` | Tabla completa: [Rechazos SIFEN](/docs/solucion-problemas/rechazos-sifen). ### Cómo leer el rechazo [#cómo-leer-el-rechazo] El campo `mensajeRechazo` del status response contiene el código y la descripción: ```typescript const resultado = await esperarResultadoSIFEN(cdc); if (resultado.estado === 'RECHAZADO') { // Ej: "[1107] Fecha de inicio de vigencia del timbrado incorrecta | [1302] Falta tipoContribuyente" const codigo = resultado.mensajeRechazo?.match(/\[(\d+)\]/)?.[1]; log.warn({ cdc, codigo, motivo: resultado.mensajeRechazo }, 'DE rechazado por SIFEN'); } ``` ## Cuándo reintentar (y cuándo no) [#cuándo-reintentar-y-cuándo-no] | Situación | ¿Reintentar? | Cómo | | --------------------------------------------------------------------------------------- | :----------: | ---------------------------------------------------------------------------------------------------------------------------------------------- | | 5xx en un `GET` (consulta) | ✅ | Backoff exponencial (1s, 2s, 4s…), máximo 3 intentos | | Timeout, reset o conexión cortada antes de recibir una respuesta de un `POST` con clave | ✅ | Repetí exactamente la misma solicitud con la misma `Idempotency-Key` | | `409 idempotency-in-progress` | ✅ | Esperá `Retry-After` y repetí la misma solicitud con la misma clave | | `503 idempotency-upstream-unknown` | ✅ | Esperá `Retry-After` y repetí la misma solicitud con la misma clave | | `409 idempotency-outcome-unknown` | ❌ | Detenete. El resultado es indeterminado y terminal; no reenvíes ni cambies de clave | | `409 idempotency-key-expired` | ❌ | El replay venció y la clave sigue reservada; no la recicles | | 5xx en un `POST` sin clave | ⚠️ | **Consultá el estado antes de reenviar** — ver abajo | | `403 document-quota-exceeded` | ❌ inmediato | No hubo efecto. Reintentá solo cuando un rechazo libere capacidad, comience otro período o cambie el plan; las reservas no son consumo cobrado | | 401 / 403 de permisos | ❌ | Arreglá credenciales o permisos, no reintentes con la misma configuración | | 400 `validation-error` | ❌ | Corregí los datos antes de reenviar | | 422 `configuracion-incompleta` | ❌ | Completá lo que indica `campo` en el panel; reintentar no cambia nada | | 404 `documento-electronico-not-found` | ❌ | El CDC no existe; no aparecerá reintentando | | Rechazo SIFEN | ⚠️ | **Emití un DE nuevo** con los datos corregidos. El original queda rechazado para siempre | Para el contrato completo —creación y persistencia de claves, decisiones de reintento, diferencias entre las operaciones y reserva de claves— ver [Idempotencia y Reintentos Seguros](/docs/guias/idempotencia). **Un 5xx en un `POST` sin `Idempotency-Key` no significa que la operación no ocurrió.** Si reenviás a ciegas y la primera solicitud sí produjo un efecto, podés duplicar una emisión o un evento tributario. El problem detail indica este riesgo con `resultadoIndeterminado`: ```json { "status": 500, "type": "https://sifende.com.py/docs/solucion-problemas/internal-error", "detail": "Ocurrió un error inesperado y el resultado de la operación es indeterminado...", "resultadoIndeterminado": true, "accion": "Consultá el estado del recurso antes de reenviar...", "traceId": "f2f0333f78bfb6a4184cb5a5374685a5" } ``` Con `resultadoIndeterminado: true`, investigá el resultado antes de reenviar. Con `false` en una consulta `GET`, la operación no tocó datos y el reintento es seguro. ## Recomendaciones de logging [#recomendaciones-de-logging] En tu integración, logueá siempre: * `cdc`, para correlacionar con tu sistema. * `estado` y `mensajeRechazo` cuando consultes status. * `type`, `title`, `status` y `detail` del Problem Details ante errores. * El **cuerpo de la solicitud completo** en errores 4xx (excepto la API key); facilita reproducir el problema. ```typescript log.error({ cdc, estado: resultado.estado, mensajeRechazo: resultado.mensajeRechazo, }, 'DE rechazado'); ``` ## Próximos pasos [#próximos-pasos] * Para reintentar después de un rechazo, ver [Reintentar Rechazados](/docs/guias/reintentar-rechazados). * Para ver el catálogo de códigos SIFEN, ver [Rechazos SIFEN](/docs/solucion-problemas/rechazos-sifen). * Para problemas con certificados y firmado, ver [Certificado Digital](/docs/solucion-problemas/certificado-digital). # Facturar en Moneda Extranjera (/docs/guias/moneda-extranjera) SIFEN permite emitir documentos en moneda extranjera (USD, EUR, BRL, ARS, etc.) con tipo de cambio GLOBAL o POR\_ITEM y reportar los equivalentes en guaraníes. Esta guía explica cómo configurarla correctamente. ## Conceptos clave [#conceptos-clave] | Campo API | Descripción | Ejemplo | | -------------------------- | -------------------------------------------------------------------------- | ------------ | | `monedaOperacion` | Código ISO de la moneda de operación | `USD`, `EUR` | | `tipoCambio` | Tipo de cambio GLOBAL: cantidad de PYG por una unidad de moneda extranjera | `7135.1256` | | `items[].tipoCambio` | Tipo de cambio POR\_ITEM, obligatorio en todos los ítems de esa modalidad | `7100.1111` | | `condicionPago.tipoCambio` | Tipo de cambio de la moneda extranjera del pago | `7130.5000` | La cotización comprador o vendedor publicada por el BCP es una referencia para tu política contable y fiscal. Sifende valida la presencia y el formato del tipo de cambio, no que coincida con una cotización específica del BCP. ## Cómo obtener el tipo de cambio [#cómo-obtener-el-tipo-de-cambio] * **BCP (oficial):** [https://www.bcp.gov.py](https://www.bcp.gov.py) publica diariamente las cotizaciones * Elegí la cotización **comprador** o **vendedor** según tu política contable y el criterio de tu contador * Guardá el tipo de cambio usado junto con el DE para auditoría ## Ejemplo: factura en USD [#ejemplo-factura-en-usd] ```json { "tipoDocumento": "FACTURA_ELECTRONICA", "fechaEmision": "2026-04-15T10:30:00", "tipoEmision": "NORMAL", "numeroEstablecimiento": 1, "puntoExpedicion": 1, "monedaOperacion": "USD", "tipoCambio": 7300, "tipoTransaccion": "PRESTACION_SERVICIOS", "condicionOperacion": "CONTADO", "receptor": { "tipoContribuyente": "CONTRIBUYENTE", "tipoOperacion": "B2B", "tipoContribuyenteReceptor": "PERSONA_JURIDICA", "numeroDocumento": "80012345", "digitoVerificador": "0", "nombreRazonSocial": "Comercial Guaraní S.A." }, "condicionPago": { "tipo": "CONTADO", "tipoPago": "TRANSFERENCIA", "monedaPago": "USD", "tipoCambio": 7300, "montoPago": 1200 }, "items": [ { "codigo": "SRV-001", "descripcion": "Licencia de software anual", "cantidad": 1, "unidadMedida": "UNI", "precioUnitario": 1200, "afectacionTributaria": "GRAVADO", "tasaIVA": 10 } ] } ``` En este caso: * El precio del ítem (`1200`) está en **USD** * Sifende calcula automáticamente el equivalente en PYG: `1200 × 7300 = 8.760.000 PYG` * El KuDE muestra ambos valores: USD (operación) y PYG (referencia) ## Cálculo de IVA [#cálculo-de-iva] El IVA siempre se calcula sobre el monto en moneda de operación (USD en este caso), pero también se reporta su equivalente en PYG: | Concepto | USD | PYG | | --------- | ------------ | ------------- | | Subtotal | 1.090,91 | 7.963.636 | | IVA 10% | 109,09 | 796.364 | | **Total** | **1.200,00** | **8.760.000** | Sifende hace estos cálculos automáticamente; solo enviá los precios en moneda extranjera. En moneda extranjera el total no se redondea: el redondeo a múltiplos de 50 sólo aplica a operaciones en guaraníes. Un pago al contado en la moneda de la operación cubre el total general exacto. ## Modos de tipo de cambio [#modos-de-tipo-de-cambio] ### GLOBAL (recomendado) [#global-recomendado] Un solo tipo de cambio para toda la factura. Más simple y común. Enviá `monedaOperacion` + `tipoCambio` a nivel de documento: ```json { "monedaOperacion": "USD", "tipoCambio": 7300 } ``` ### POR\_ITEM [#por_item] Cada ítem tiene su propio tipo de cambio. Usado en operaciones complejas con commodities. Omití el `tipoCambio` global y envialo en todos los ítems. Si la moneda del pago también es extranjera, informá además `condicionPago.tipoCambio`: ```json { "tipoDocumento": "FACTURA_ELECTRONICA", "fechaEmision": "2026-04-15T10:30:00", "tipoEmision": "NORMAL", "numeroEstablecimiento": 1, "puntoExpedicion": 1, "tipoTransaccion": "VENTA_MERCADERIA", "monedaOperacion": "USD", "receptor": { "tipoContribuyente": "CONTRIBUYENTE", "tipoOperacion": "B2B", "tipoContribuyenteReceptor": "PERSONA_JURIDICA", "numeroDocumento": "80012345", "digitoVerificador": "0", "nombreRazonSocial": "Comercial San Roque S.A." }, "condicionOperacion": "CONTADO", "condicionPago": { "tipo": "CONTADO", "tipoPago": "EFECTIVO", "monedaPago": "USD", "tipoCambio": 7130.5000, "montoPago": 30.75 }, "items": [ { "codigo": "PROD-USD-1", "descripcion": "Producto con cambio uno", "cantidad": 2, "unidadMedida": "UNI", "precioUnitario": 10.25, "tipoCambio": 7100.1111, "afectacionTributaria": "GRAVADO", "tasaIVA": 10 }, { "codigo": "PROD-USD-2", "descripcion": "Producto con cambio dos", "cantidad": 1, "unidadMedida": "UNI", "precioUnitario": 10.25, "tipoCambio": 7200.2222, "afectacionTributaria": "GRAVADO", "tasaIVA": 10 } ] } ``` ## Restricciones SIFEN [#restricciones-sifen] | Restricción | Detalle | | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | | Tipo de cambio positivo, con hasta 5 enteros y 4 decimales | Debe ser mayor que 0 y menor que `99999.9999` | | Modalidades excluyentes | No combines `tipoCambio` global con `items[].tipoCambio`; en POR\_ITEM todos los ítems deben informar `tipoCambio` | | Operaciones B2C en USD | Permitidas pero infrecuentes; confirmá con tu contador | | Pago en moneda extranjera | `condicionPago.tipoCambio` es obligatorio; para pagos en PYG no se informa | | Moneda extranjera + receptor INNOMINADO | Permitido para FE, no para Notas de Crédito | | Crédito en moneda extranjera | El crédito se emite en PYG; otra moneda devuelve `400 validation-error` | ## Ejemplo en TypeScript [#ejemplo-en-typescript] ```typescript async function emitirFacturaUSD(montoUSD: number, ruc: string, razonSocial: string) { const tipoCambio = await obtenerCotizacionBCP(); // tu integración con BCP const response = await fetch( "https://api.sifende.com.py/api/v1/documento-electronico", { method: "POST", headers: { "Authorization": `Bearer ${process.env.SIFENDE_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ tipoDocumento: "FACTURA_ELECTRONICA", fechaEmision: new Date().toISOString().slice(0, 19), tipoEmision: "NORMAL", numeroEstablecimiento: 1, puntoExpedicion: 1, monedaOperacion: "USD", tipoCambio, tipoTransaccion: "PRESTACION_SERVICIOS", condicionOperacion: "CONTADO", receptor: { tipoContribuyente: "CONTRIBUYENTE", tipoOperacion: "B2B", tipoContribuyenteReceptor: "PERSONA_JURIDICA", numeroDocumento: ruc.split("-")[0], digitoVerificador: ruc.split("-")[1], nombreRazonSocial: razonSocial, }, condicionPago: { tipo: "CONTADO", tipoPago: "TRANSFERENCIA", monedaPago: "USD", tipoCambio, montoPago: montoUSD }, items: [{ codigo: "SRV-001", descripcion: "Servicio", cantidad: 1, unidadMedida: "UNI", precioUnitario: montoUSD, afectacionTributaria: "GRAVADO", tasaIVA: 10, }], }), } ); return response.json(); } ``` ## Próximos pasos [#próximos-pasos] * [Factura Electrónica](/docs/guias/factura-electronica): guía base de FE * [Modelo: Factura Electrónica](/docs/referencia/modelos/factura-electronica): schema completo * [Items y IVA](/docs/conceptos/items-iva): cómo se calcula el IVA # Múltiples Establecimientos (/docs/guias/multiples-establecimientos) Para emitir desde varias sucursales o cajas, indicá el establecimiento y el punto de expedición en cada documento. ## Casos de uso [#casos-de-uso] * **Varias sucursales:** identificá cada local con su número de establecimiento. * **Varias cajas en un local:** usá puntos de expedición distintos dentro del mismo establecimiento. * **Ventas presenciales y online:** distinguí ambos canales con puntos de expedición, según la configuración de tu contribuyente. Cada combinación mantiene su numeración por ambiente y tipo de documento. ## Configuración [#configuración] 1. Verificá los establecimientos y puntos habilitados para tu contribuyente. Consultá la [guía de establecimientos](/docs/panel/establecimientos) para cargar el nombre de sucursal y conocer su efecto en las emisiones por API. 2. Cargá el [timbrado del ambiente](/docs/panel/timbrado) desde **Contribuyente → Timbrado**, con su número y fechas de inicio y fin. 3. En cada emisión, enviá `numeroEstablecimiento` y `puntoExpedicion` como enteros. El timbrado se configura por ambiente. El formulario no pide un rango de numeración, un tipo de documento ni un timbrado por cada combinación de sucursal y caja. ## Ejemplo de distribución [#ejemplo-de-distribución] | Sucursal o canal | `numeroEstablecimiento` | `puntoExpedicion` | | ---------------------------- | ----------------------- | ----------------- | | Casa central, caja 1 | `1` | `1` | | Casa central, ventas online | `1` | `2` | | Sucursal Encarnación, caja 1 | `2` | `1` | Para emitir desde Encarnación, agregá estos campos a la solicitud completa: ```json { "tipoDocumento": "FACTURA_ELECTRONICA", "numeroEstablecimiento": 2, "puntoExpedicion": 1 } ``` Completá los datos del receptor, ítems y pago según el [modelo de factura](/docs/referencia/modelos/factura-electronica). El establecimiento y el punto son obligatorios en cada emisión. ## Numeración [#numeración] Cada combinación de ambiente, tipo de documento, establecimiento y punto mantiene su secuencia. Sifende asigna el siguiente número disponible: tu sistema no lo envía. Para establecimiento `2`, punto `1` y documento `25`, `numeroFormateado` es `002-001-0000025`. Guardá ese valor junto con el CDC recibido. ## Problemas de configuración [#problemas-de-configuración] Si falta el timbrado del ambiente o no está vigente, revisá **Contribuyente → Timbrado**. La [referencia de errores](/docs/referencia/errores) explica cómo resolver la respuesta recibida. Si migrás desde otro sistema, [fijá el próximo número antes de emitir](/docs/panel/numeracion). ## Próximos pasos [#próximos-pasos] * [Timbrado y numeración](/docs/conceptos/timbrado-numeracion). * [CDC](/docs/conceptos/cdc). * [Ir a producción](/docs/guias/ir-a-produccion). # Nominar una factura innominada (/docs/guias/nominar-factura) La nominación identifica al cliente de una FE que originalmente se emitió como innominada. Es un evento sobre la factura existente: conserva el CDC, XML firmado y KuDE originales. ## 1. Verificá la factura [#1-verificá-la-factura] Usá una API key del mismo contribuyente y ambiente de emisión. La nominación está disponible en DEV y PROD; SANDBOX responde `422`. [Consultá el estado](/docs/guias/consultar-estado) y continuá sólo si la FE está `APROBADO` o `APROBADO_OBSERVACION`. El receptor original debe ser no contribuyente, `INNOMINADO`, con número `"0"`. Una factura ya identificada no es elegible. ## 2. Prepará el receptor y guardá la intención [#2-prepará-el-receptor-y-guardá-la-intención] Guardá el CDC, cuerpo de la solicitud y una `Idempotency-Key` antes de enviar. Reutilizá estos datos si perdés la respuesta. Para identificar a un consumidor con cédula, guardá este contenido en `nominacion.json`, reemplazando los datos por los del cliente: ```json { "motivo": "Identificación del cliente a su solicitud", "receptor": { "naturaleza": "NO_CONTRIBUYENTE", "tipoOperacion": "B2C", "pais": "PRY", "tipoDocumento": "CEDULA_PARAGUAYA", "numeroDocumento": "1234567", "nombreRazonSocial": "Juan Pérez" } } ``` Para B2B, usá `naturaleza: "CONTRIBUYENTE"`, `tipoOperacion: "B2B"`, `pais: "PRY"`, `tipoContribuyente`, `ruc` y `digitoVerificador`; omití `tipoDocumento` y `numeroDocumento`. También se admite B2F, con domicilio extranjero. La [referencia de nominación](/docs/referencia/documentos-electronicos/nominar#receptor-de-la-nominación) detalla todos los campos y reglas; el objeto de receptor de emisión no sirve sin adaptar sus nombres. ## 3. Enviá la nominación [#3-enviá-la-nominación] Definí `SIFENDE_API_KEY`, `CDC` e `IDEMPOTENCY_KEY` con la clave de acceso, el CDC de la factura y la clave de intención que guardaste: ```bash curl --include -X POST \ "https://api.sifende.com.py/api/v1/documento-electronico/$CDC/nominar" \ --header "Authorization: Bearer $SIFENDE_API_KEY" \ --header "Idempotency-Key: $IDEMPOTENCY_KEY" \ --header 'Content-Type: application/json' \ --data-binary @nominacion.json ``` ## 4. Interpretá el resultado [#4-interpretá-el-resultado] | Respuesta | Acción | | -------------------------------- | -------------------------------------------------------------------------------------------------------------------- | | `200`, `estadoEvento: APROBADO` | Guardá el evento y protocolo. La nominación quedó confirmada | | `200`, `estadoEvento: RECHAZADO` | Revisá `codigoRespuesta` y `mensajeRespuesta`; el HTTP por sí solo no confirma la nominación | | `503 evento-nominacion-error` | Esperá `Retry-After: 2` y repetí exactamente la misma solicitud y clave | | `400` | Corregí los campos o condiciones que indique el error; verificá si ya existe un evento antes de crear otra intención | | `409 evento-nominacion-error` | Revisá la nominación existente en el panel; no intentes sustituir una aprobada con otra solicitud | Un resultado incierto conserva el evento `ENVIADO` y requiere un reintento: no hay recuperación en segundo plano. El reintento consulta la confirmación antes de reenviar. Si enviaste una clave, los demás errores y plazos de replay siguen las [reglas de idempotencia](/docs/guias/idempotencia). La nominación no consume numeración ni cupo de emisión. Sólo el evento aprobado aporta el receptor efectivo al preparar NCE/NDE desde el panel; el KuDE original conserva sus datos. ## Referencias [#referencias] * [Endpoint y contrato completo](/docs/referencia/documentos-electronicos/nominar) * [Errores de nominación](/docs/solucion-problemas/evento-nominacion-error) # Nota de Crédito Electrónica (/docs/guias/nota-credito) La **Nota de Crédito Electrónica (NCE)** se emite para revertir, descontar o anular una Factura Electrónica que ya fue aprobada por SIFEN. No reemplaza a la FE original; la complementa. ## ¿Cuándo emitir una NCE? [#cuándo-emitir-una-nce] Emití una NCE para: * Devoluciones totales o parciales de mercadería ya facturada. * Descuentos aplicados después de la emisión de la FE. * Anular una FE aprobada por error en datos no críticos (la FE original sigue existiendo en SIFEN). La NCE **solo aplica a documentos registrados en SIFEN**: estado `APROBADO` o `APROBADO_OBSERVACION`. Si tu FE fue rechazada por SIFEN, no necesitás (ni podés) emitir una NCE: corregí los datos y emití una nueva FE. Ver [Reintentar Rechazados](/docs/guias/reintentar-rechazados). ## Diferencias clave con una FE [#diferencias-clave-con-una-fe] | Aspecto | FE | NCE | | ------------------- | --------------------- | --------------------------------------------- | | `tipoDocumento` | `FACTURA_ELECTRONICA` | `NOTA_DE_CREDITO_ELECTRONICA` | | `documentoAsociado` | Opcional | **Obligatorio** (referencia a la FE original) | | `motivoEmision` | No aplica | **Obligatorio** (string enum) | | `tipoTransaccion` | Obligatorio | No se envía (lo hereda de la FE original) | | Receptor innominado | Permitido | **No permitido** (siempre identificado) | | `condicionPago` | Obligatoria | No aplica | ## Restricción importante: receptor identificado [#restricción-importante-receptor-identificado] La NCE **no acepta receptor innominado**. Si la FE original fue innominada (consumo final), igual debés identificar al receptor en la NCE con cédula o RUC. ## Paso 1: Identificá la FE a referenciar [#paso-1-identificá-la-fe-a-referenciar] Necesitás el **CDC de la FE original** y conocer el motivo de emisión. Los motivos válidos para NCE son: | Valor | Motivo | | --------------------------------- | ------------------------------------------ | | `DEVOLUCION` | Devolución total o parcial de mercadería | | `DESCUENTO` | Descuento aplicado posterior a la emisión | | `BONIFICACION` | Bonificación comercial | | `DEVOLUCION_Y_AJUSTES_DE_PRECIOS` | Devolución combinada con ajuste de precios | | `CREDITO_INCOBRABLE` | Crédito declarado incobrable | | `RECUPERO_DE_COSTO` | Recupero de costos | | `RECUPERO_DE_GASTO` | Recupero de gastos | | `AJUSTE_DE_PRECIO` | Ajuste por error de precio | `motivoEmision` es un **string enum**, no un código numérico. La API valida contra estos valores exactos. ## Paso 2: Armá la solicitud [#paso-2-armá-la-solicitud] ```json { "tipoDocumento": "NOTA_DE_CREDITO_ELECTRONICA", "fechaEmision": "2026-04-27T14:00:00", "tipoEmision": "NORMAL", "numeroEstablecimiento": 1, "puntoExpedicion": 1, "monedaOperacion": "PYG", "motivoEmision": "DEVOLUCION", "receptor": { "tipoContribuyente": "NO_CONTRIBUYENTE", "tipoOperacion": "B2C", "tipoDocumento": "CEDULA_PARAGUAYA", "numeroDocumento": "1234567", "nombreRazonSocial": "Juan Pérez" }, "documentoAsociado": { "tipoDocumento": "ELECTRONICO", "cdc": "01800123451001001000000122026042710000000006" }, "items": [ { "codigo": "PROD-A4-75", "descripcion": "Resma de papel A4 75g - devolución", "cantidad": 2, "unidadMedida": "UNI", "precioUnitario": 15000, "afectacionTributaria": "GRAVADO", "tasaIVA": 10 } ] } ``` ## Paso 3: Enviá la NCE [#paso-3-enviá-la-nce] ```bash curl -X POST https://api.sifende.com.py/api/v1/documento-electronico \ -H "Authorization: Bearer $SIFENDE_API_KEY" \ -H "Content-Type: application/json" \ -d @nota-credito.json ``` Respuesta exitosa: **`202 Accepted`** con una respuesta que incluye el `id`, el `cdc`, `estado: "PENDIENTE"`, `numeroFormateado`, `qrUrl`, `statusUrl` y `kudeUrl`. Guardalos igual que con la FE. ## Paso 4: Confirmá la aprobación [#paso-4-confirmá-la-aprobación] Igual que con la FE, esperá el procesamiento asíncrono de SIFEN. Ver [Consultar Estado](/docs/guias/consultar-estado). ## Errores frecuentes [#errores-frecuentes] | Status | Tipo | Causa | Solución | | ------ | ------------------------- | ------------------------------------------------------ | --------------------------------------------------------------------- | | 400 | `validation-error` | Falta `motivoEmision` o `documentoAsociado` | Completar ambos campos | | 400 | `invalid-enum-value` | `motivoEmision` no es uno de los enums válidos | Usar uno de los valores documentados en la tabla anterior | | 422 | SIFEN 2026 | CDC referenciado no existe en SIFEN o no está aprobado | Verificar que la FE original esté `APROBADO` o `APROBADO_OBSERVACION` | | 422 | SIFEN (receptor inválido) | Se intentó usar receptor innominado | Identificar al receptor con cédula o RUC | ## Próximos pasos [#próximos-pasos] * ¿Necesitás cobrar más por la operación original? → [Nota de Débito](/docs/guias/nota-debito). * ¿La FE estaba dirigida a una empresa? → [Receptor B2B y B2C](/docs/guias/receptor-b2b-b2c) para estructurar el receptor. * Si SIFEN rechaza la NCE, consultá [Manejar Errores](/docs/guias/manejar-errores). # Nota de Débito Electrónica (/docs/guias/nota-debito) La **Nota de Débito Electrónica (NDE)** se emite para agregar cargos a una Factura Electrónica ya aprobada: intereses, ajustes por diferencias de cambio, fletes facturados después, recargos por mora, etc. ## ¿Cuándo emitir una NDE? [#cuándo-emitir-una-nde] Emití una NDE cuando necesitás **incrementar** el monto cobrado al receptor sobre una FE ya aprobada. Algunos casos típicos: * Intereses por mora. * Ajustes positivos por diferencia de cambio en facturas en moneda extranjera. * Fletes o servicios adicionales no incluidos en la FE original. * Recargos pactados después de la emisión. La NDE **solo aplica a documentos registrados en SIFEN**: estado `APROBADO` o `APROBADO_OBSERVACION`. Si vas a corregir una FE rechazada, emití una nueva FE en lugar de una NDE. ## Estructura [#estructura] La NDE usa el mismo patrón que la NCE: requiere `documentoAsociado` con el CDC de la FE original y un `motivoEmision`. La diferencia es que el efecto es **aumentar** el monto, no descontarlo. | Aspecto | FE | NDE | | ------------------- | --------------------- | ----------------------------------------- | | `tipoDocumento` | `FACTURA_ELECTRONICA` | `NOTA_DE_DEBITO_ELECTRONICA` | | `documentoAsociado` | Opcional | **Obligatorio** (CDC de la FE original) | | `motivoEmision` | No aplica | **Obligatorio** (string enum) | | `tipoTransaccion` | Obligatorio | No se envía (lo hereda de la FE original) | | Receptor innominado | Permitido | **No permitido** | ## Restricción de receptor [#restricción-de-receptor] Igual que la NCE, la NDE **no admite receptor innominado**. Si la FE original era innominada, identificá al receptor con cédula o RUC en la NDE. ## Motivos válidos de emisión [#motivos-válidos-de-emisión] | Valor | Motivo | | --------------------------------- | ------------------------------------------ | | `DEVOLUCION_Y_AJUSTES_DE_PRECIOS` | Devolución combinada con ajuste de precios | | `DEVOLUCION` | Devolución | | `DESCUENTO` | Descuento | | `BONIFICACION` | Bonificación | | `CREDITO_INCOBRABLE` | Crédito declarado incobrable | | `RECUPERO_DE_COSTO` | Recupero de costos | | `RECUPERO_DE_GASTO` | Recupero de gastos | | `AJUSTE_DE_PRECIO` | Ajuste de precio | `motivoEmision` es un **string enum**, no un código numérico. La API valida contra estos valores exactos. ## Paso 1: Armá la solicitud [#paso-1-armá-la-solicitud] Ejemplo de NDE por ajuste de precio sobre una FE B2B aprobada: ```json { "tipoDocumento": "NOTA_DE_DEBITO_ELECTRONICA", "fechaEmision": "2026-04-27T16:15:00", "tipoEmision": "NORMAL", "numeroEstablecimiento": 1, "puntoExpedicion": 1, "monedaOperacion": "PYG", "motivoEmision": "AJUSTE_DE_PRECIO", "receptor": { "tipoContribuyente": "CONTRIBUYENTE", "tipoOperacion": "B2B", "tipoContribuyenteReceptor": "PERSONA_JURIDICA", "numeroDocumento": "80012345", "digitoVerificador": "0", "nombreRazonSocial": "Comercial Guaraní S.A." }, "documentoAsociado": { "tipoDocumento": "ELECTRONICO", "cdc": "01800123451001001000000122026042710000000006" }, "items": [ { "codigo": "AJ-PRECIO", "descripcion": "Ajuste de precio - Factura 001-001-0000123", "cantidad": 1, "unidadMedida": "UNI", "precioUnitario": 75000, "afectacionTributaria": "GRAVADO", "tasaIVA": 10 } ] } ``` ## Paso 2: Enviá la NDE [#paso-2-enviá-la-nde] ```bash curl -X POST https://api.sifende.com.py/api/v1/documento-electronico \ -H "Authorization: Bearer $SIFENDE_API_KEY" \ -H "Content-Type: application/json" \ -d @nota-debito.json ``` Respuesta exitosa: **`202 Accepted`** con una respuesta con (`id`, `cdc`, `estado: "PENDIENTE"`, `numeroFormateado`, `qrUrl`, `statusUrl`, `kudeUrl`). Guardá los identificadores como en la FE. ## Paso 3: Verificá el estado [#paso-3-verificá-el-estado] El procesamiento es asíncrono. Aplicá la misma estrategia de polling que para FE y NCE; ver [Consultar Estado](/docs/guias/consultar-estado). ## Errores frecuentes [#errores-frecuentes] | Status | Tipo | Causa | Solución | | ------ | -------------------- | ---------------------------------------------- | --------------------------------------------------------- | | 400 | `validation-error` | Falta `documentoAsociado` o `motivoEmision` | Completar ambos campos | | 400 | `invalid-enum-value` | `motivoEmision` no es uno de los enums válidos | Usar uno de los valores documentados en la tabla anterior | | 422 | SIFEN (CDC asociado) | CDC referenciado no existe o no está aprobado | Confirmar estado de la FE original | | 422 | SIFEN (receptor) | Se intentó usar receptor innominado | Identificar al receptor | ## Próximos pasos [#próximos-pasos] * ¿Necesitás revertir un cargo? → [Nota de Crédito](/docs/guias/nota-credito). * ¿Vas a entregar el comprobante al cliente? → [Descargar KuDE](/docs/guias/descargar-kude). * ¿Tenés errores de receptor? → [Receptor B2B y B2C](/docs/guias/receptor-b2b-b2c). # Nota de Remisión (/docs/guias/nota-remision) Usá una **Nota de Remisión Electrónica (NRE)** para documentar un traslado de mercadería, por ejemplo por consignación o entre locales. Elegí el motivo que corresponda a la operación. A diferencia de una factura, la NRE describe las mercaderías **sin precios ni IVA**. El receptor siempre tiene que estar identificado y el bloque `transporte` es obligatorio. ## Paso 1: Armá la solicitud [#paso-1-armá-la-solicitud] Este ejemplo muestra un traslado nacional por consignación. Reemplazá las identidades, las fechas y las direcciones por las de tu operación y guardalo como `nota-remision.json`. ```json { "tipoDocumento": "NOTA_DE_REMISION_ELECTRONICA", "fechaEmision": "2026-10-02T08:00:00", "tipoEmision": "NORMAL", "numeroEstablecimiento": 1, "puntoExpedicion": 1, "receptor": { "tipoContribuyente": "NO_CONTRIBUYENTE", "tipoOperacion": "B2C", "tipoDocumento": "CEDULA_PARAGUAYA", "numeroDocumento": "4567890", "nombreRazonSocial": "Ana González", "pais": "PRY", "direccion": "Avenida Mariscal López", "numeroCasa": 450, "departamento": "CENTRAL", "ciudad": "SAN LORENZO" }, "motivoTraslado": "TRASLADO_POR_CONSIGNACION", "responsableEmision": "EMISOR_FACTURA", "kilometrosRecorrido": 8, "items": [ { "codigo": "PAP-A4-75", "descripcion": "Resma de papel A4 de 75 gramos", "cantidad": 100, "unidadMedida": "UNI" } ], "transporte": { "tipoTransporte": "PROPIO", "modalidad": "TERRESTRE", "responsableFlete": "TRANSPORTE_PROPIO", "fechaInicioTraslado": "2026-10-02", "fechaFinTraslado": "2026-10-02", "salida": { "direccion": "Calle Teniente Benítez", "numeroCasa": 120, "departamento": "CENTRAL", "ciudad": "SAN LORENZO" }, "entregas": [ { "direccion": "Avenida Mariscal López", "numeroCasa": 450, "departamento": "CENTRAL", "ciudad": "SAN LORENZO" } ], "vehiculos": [ { "tipoVehiculo": "CAMION", "marca": "ISUZU", "tipoIdentificacion": 2, "matricula": "ABC1234" } ], "transportista": { "naturaleza": "NO_CONTRIBUYENTE", "nombreRazonSocial": "Carlos Benítez", "tipoDocumento": "CEDULA_PARAGUAYA", "numeroDocumento": "3456789", "domicilioFiscal": "Calle Teniente Benítez 120, San Lorenzo", "numeroDocumentoConductor": "3456789", "nombreConductor": "Carlos Benítez", "direccionConductor": "Calle Teniente Benítez 120, San Lorenzo" } } } ``` Consultá el [modelo de nota de remisión](/docs/referencia/modelos/nota-remision) para los campos, los motivos de traslado y las reglas de transporte. En `TRASLADO_ENTRE_LOCALES`, el receptor tiene que ser contribuyente y tener el mismo RUC que el emisor. ## Paso 2: Enviá la nota [#paso-2-enviá-la-nota] ```bash curl -X POST https://api.sifende.com.py/api/v1/documento-electronico \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ --data-binary @nota-remision.json ``` La API responde `202 Accepted` con el CDC y las URLs de seguimiento. Guardalos para consultar el mismo documento. Para recuperar una respuesta perdida, seguí la [guía de idempotencia](/docs/guias/idempotencia). ## Paso 3: Esperá la aprobación y descargá el KuDE [#paso-3-esperá-la-aprobación-y-descargá-el-kude] [Consultá el estado](/docs/guias/consultar-estado) hasta obtener `APROBADO` o `APROBADO_OBSERVACION`. Antes de iniciar el traslado, [descargá el KuDE](/docs/guias/descargar-kude) para acompañar la mercadería. Si la NRE todavía no está aprobada, la descarga responde **403**. Si queda `RECHAZADO`, revisá el motivo y corregí los datos antes de emitir otra nota. Si queda `ERROR` o sigue en `EN_LOTE` después de varias horas, revisá el [lote en el panel](/docs/panel/lotes) y continuá el seguimiento con el mismo CDC. ## Errores frecuentes [#errores-frecuentes] | Dato | Qué revisar | | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | Receptor | No admite `INNOMINADO`. Informá `direccion` y `numeroCasa`; para un receptor nacional, también `departamento` y `ciudad`, con `pais: "PRY"` | | Traslado entre locales | El receptor debe ser contribuyente y tener el RUC del emisor | | Traslado por ventas | Si no asociás una factura, informá `fechaFacturaFutura`; su mes y año no pueden ser posteriores a los de la emisión | | Motivo `OTRO` | Requiere `descripcionMotivoTraslado`; omití esa descripción para los demás motivos | | Fechas del traslado | `fechaFinTraslado` no puede ser anterior a `fechaInicioTraslado` | | Vehículo | Con `tipoIdentificacion: 1`, informá su identificación; con `2`, la `matricula` | Una solicitud inválida devuelve **400**. Consultá los campos señalados en `errores` y el [modelo completo](/docs/referencia/modelos/nota-remision) antes de reenviarla. # Polling de Resultados SIFEN (/docs/guias/polling-resultados) Después de emitir, guardá el CDC y consultá el resultado sin volver a emitir el documento. ## Cuándo consultar [#cuándo-consultar] * Consultá cada **5 segundos**, con un máximo de **5 minutos** por espera. * Seguí mientras el estado sea `PENDIENTE` o `EN_LOTE`. * Detenete al recibir `APROBADO`, `APROBADO_OBSERVACION`, `RECHAZADO`, `CANCELADO` o `ERROR`. * Si se agota la espera, conservá el CDC y retomá la consulta después. Un timeout no es un rechazo ni autoriza una emisión nueva. ## Ejemplo en TypeScript [#ejemplo-en-typescript] Ejecutá este ejemplo desde tu servidor para mantener la API key fuera del navegador. La función devuelve el primer estado que requiere terminar la espera; revisá cuál es antes de continuar tu flujo. ```typescript type EstadoDocumento = | 'PENDIENTE' | 'EN_LOTE' | 'APROBADO' | 'APROBADO_OBSERVACION' | 'RECHAZADO' | 'CANCELADO' | 'ERROR'; interface EstadoRespuesta { cdc: string; estado: EstadoDocumento; ambiente: 'DEV' | 'PROD' | 'SANDBOX'; iTiDe: number; numeroDocumento: number; fechaCreacion: string; protocoloAutorizacion: string | null; mensajeRechazo: string | null; } async function esperarResultado(cdc: string, apiKey: string): Promise { const limite = Date.now() + 300_000; while (true) { const restante = limite - Date.now(); if (restante <= 0) break; const respuesta = await fetch( `https://api.sifende.com.py/api/v1/documento-electronico/status/${cdc}`, { headers: { Authorization: `Bearer ${apiKey}` }, signal: AbortSignal.timeout(Math.min(10_000, restante)), }, ); if (!respuesta.ok) { throw new Error(`No se pudo consultar el estado: HTTP ${respuesta.status}`); } const documento: EstadoRespuesta = await respuesta.json(); if (!['PENDIENTE', 'EN_LOTE'].includes(documento.estado)) { return documento; } await new Promise(resolve => setTimeout(resolve, Math.min(5_000, Math.max(0, limite - Date.now())))); } throw new Error('Terminó la espera. Conservá el CDC y retomá la consulta después.'); } ``` ## Guardar el CDC y retomar consultas [#guardar-el-cdc-y-retomar-consultas] Guardá el CDC en tu base de datos antes de iniciar las consultas, junto con la operación de tu sistema, el ambiente y el último estado conocido. Actualizá ese registro con cada resultado. Al iniciar de nuevo tu proceso, recuperá los documentos en `PENDIENTE` o `EN_LOTE` y retomá la consulta con el mismo CDC y una clave del mismo contribuyente y ambiente. También podés retomar los que agotaron el tiempo de espera: el timeout de tu proceso no cambia el estado del documento. Si tu proceso se interrumpió antes de guardar la respuesta de emisión, recuperala mediante la misma intención, clave y contenido según la [guía de idempotencia](/docs/guias/idempotencia). No emitas de nuevo con una clave distinta. ## Consejos para producción [#consejos-para-producción] * Consultá en segundo plano desde tu servidor para no bloquear la interacción del usuario ni exponer la API key. * Guardá `mensajeRechazo` completo cuando recibas `RECHAZADO` o `APROBADO_OBSERVACION`. * Medí el tiempo desde la aceptación de la emisión hasta que tu integración observa `APROBADO` o `APROBADO_OBSERVACION`. Ese dato permite detectar cambios en los tiempos de respuesta. * Limitá las consultas simultáneas y respetá `Retry-After` ante un `429`. ## Interpretar el resultado [#interpretar-el-resultado] En [SANDBOX](/docs/conceptos/ambientes#sandbox-de-sifende), `APROBADO` representa una aprobación de prueba de Sifende, sin envío a SIFEN ni validez fiscal. Los estados de envío y las respuestas de SIFEN de esta tabla corresponden a DEV y PROD. | Estado | Qué significa | Qué hacer | | ---------------------- | -------------------------------------------------------- | ------------------------------------------------------------------ | | `PENDIENTE` | Sifende recibió el documento y está preparando su envío | Seguí consultando | | `EN_LOTE` | En proceso de envío o a la espera del resultado de SIFEN | Seguí consultando | | `APROBADO` | SIFEN aceptó el documento | Detené las consultas; guardá el protocolo | | `APROBADO_OBSERVACION` | SIFEN aceptó el documento con observaciones | Detené las consultas y revisá `mensajeRechazo`; no lo reemitas | | `RECHAZADO` | SIFEN rechazó el documento | Detené las consultas y corregí el motivo antes de emitir uno nuevo | | `CANCELADO` | Se confirmó la cancelación de un documento aprobado | Detené las consultas | | `ERROR` | El envío falló de forma definitiva | Detené las consultas y revisá el panel; no lo reemitas | En `ERROR`, el documento no se reintenta solo. Pedí el reintento a [soporte](/docs/solucion-problemas/soporte) o seguí la [guía para reintentar el lote](/docs/panel/lotes). Al reintentarlo vuelve a `EN_LOTE` y podés retomar las consultas con el mismo CDC. Si después de varias horas sigue en `EN_LOTE`, puede pertenecer a un lote **Fallido**. Revisá **Historial de Lotes** en el detalle del documento y, si el lote está **Fallido**, seguí la [guía de reintento](/docs/panel/lotes). Conservá el mismo CDC. Una consulta de estado no consume numeración ni cupo. Si la consulta falla por conexión o recibe `5xx`, podés repetirla. Ante `429`, respetá `Retry-After`. Ante `401` o `403`, revisá las credenciales o el acceso antes de seguir. Para recibir el resultado sin mantener una espera continua, configurá [webhooks](/docs/panel/webhooks). Podés usar las consultas de estado para confirmar el estado de los documentos pendientes. # Receptor B2B y B2C (/docs/guias/receptor-b2b-b2c) El bloque `receptor` define a quién va dirigido el documento electrónico. SIFEN distingue tres situaciones principales, y elegir mal el tipo es la causa más común de rechazos en producción. ## Cuándo usar cada tipo [#cuándo-usar-cada-tipo] | Caso | `tipoOperacion` | `tipoContribuyente` | `tipoDocumento` | Datos requeridos | | -------------------------------------------------------- | --------------- | ------------------- | --------------------------- | ----------------------------------------------------- | | Venta a empresa con RUC (deduce IVA) | `B2B` | `CONTRIBUYENTE` | — (no se envía) | RUC + DV + `tipoContribuyenteReceptor` + razón social | | Venta a persona física identificada | `B2C` | `NO_CONTRIBUYENTE` | `CEDULA_PARAGUAYA` (u otro) | Nº de documento + nombre | | Consumo final por menos de Gs. 7.000.000 sin identificar | `B2C` | `NO_CONTRIBUYENTE` | `INNOMINADO` | `"0"` + `"Sin Nombre"` | `tipoContribuyente` acepta los valores `CONTRIBUYENTE` y `NO_CONTRIBUYENTE`, y es obligatorio en todas las operaciones (B2B, B2C, B2G y B2F). Los valores de `tipoOperacion` son: `B2B`, `B2C`, `B2G` (gobierno) y `B2F` (extranjero). ## B2C innominado [#b2c-innominado] Es el caso más simple: ventas al consumidor final por menos de Gs. 7.000.000 donde no hace falta pedir documento. Se arma con `tipoContribuyente: "NO_CONTRIBUYENTE"` + `tipoDocumento: "INNOMINADO"`. Aunque el cliente no se identifique, `numeroDocumento` y `nombreRazonSocial` siguen siendo obligatorios. Para el caso innominado el Manual Técnico de SIFEN define los valores literales `"0"` y `"Sin Nombre"` — no son placeholders, tienen que ir exactamente así. El límite es estricto: un total igual a Gs. 7.000.000 exige identificar al receptor. En moneda extranjera se compara el total convertido a guaraníes. La API exceptúa de este límite las operaciones `MUESTRAS_MEDICAS`. ```json { "receptor": { "tipoContribuyente": "NO_CONTRIBUYENTE", "tipoOperacion": "B2C", "tipoDocumento": "INNOMINADO", "numeroDocumento": "0", "nombreRazonSocial": "Sin Nombre" } } ``` **Restricción:** las **Notas de Crédito** y **Notas de Débito** electrónicas **no admiten receptor innominado**. Si querés anular o ajustar una FE innominada, vas a tener que identificar al receptor en la NCE/NDE. ## B2C identificado [#b2c-identificado] Para ventas a personas físicas con cédula cuando el monto es igual o mayor a Gs. 7.000.000, o el cliente lo solicita explícitamente. Es el mismo `tipoContribuyente: "NO_CONTRIBUYENTE"` que el caso innominado — lo único que cambia es el `tipoDocumento` y los datos reales del receptor. ```json { "receptor": { "tipoContribuyente": "NO_CONTRIBUYENTE", "tipoOperacion": "B2C", "tipoDocumento": "CEDULA_PARAGUAYA", "numeroDocumento": "1234567", "nombreRazonSocial": "Juan Pérez", "direccion": "Av. España 1234, Asunción" } } ``` Otros tipos de documento aceptados para `B2C` cuando no hay cédula paraguaya: | `tipoDocumento` | Cuándo usarlo | | ---------------------- | ---------------------------------------- | | `CEDULA_PARAGUAYA` | Cédula de identidad paraguaya | | `PASAPORTE` | Extranjero sin cédula | | `CARNET_DE_RESIDENCIA` | Residente extranjero | | `CEDULA_EXTRANJERA` | Cédula de identidad extranjera | | `TARJETA_DIPLOMATICA` | Tarjeta diplomática | | `OTRO` | Otro identificador no contemplado arriba | ## B2B (factura a empresa) [#b2b-factura-a-empresa] Cuando el receptor es **otro contribuyente** que va a deducir IVA, el RUC es obligatorio. Sifende valida el RUC contra el padrón de la SET. Si no tenés los datos completos del cliente, [consultá el RUC en el padrón](/docs/referencia/padron) y usá la razón social, el DV y el domicilio que devuelve la SET para armar este bloque. ```json { "receptor": { "tipoContribuyente": "CONTRIBUYENTE", "tipoOperacion": "B2B", "tipoContribuyenteReceptor": "PERSONA_JURIDICA", "numeroDocumento": "80012345", "digitoVerificador": "0", "nombreRazonSocial": "Comercial Guaraní S.A.", "direccion": "Av. Mariscal López 4567, Asunción" } } ``` Para B2B, **no enviés `tipoDocumento`**: el RUC se identifica por `tipoOperacion: "B2B"` + `tipoContribuyente: "CONTRIBUYENTE"`. Separás el número y el dígito verificador en dos campos: `numeroDocumento: "80012345"` y `digitoVerificador: "0"`. ### Persona física o jurídica (`tipoContribuyenteReceptor`) [#persona-física-o-jurídica-tipocontribuyentereceptor] Todo receptor contribuyente tiene que declarar **si es persona física o jurídica** en `tipoContribuyenteReceptor`. No se usa en B2C, así que es un campo nuevo cuando pasás de facturar a consumidores finales a facturar a empresas. | Valor | Cuándo usarlo | | ------------------ | ---------------------------------------------------------------------------- | | `PERSONA_JURIDICA` | Empresas: S.A., S.R.L., EIRL, cooperativas, fundaciones, organismos públicos | | `PERSONA_FISICA` | Unipersonales y profesionales con RUC propio | Si no lo mandás, la API responde `400 validation-error` con `tipoContribuyenteReceptor: "Tipo de contribuyente receptor es obligatorio para un contribuyente"` — el documento nunca llega a SIFEN. Lo mismo aplica a `digitoVerificador`: para un receptor contribuyente es obligatorio y tiene que ser **un solo dígito** (el DV del RUC, sin el guión ni el número base). `tipoContribuyente` y `tipoContribuyenteReceptor` son campos distintos y suenan casi igual. `tipoContribuyente` dice **si** el receptor es contribuyente y va siempre; `tipoContribuyenteReceptor` dice **qué tipo** de contribuyente es y va únicamente cuando el primero vale `CONTRIBUYENTE`. Mandar el segundo para un `NO_CONTRIBUYENTE` es el rechazo 1303. ### Cuándo es obligatorio facturar B2B [#cuándo-es-obligatorio-facturar-b2b] * Tu cliente es una empresa (PJ o EIRL). * Te pide factura crédito fiscal. * El monto es igual o mayor a Gs. 7.000.000 y el cliente tiene RUC. * Vas a registrar la operación contra cuenta corriente del receptor. ## Restricciones según tipo de documento [#restricciones-según-tipo-de-documento] | Tipo de documento | Innominado | B2C identificado | B2B con RUC | | ------------------------ | :--------: | :--------------: | :---------: | | Factura Electrónica (FE) | ✅ | ✅ | ✅ | | Nota de Crédito (NCE) | ❌ | ✅ | ✅ | | Nota de Débito (NDE) | ❌ | ✅ | ✅ | | Nota de Remisión (NRE) | ❌ | ✅ | ✅ | En una NRE, informá `direccion` y `numeroCasa` del receptor. Para un receptor nacional, también `departamento` y `ciudad`. En `TRASLADO_ENTRE_LOCALES`, debe ser contribuyente con el mismo RUC que el emisor. Ver la [guía de nota de remisión](/docs/guias/nota-remision). ## Errores frecuentes [#errores-frecuentes] | SIFEN | Causa | Solución | | ----- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | 1302 | Falta `tipoContribuyente` para receptor B2B | Completar `tipoContribuyente: "CONTRIBUYENTE"` | | 1303 | Se informó `tipoContribuyenteReceptor` cuando el receptor es `NO_CONTRIBUYENTE` | Eliminar `tipoContribuyenteReceptor` — solo aplica a receptores `CONTRIBUYENTE`. El campo `tipoContribuyente` siempre se envía | | 1304 | Falta `numeroDocumento` (RUC) para receptor contribuyente | Completar el RUC del receptor | | 1305 | Se informó el RUC del receptor cuando el receptor es `NO_CONTRIBUYENTE` | No hay que eliminar `numeroDocumento`: ese campo es obligatorio siempre y en B2C pasa a ser el número de CI/pasaporte. Revisá que tu integración no esté enviando datos de RUC/contribuyente para un receptor no contribuyente | | 1306 | RUC del receptor inexistente en Marangatu (no registrado en SET) | Confirmar el RUC con tu cliente | | 1309 | DV del RUC del receptor incorrecto | Verificar `digitoVerificador` | Ver el catálogo completo en [Rechazos SIFEN](/docs/solucion-problemas/rechazos-sifen). ## Próximos pasos [#próximos-pasos] * Volvé a [Factura Electrónica](/docs/guias/factura-electronica) para el flujo completo de emisión. * Si vas a emitir notas de crédito/débito, repasá las restricciones en [Nota de Crédito](/docs/guias/nota-credito) y [Nota de Débito](/docs/guias/nota-debito). Para identificar al cliente después de aprobar una FE innominada, seguí la [guía de nominación](/docs/guias/nominar-factura). # Reintentar Documentos Rechazados (/docs/guias/reintentar-rechazados) Cuando SIFEN rechaza un DE, el documento queda **legalmente nulo** y no se puede "corregir". El flujo correcto es: identificar la causa, emitir un **nuevo DE** con los datos corregidos, e inutilizar el número original si es necesario. Un DE en estado `RECHAZADO` no tiene validez fiscal. **No lo entregues al cliente.** El número de documento que consumió tampoco se puede reutilizar: debe inutilizarse o quedará como hueco en la secuencia. ## Flujo completo [#flujo-completo] **Detectá el rechazo** consultando el estado del DE: ```bash curl "https://api.sifende.com.py/api/v1/documento-electronico/status/{cdc}" \ -H "Authorization: Bearer sk_live_..." ``` Respuesta: ```json { "cdc": "01800123451001001000000122026042710000000006", "estado": "RECHAZADO", "ambiente": "PROD", "iTiDe": 1, "numeroDocumento": 1, "fechaCreacion": "2026-04-15T10:30:00", "protocoloAutorizacion": null, "mensajeRechazo": "[1306] RUC del receptor inexistente en Marangatu" } ``` `numeroDocumento` es un **entero**. El formato `"NNN-NNN-NNNNNNN"` se devuelve como `numeroFormateado` en la respuesta de **emisión**: son campos separados. **Identificá la causa** a partir del código entre corchetes (`[1302]`) en `mensajeRechazo`. Consultá la tabla de [Rechazos SIFEN](/docs/solucion-problemas/rechazos-sifen) para ver el significado. **Corregí los datos** en tu sistema. Ej: corregir el formato del RUC, completar campos faltantes del receptor, ajustar fechas, etc. **Emití un NUEVO DE** con los datos corregidos. Recibirá un nuevo CDC. ```bash curl -X POST "https://api.sifende.com.py/api/v1/documento-electronico" \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ ...payload corregido... }' ``` **Inutilizá el número original** si el rechazo dejó un hueco que no se rellenará automáticamente. Ver [Inutilizar Numeración](/docs/guias/inutilizar-numeracion). ## Rechazos comunes y cómo corregirlos [#rechazos-comunes-y-cómo-corregirlos] ### `1302`: Falta `tipoContribuyente` para receptor B2B [#1302-falta-tipocontribuyente-para-receptor-b2b] **Causa:** Operación B2B sin el campo `tipoContribuyente` del receptor. **Solución:** Incluí `tipoContribuyente: "CONTRIBUYENTE"` en el bloque receptor — es el valor que corresponde siempre a B2B. Reemití. ### `1303`: Tipo de contribuyente receptor inválido [#1303-tipo-de-contribuyente-receptor-inválido] **Causa:** Se envió `tipoContribuyenteReceptor` (`PERSONA_FISICA` / `PERSONA_JURIDICA`) cuando el receptor es `NO_CONTRIBUYENTE`. Ese campo solo aplica a receptores contribuyentes. **Solución:** Eliminá `tipoContribuyenteReceptor` cuando el receptor es `NO_CONTRIBUYENTE`. Es un campo distinto de `tipoContribuyente`, que es obligatorio en todos los documentos y nunca se omite. Reemití. ### `1304`: Falta `numeroDocumento` (RUC) para receptor contribuyente [#1304-falta-numerodocumento-ruc-para-receptor-contribuyente] **Causa:** Operación B2B sin el RUC del receptor. **Solución:** Completá `numeroDocumento` (RUC sin DV) y `digitoVerificador` separadamente. Reemití. ### `1305`: RUC del receptor no requerido [#1305-ruc-del-receptor-no-requerido] **Causa:** Se enviaron datos de RUC o de contribuyente cuando el receptor es `NO_CONTRIBUYENTE`. **Solución:** No elimines `numeroDocumento`: para un receptor B2C sigue siendo obligatorio y contiene su número de CI o pasaporte. Eliminá los datos específicos de RUC/contribuyente que no correspondan y reemití. ### `1306`: RUC del receptor inexistente en Marangatu [#1306-ruc-del-receptor-inexistente-en-marangatu] **Causa:** El RUC enviado no está registrado en el padrón de la SET. **Solución:** 1. Verificá el RUC en el [consultador SET](https://www.set.gov.py/portal/PARAGUAY-SET/Servicios/Consultas/RUC) 2. Confirmá con tu cliente que el RUC sea correcto 3. Reemití con el RUC corregido ### `1309`: Dígito verificador del RUC incorrecto [#1309-dígito-verificador-del-ruc-incorrecto] **Causa:** El DV enviado no coincide con el algoritmo SET (módulo 11). **Solución:** Verificá `digitoVerificador` por separado o pedile al receptor su RUC con DV. Reemití. ## Implementación TypeScript [#implementación-typescript] ```typescript async function reemitirSiRechazado(cdcOriginal: string, payloadOriginal: any) { const estado = await consultarEstado(cdcOriginal); if (estado.estado !== "RECHAZADO") { throw new Error(`No corresponde reemitir. Estado actual: ${estado.estado}`); } const codigoError = extraerCodigo(estado.mensajeRechazo); console.log(`Rechazo ${codigoError}: ${estado.mensajeRechazo}`); const payloadCorregido = await aplicarCorrecciones(payloadOriginal, codigoError); // Emitir nuevo DE: recibe un CDC nuevo const nuevo = await emitirDE(payloadCorregido); console.log(`Reemitido como CDC: ${nuevo.cdc}`); // Si querés que el número original quede formalmente cerrado await inutilizarNumero(cdcOriginal); return nuevo; } function extraerCodigo(motivo: string): string { const match = motivo.match(/\[(\d+)\]/); return match ? match[1] : "sin código"; } ``` ## Buenas prácticas [#buenas-prácticas] * **Loggeá todos los rechazos** con el código y el payload original. Sirven para detectar bugs sistemáticos * **Validá antes de enviar.** Si el 80% de tus rechazos son `1302`, fortalecé la validación de RUC en tu frontend * **Notificá al usuario.** Si un rechazo se da en el contexto de una venta, mostrale al cajero/vendedor qué corregir * **Monitoreá la tasa de rechazos.** Una tasa > 1% indica un problema en tu integración **No reintentes el mismo payload.** Reenviar exactamente los mismos datos producirá el mismo rechazo. Siempre corregí los datos antes de reemitir. ## Próximos pasos [#próximos-pasos] * [Rechazos SIFEN](/docs/solucion-problemas/rechazos-sifen): tabla completa de códigos * [Inutilizar Numeración](/docs/guias/inutilizar-numeracion): cerrar el hueco del número rechazado * [Manejar Errores](/docs/guias/manejar-errores): patrones de error handling # Herramientas (/docs/herramientas) Las herramientas que mantenemos te permiten probar tu API key, validar payloads y ejecutar los flujos típicos contra la API de Sifende sin tener que armar `curl` a mano ni montar un proyecto entero. ## Disponibles [#disponibles] ## ¿Cuándo usarlas? [#cuándo-usarlas] * Para probar tu API key antes de integrar. * Para reproducir un error con una solicitud conocida en el ambiente de pruebas. * En demos y pruebas manuales. * En scripts puntuales de consulta, carga o reemisión de documentos rechazados. Para integrar Sifende en tu sistema, consultá la [Referencia API](/docs/referencia). # Sifende CLI (/docs/herramientas/sifende-cli) Sifende CLI es un cliente de línea de comandos que envuelve la API REST de Sifende. Sirve para ejecutar los flujos típicos (emitir, consultar estado, descargar KuDE, cancelar e inutilizar) contra `https://api.sifende.com.py/api/v1/` sin escribir código. Va bien para probar tu API key, validar payloads, reproducir bugs y armar scripts puntuales. Solo depende de la stdlib de Python y de `requests`. La CLI no reemplaza una integración. Para producción, integrá la API REST directamente desde tu servidor siguiendo la [Referencia](/docs/referencia). ## Requisitos [#requisitos] * Python 3.9 o superior * `make` (opcional; todo se puede correr con `python` directo) * Una API key de Sifende. Si no tenés una, seguí [Paso 1: Credenciales](/docs/inicio-rapido/paso-1-credenciales) ## Instalación [#instalación] Cloná el repositorio y entrá al directorio del CLI: ```bash git clone https://github.com/ithdev/sifende-cli.git cd sifende-cli ``` El repo trae `sample_factura.json` para contado y [`sample_factura_credito.json`](https://github.com/ithdev/sifende-cli/blob/main/sample_factura_credito.json) para crédito por cuotas con entrega inicial. ## Quickstart en 3 comandos [#quickstart-en-3-comandos] ```bash make setup # crea venv, instala deps, copia .env.example a .env nano .env # o tu editor preferido; poné tu SIFENDE_API_KEY make emitir FILE=sample_factura.json ``` `make setup` crea un entorno virtual en `.venv/`, instala las dependencias y copia `.env.example` a `.env` si todavía no existe. Después abrís `.env` y pegás tu `SIFENDE_API_KEY`. Si todo salió bien, vas a ver el `cdc` impreso en consola y un directorio `documentos/{cdc}/` con `payload.json`, `response.json` y, una vez aprobado, `kude.pdf`. Para probar el sample de crédito desde archivo: ```bash make emitir FILE=sample_factura_credito.json ``` El wizard interactivo (`make emitir-i`) sigue limitado a facturas al contado. El crédito se emite pasando un archivo JSON con `--file`. ### Sin Make [#sin-make] ```bash python3 -m venv .venv source .venv/bin/activate # Windows PowerShell: .venv\Scripts\Activate.ps1 pip install -r requirements.txt cp .env.example .env # editá .env con tu API key python sifende.py emitir --file sample_factura.json ``` ## Configuración [#configuración] La CLI busca tu API key en este orden (gana el primero que la encuentre): 1. Flag `--api-key` en la línea de comandos 2. Variable de entorno `SIFENDE_API_KEY` 3. Archivo `.env` en el directorio actual 4. Archivo `.env` en la raíz del paquete CLI La API key nunca se ecoa, ni en logs ni en mensajes de error. Podés correr `--debug` con tranquilidad. ### Variables soportadas en `.env` [#variables-soportadas-en-env] | Variable | Default | | ------------------- | ------------------------------------ | | `SIFENDE_API_KEY` | (requerido) | | `SIFENDE_BASE_URL` | `https://api.sifende.com.py/api/v1/` | | `SIFENDE_TIMEOUT_S` | `30` | El ambiente lo determina la API key: `sk_sandbox_` usa Sandbox de Sifende, `sk_test_` envía a pruebas de SIFEN y `sk_live_` a producción. Todos usan la misma URL base; mantené el valor por defecto. SANDBOX no admite cancelar ni inutilizar. Consultá [Ambientes](/docs/conceptos/ambientes). ## Comandos [#comandos] Cada operación está disponible en dos formas: con `make` (más corto, ideal para uso interactivo) o con `python sifende.py` (más explícito, ideal para scripts). `emitir` espera la confirmación de SIFEN antes de retornar: la CLI hace polling automático del estado hasta que el documento llegue a un estado terminal (`APROBADO`, `APROBADO_OBSERVACION`, `RECHAZADO` o `ERROR`). Si querés solo enviar y no esperar, pasá `--no-wait`. Para polling manual sobre un CDC ya emitido, usá `estado`. | Operación | Make | Python | | -------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | | Emitir desde archivo | `make emitir FILE=factura.json` | `python sifende.py emitir --file factura.json` | | Emitir interactivo | `make emitir-i` | `python sifende.py emitir` | | Consultar estado | `make estado CDC=` | `python sifende.py estado ` | | Descargar KuDE | `make kude CDC= OUT=factura.pdf` | `python sifende.py kude --out factura.pdf` | | Cancelar | `make cancelar CDC= MOTIVO="..."` | `python sifende.py cancelar --motivo "..."` | | Inutilizar | `make inutilizar TIPO=1 EST=001 PE=001 TIMBRADO= DESDE=1 HASTA=3 MOTIVO="..."` | `python sifende.py inutilizar --tipo-documento 1 --establecimiento 001 --punto-expedicion 001 --numero-timbrado --desde 1 --hasta 3 --motivo "..."` | | Debug HTTP | `make debug FILE=factura.json` | `python sifende.py --debug emitir --file factura.json` | ### Flags globales [#flags-globales] Estos flags funcionan en todos los comandos: | Flag | Qué hace | | ------------------ | -------------------------------------------------------------- | | `--api-key ` | Pisa la API key resuelta del entorno | | `--base-url ` | Pisa la URL base de la API | | `--quiet` | Solo imprime el dato esencial (CDC, estado) | | `--json` | Imprime la respuesta cruda como JSON | | `--debug` | Traza HTTP completa con headers (la API key queda enmascarada) | Con `make` se reenvían como `EXTRA="..."`: ```bash make emitir FILE=factura.json EXTRA="--json --quiet" ``` ## Comportamiento al aprobar [#comportamiento-al-aprobar] Al confirmarse la aprobación de un documento, la CLI guarda automáticamente: ``` documentos/ └── {cdc}/ ├── payload.json # solicitud enviada ├── response.json # respuesta de la API └── kude.pdf # KuDE descargado ``` Esto te da un audit trail local para cada emisión sin trabajo extra. ## Ejemplo: emitir y descargar el KuDE [#ejemplo-emitir-y-descargar-el-kude] ```bash # 1. Emitir desde el archivo de muestra make emitir FILE=sample_factura.json # Salida: # CDC: 01800123451001001000000122026050910000000001 # Estado: PENDIENTE → APROBADO # 2. Consultar estado por CDC make estado CDC=01800123451001001000000122026050910000000001 # 3. Descargar el KuDE PDF make kude CDC=01800123451001001000000122026050910000000001 OUT=factura.pdf ``` ## Ejemplo: cancelar un documento aprobado [#ejemplo-cancelar-un-documento-aprobado] ```bash make cancelar \ CDC=01800123451001001000000122026050910000000001 \ MOTIVO="Error en datos del receptor" ``` Recordá que cancelar tiene 48 horas desde la aprobación para FE y 168 horas para NCE, NDE y NRE. Para ajustar una factura fuera de plazo, consultá la guía de [Nota de Crédito](/docs/guias/nota-credito). ## Ejemplo: inutilizar un rango de numeración [#ejemplo-inutilizar-un-rango-de-numeración] Si saltaste números (por ejemplo, una falla puntual te dejó huecos del 25 al 30), inutilizalos antes de seguir emitiendo: ```bash make inutilizar \ TIPO=1 \ EST=001 \ PE=001 \ TIMBRADO=12557896 \ DESDE=0000025 \ HASTA=0000030 \ MOTIVO="Números no utilizados por error de sistema" ``` Para entender cuándo y cómo usar este flujo, revisá [Inutilizar Numeración](/docs/guias/inutilizar-numeracion). ## Estructura del payload [#estructura-del-payload] El archivo JSON que pasás a `emitir --file` es exactamente el mismo cuerpo que envía la API REST. El repositorio incluye: * [`sample_factura.json`](https://github.com/ithdev/sifende-cli/blob/main/sample_factura.json), una factura B2C al contado. * [`sample_factura_credito.json`](https://github.com/ithdev/sifende-cli/blob/main/sample_factura_credito.json), un crédito por cuotas con entrega inicial. ```bash make emitir FILE=sample_factura_credito.json # Equivalente: python sifende.py emitir --file sample_factura_credito.json ``` La emisión desde archivo soporta `PLAZO` y `CUOTA`. El wizard interactivo no solicita esos campos y continúa generando sólo contado. Para construir tu propio payload, ver: * [Modelos: Factura Electrónica](/docs/referencia/modelos/factura-electronica) * [Modelo: Condición de Pago](/docs/referencia/modelos/condicion-pago) * [Endpoint: Emitir](/docs/referencia/documentos-electronicos/emitir) ## Solución de problemas [#solución-de-problemas] | Síntoma | Causa probable | Cómo resolverlo | | -------------------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------- | | `SIFENDE_API_KEY no configurada` | El `.env` está vacío o no se cargó | Verificá `.env` en el directorio actual o pasá `--api-key` | | `401 Invalid or expired API key` | Key revocada o pegada con espacios | Rotá la credencial desde el panel → API Keys | | `400 validation-error` | Payload mal armado | Corré con `--debug` y revisá `errores` en la respuesta | | `422 timbrado-no-vigente` | La fecha de emisión es anterior al inicio de vigencia del timbrado | Revisá la fecha de inicio del timbrado en el panel | | `make: command not found` | No tenés Make instalado | Usá la forma `python sifende.py ...` | Para errores de SIFEN (códigos 1xxx, 2xxx, 3xxx), revisá [Rechazos SIFEN](/docs/solucion-problemas/rechazos-sifen). ## Recursos [#recursos] * Repositorio: [github.com/ithdev/sifende-cli](https://github.com/ithdev/sifende-cli) (código fuente, ejemplos y `CHANGELOG.md`) * Issues: [reportá bugs o pedí mejoras](https://github.com/ithdev/sifende-cli/issues) * Referencia API: [Documentos Electrónicos](/docs/referencia/documentos-electronicos) * Inicio Rápido: [Paso 2: Tu Primera Factura](/docs/inicio-rapido/paso-2-primera-factura) # Inicio Rápido (/docs/inicio-rapido) Esta guía te lleva desde cero hasta tu primer documento electrónico aprobado por SIFEN. ## Lo que vas a lograr [#lo-que-vas-a-lograr] Al final de esta guía vas a tener: 1. Un API key configurado y listo para usar. 2. Tu primera Factura Electrónica emitida y su CDC generado. 3. El estado de procesamiento verificado vía SIFEN. ## Requisitos previos [#requisitos-previos] Antes de empezar, asegurate de tener: * Un certificado digital PKCS12 emitido por un prestador de servicios de certificación autorizado. * RUC activo y autorizado para emitir electrónicamente. ¿No tenés estos datos? Empezá por [Requisitos Previos](/docs/inicio-rapido/requisitos-previos). ## Pasos [#pasos] [Configurar tus credenciales y obtener un API key](/docs/inicio-rapido/paso-1-credenciales) [Emitir tu primera Factura Electrónica](/docs/inicio-rapido/paso-2-primera-factura) [Verificar el estado de procesamiento](/docs/inicio-rapido/paso-3-verificar-estado) [Ir a producción](/docs/inicio-rapido/paso-4-produccion) ## ¿Qué sigue? [#qué-sigue] Una vez que tengas tu primera factura aprobada, podés seguir por dos caminos: ## Configurar desde el panel [#configurar-desde-el-panel] Consultá las [guías del panel](/docs/panel) para administrar las API keys, el certificado, el CSC, el timbrado y el acceso de tu equipo. # Paso 1: Configurar Credenciales (/docs/inicio-rapido/paso-1-credenciales) En este paso vas a configurar todo lo que hace falta en Sifende para hacer tu primera llamada a la API. ## 1.1 Crear tu cuenta y contribuyente [#11-crear-tu-cuenta-y-contribuyente] Si es tu primera vez, ingresá a [app.sifende.com.py](https://app.sifende.com.py) y creá tu cuenta. Después, creá un **Contribuyente**. Llená la información que pide: RUC, datos básicos, datos de contacto, ubicación fiscal y actividades económicas. ## 1.2 Subir el certificado digital [#12-subir-el-certificado-digital] Desde el panel de Sifende, andá a [**Contribuyente → Certificado digital**](https://app.sifende.com.py/certificado-digital) y subí tu archivo PKCS12 junto con la contraseña. Cargá el IdCSC y el CSC del ambiente de pruebas según la [guía del panel](/docs/panel/certificado-y-csc). ## 1.3 Configurar el timbrado [#13-configurar-el-timbrado] Desde [**Contribuyente → Timbrado**](https://app.sifende.com.py/timbrado), elegí el ambiente de pruebas e ingresá el número y la fecha de inicio de tu timbrado. Si estás en el ambiente de pruebas, podés usar: * Tu RUC (sin dígito verificador) como número de timbrado (rellenar con ceros a la izquierda si hace falta). * Fecha de inicio: la fecha en que tu Formulario 364 quedó "Aceptado" (debe coincidir **exactamente** con la de SET, o vas a recibir el rechazo `1107`). Estos datos tienen que coincidir con el dataset que SET provisiona al habilitarte. Ver [El ambiente de prueba (TEST)](/docs/solucion-problemas/rechazos-comunes#ambiente-prueba). ## 1.4 Crear tu API key [#14-crear-tu-api-key] Desde [**API Keys**](https://app.sifende.com.py/api-keys), seleccioná **Crear API Key** y elegí **DEV — Pruebas con SIFEN**. Guardá el valor generado: no se muestra de nuevo. ```bash # Te recomendamos guardar tu API Key, la vas a usar en los próximos pasos. export SIFENDE_API_KEY="sk_test_..." ``` ¿Querés probar tu API key en segundos? La [Sifende CLI](/docs/herramientas/sifende-cli) te deja emitir tu primer documento con 3 comandos, sin escribir código. Tu API key tiene permisos completos para el contribuyente. Tratala como una contraseña: nunca la incluyas en el código fuente ni en repositorios públicos. Cuando esté todo listo, seguí con [Paso 2: Tu primera Factura Electrónica](/docs/inicio-rapido/paso-2-primera-factura). # Paso 2: Tu Primera Factura Electrónica (/docs/inicio-rapido/paso-2-primera-factura) Un endpoint para todos los tipos de documento. Sifende usa un único endpoint `POST /api/v1/documento-electronico` para todos los tipos de documento electrónico. El campo `tipoDocumento` define qué tipo emitís. Más información en [Emitir Documento Electrónico](/docs/referencia/documentos-electronicos/emitir). ## Tu primera factura [#tu-primera-factura] Para tu primer ejemplo usamos un receptor **innominado**: un consumidor final anónimo (sin cédula, sin RUC). Es el caso más simple y permite emitir facturas válidas sin pedirle datos al comprador. En el modelo de Sifende eso se expresa con `tipoContribuyente: "NO_CONTRIBUYENTE"` más `tipoDocumento: "INNOMINADO"`. SIFEN igual exige un `numeroDocumento` y un `nombreRazonSocial`: para el caso innominado los valores literales son `"0"` y `"Sin Nombre"`. ¿Querés hacer todo esto más rápido? Probá la [Sifende CLI](/docs/herramientas/sifende-cli): emite, consulta estado y descarga el KuDE desde la terminal con tres comandos. ```bash 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-04-15T10:30:00", "tipoEmision": "NORMAL", "numeroEstablecimiento": 1, "puntoExpedicion": 1, "tipoTransaccion": "VENTA_MERCADERIA", "monedaOperacion": "PYG", "receptor": { "tipoContribuyente": "NO_CONTRIBUYENTE", "tipoOperacion": "B2C", "tipoDocumento": "INNOMINADO", "numeroDocumento": "0", "nombreRazonSocial": "Sin Nombre" }, "condicionOperacion": "CONTADO", "condicionPago": { "tipo": "CONTADO", "tipoPago": "EFECTIVO", "monedaPago": "PYG", "montoPago": 110000 }, "items": [ { "codigo": "PROD-001", "descripcion": "Resma de papel A4 75g", "cantidad": 10, "unidadMedida": "UNI", "precioUnitario": 11000, "afectacionTributaria": "GRAVADO", "tasaIVA": 10 } ] }' ``` ## Respuesta exitosa [#respuesta-exitosa] Si el documento se aceptó, la API responde `202 Accepted` con los datos del documento: ```json { "id": "550e8400-e29b-41d4-a716-446655440000", "cdc": "01800123451001001000000122026042710000000006", "estado": "PENDIENTE", "ambiente": "DEV", "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" } ``` El campo `cdc` contiene el Código de Control del Documento Electrónico: 44 caracteres que identifican a tu documento en SIFEN. Guardalo junto con el `id`: los vas a necesitar para consultar estado, descargar el KuDE y cancelar. 202 Accepted, no 200 OK. El estado inicial siempre es `PENDIENTE`: el documento aún no fue procesado por SIFEN. Mirá el [Paso 3](/docs/inicio-rapido/paso-3-verificar-estado) para hacer polling del estado real. Los montos en guaraníes (PYG) son números enteros sin decimales. `10000` = Gs. 10.000. Ver [Convenciones](/docs/referencia/convenciones) para más detalles. ## Con receptor identificado [#con-receptor-identificado] Si tu cliente da su cédula o RUC, podés emitir la factura a su nombre. Reemplazá el bloque `receptor` del ejemplo anterior por alguno de los siguientes. Receptor B2C con cédula: ```json "receptor": { "tipoContribuyente": "NO_CONTRIBUYENTE", "tipoOperacion": "B2C", "tipoDocumento": "CEDULA_PARAGUAYA", "numeroDocumento": "1234567", "nombreRazonSocial": "Juan Pérez" } ``` Para receptores B2B (con RUC) y otros casos, consultá la guía [Receptor B2B vs B2C](/docs/guias/receptor-b2b-b2c). ## ¿Algo salió mal? [#algo-salió-mal] Consultá [Errores Comunes](/docs/solucion-problemas/errores-comunes) o la [Referencia de Errores](/docs/referencia/errores). Seguí con [Paso 3: Verificar el Estado](/docs/inicio-rapido/paso-3-verificar-estado). # Paso 3: Verificar el Estado (/docs/inicio-rapido/paso-3-verificar-estado) Consultá el CDC obtenido en el paso anterior: ```bash curl "https://api.sifende.com.py/api/v1/documento-electronico/status/$CDC" \ -H "Authorization: Bearer $SIFENDE_API_KEY" ``` ## Interpretar la respuesta [#interpretar-la-respuesta] ```json { "cdc": "01800123451001001000000122026042710000000006", "estado": "APROBADO", "ambiente": "DEV", "iTiDe": 1, "numeroDocumento": 1, "fechaCreacion": "2026-04-27T10:30:00", "protocoloAutorizacion": "01202604150000123456", "mensajeRechazo": null } ``` | Estado | Qué significa | Qué hacer | | ---------------------- | -------------------------------------------------------- | ------------------------------------------------------------------ | | `PENDIENTE` | Sifende recibió el documento y está preparando su envío | Seguí consultando | | `EN_LOTE` | En proceso de envío o a la espera del resultado de SIFEN | Seguí consultando | | `APROBADO` | SIFEN aceptó el documento | Detené las consultas; guardá el protocolo | | `APROBADO_OBSERVACION` | SIFEN aceptó el documento con observaciones | Detené las consultas y revisá `mensajeRechazo`; no lo reemitas | | `RECHAZADO` | SIFEN rechazó el documento | Detené las consultas y corregí el motivo antes de emitir uno nuevo | | `CANCELADO` | Se confirmó la cancelación de un documento aprobado | Detené las consultas | | `ERROR` | El envío falló de forma definitiva | Detené las consultas y revisá el panel; no lo reemitas | ## Esperar el resultado [#esperar-el-resultado] Consultá cada **5 segundos** durante un máximo de **5 minutos**. Si el documento sigue en proceso, conservá el CDC y retomá después. Un timeout no indica rechazo. En `ERROR`, el documento no se reintenta solo. Pedí el reintento a [soporte](/docs/solucion-problemas/soporte) o seguí la [guía para reintentar el lote](/docs/panel/lotes). Al reintentarlo vuelve a `EN_LOTE` y podés retomar las consultas con el mismo CDC. Consultá [Polling de resultados](/docs/guias/polling-resultados) para automatizar la espera. Con un documento aprobado, podés [descargar el KuDE](/docs/guias/descargar-kude) y continuar al [Paso 4: Ir a producción](/docs/inicio-rapido/paso-4-produccion). # Paso 4: Ir a Producción (/docs/inicio-rapido/paso-4-produccion) Antes de enviar documentos con validez fiscal, completá este checklist: * [ ] Contribuyente habilitado para producción. * [ ] Certificado activo y vigente: el mismo que usaste en pruebas. * [ ] Timbrado de producción con número y fechas exactas de la SET. * [ ] ID CSC y CSC de producción configurados. * [ ] API key `sk_live_` creada en **API Keys**, eligiendo **PROD — Documentos con validez fiscal**. * [ ] Variable `SIFENDE_API_KEY` actualizada con esa clave. * [ ] Consulta de estado, reintentos con idempotencia y descarga de KuDE probados. La URL base sigue siendo `https://api.sifende.com.py`. La clave `sk_test_` que usabas antes conserva su ambiente de pruebas. Seguí la guía [Ir a producción](/docs/guias/ir-a-produccion) para ver los pasos y las verificaciones. Si necesitás ayuda, consultá [Soporte](/docs/solucion-problemas/soporte). # Requisitos Previos (/docs/inicio-rapido/requisitos-previos) Antes de emitir tu primer documento electrónico con Sifende, necesitás obtener el certificado de un prestador autorizado y los datos de habilitación de la SET. Esta página explica qué es cada uno y cómo conseguirlo. Estos requisitos corresponden a DEV y PROD. Si todavía no tenés timbrado o CSC, podés usar [SANDBOX](/docs/conceptos/ambientes#sandbox-de-sifende) con tu certificado activo, dirección y actividad económica. ## Certificado Digital (PKCS12) [#certificado-digital-pkcs12] El certificado digital es el equivalente a tu firma electrónica. Sifende lo usa para firmar cada documento electrónico que emitís. **¿Qué necesitás?** * Un archivo `.p12` o `.pfx` (formato PKCS12). * La contraseña del certificado. **¿Cómo obtenés el certificado?** * Solicitalo a un **prestador de servicios de certificación autorizado**. La lista oficial vigente está en [acraiz.gov.py](https://acraiz.gov.py/html/Certif_1PrestaServ.html) — son empresas privadas habilitadas por el Estado para emitir certificados digitales con validez legal. * El proceso incluye verificación presencial o digital de tu identidad y de tu RUC según el tipo de contribuyente. * El prestador te entrega el archivo `.p12` (o `.pfx`) y la contraseña que vas a usar en Sifende. El certificado tiene fecha de vencimiento. Sifende te avisa cuando se acerca el vencimiento, pero renovarlo a tiempo queda de tu lado. ## CSC (Código de Seguridad del Contribuyente) [#csc-código-de-seguridad-del-contribuyente] La SET asigna a cada contribuyente un identificador de 4 caracteres y un código CSC de 32 caracteres para generar el código QR del KuDE. **¿Cómo obtenés el CSC?** * Se solicita junto con la habilitación como facturador electrónico en la SET. * Configurá en Sifende el identificador de 4 caracteres y el código CSC de 32 caracteres de cada ambiente. ## Timbrado Electrónico [#timbrado-electrónico] El timbrado es la habilitación de la SET para emitir documentos. El **timbrado electrónico** (e-timbrado) es distinto al timbrado tradicional en papel: es específico para documentos electrónicos. **¿Cómo obtenés el timbrado electrónico?** * Se solicita a través de Marangatu una vez que estás habilitado como facturador electrónico. * Tiene una fecha de inicio de vigencia y no tiene fecha de fin. * Cargá su número y fecha de inicio por ambiente desde [Contribuyente → Timbrado](/docs/panel/timbrado). Si ya tenés timbrado para documentos en papel, no es el mismo. Necesitás solicitar un timbrado electrónico aparte. ## Ambiente de Pruebas (QA) [#ambiente-de-pruebas-qa] Antes de ir a producción, podés probar tu integración en el ambiente de pruebas de SIFEN. **Credenciales de prueba:** * Usá el mismo certificado digital que vas a usar en producción. * Los timbrados de prueba son distintos a los de producción. * Las RUCs de receptores también tienen valores de prueba definidos por la SET. Para emitir en el ambiente de prueba, tu RUC tiene que estar habilitado como facturador electrónico (Formulario 364) y SET provisiona un dataset de prueba con una convención fija (timbrado = tu RUC sin DV, establecimiento `001`, puntos `001`/`002`/`003`, CSC genéricos). Ver [El ambiente de prueba (TEST)](/docs/solucion-problemas/rechazos-comunes#ambiente-prueba). ## Checklist antes de integrar [#checklist-antes-de-integrar] * [ ] Certificado digital PKCS12 + contraseña * [ ] Identificador de 4 caracteres y código CSC de 32 caracteres * [ ] Número de timbrado electrónico * [ ] Fecha de inicio de vigencia del timbrado (`fechaInicio`) * [ ] Número de establecimiento y punto de expedición * [ ] API key `sk_test_` y timbrado y CSC de pruebas Una vez que tenés todo esto, seguí con [Paso 1: Configurar tus credenciales](/docs/inicio-rapido/paso-1-credenciales). # Características (/docs/plataforma/caracteristicas) Sifende cubre el ciclo completo del documento electrónico: firma digital, transmisión a SIFEN, seguimiento del estado y notificación al receptor. ## Conexión automatizada con e-kuatia [#conexión-automatizada-con-e-kuatia] Sifende gestiona la conexión con e-kuatia de la DNIT: firma digital con tu certificado P12, generación del XML según el Manual Técnico V150, envío por lotes, transmisión vía SOAP y consulta de resultados. Vos enviás un POST con JSON. Del resto se encarga la plataforma. 99.9% de uptime, baja latencia y reintentos automáticos. Ante fallas transitorias de la DNIT, Sifende reintenta el envío automáticamente. No perdés emisiones. ### Todos los documentos electrónicos [#todos-los-documentos-electrónicos] Emití Factura Electrónica (FE), Nota de Crédito Electrónica (NCE), Nota de Débito Electrónica (NDE), Nota de Remisión Electrónica (NRE) y Autofactura Electrónica (AFE) desde una sola API REST. Cada documento queda firmado, validado y rastreable por su CDC (Código de Control del Documento Electrónico). ### Procesamiento por lotes para alto volumen [#procesamiento-por-lotes-para-alto-volumen] Para integraciones con alto volumen: * [Envío por lotes a SIFEN](/docs/conceptos/lotes), con seguimiento de cada documento por CDC. * Reintentos automáticos ante errores transitorios de red o de la DNIT. * Clasificación de errores que separa los recuperables de los definitivos, para que no pierdas tiempo reintentando lo que no se va a aprobar. * Miles de documentos por minuto sostenidos. ### Seguridad por diseño [#seguridad-por-diseño] La facturación electrónica maneja datos fiscales sensibles, así que la plataforma se diseñó con eso en mente desde el primer día: * Certificados P12 cifrados en reposo. Los subís una sola vez al panel web. * La clave completa solo se muestra una vez al crearla. * Errores en formato RFC 9457 (Problem Details), para integraciones predecibles. * Multi-tenant con aislamiento estricto de datos por contribuyente. ### Panel web completo [#panel-web-completo] Más allá de la API, Sifende incluye un panel web donde podés: * Navegar, filtrar y rastrear todos tus documentos electrónicos. * Descargar el XML firmado y el KuDE en PDF. * Visualizar el código QR del documento. * Consultar el estado de cada documento en tiempo real. * Gestionar contribuyentes, timbrados y certificados. ### API keys y multi-usuario [#api-keys-y-multi-usuario] Gestión completa del acceso a la plataforma: * API keys: crealas, rotalas y eliminalas desde el panel web. Podés tener varias claves activas para separar ambientes o servicios. * Equipos: invitá miembros con control de acceso por rol. * Multi-tenant: una sola cuenta puede administrar varios contribuyentes (RUCs), útil para contadores y proveedores de software. ### Notificaciones por email [#notificaciones-por-email] Configurá emails de receptor en tus DEs y Sifende genera el KuDE en PDF y envía automáticamente una notificación al cliente. Sin código adicional ni servicios SMTP que mantener. ## ¿Listo para empezar? [#listo-para-empezar] # Cómo Funciona (/docs/plataforma/como-funciona) Sifende reduce el flujo de e-kuatia (SIFEN) a tres pasos. Enviás un JSON y recibís un CDC para consultar el resultado. Sifende se encarga de la firma y el envío a SIFEN. ¿Cuánto toma integrar? Una integración básica se completa en horas, no en semanas. Solo hace falta un POST HTTP con JSON, y todos los planes incluyen acceso al ambiente de pruebas para probar sin compromiso. ## El flujo en 3 pasos [#el-flujo-en-3-pasos] **Registrate y configurá** Creá tu cuenta gratis, subí tu certificado digital P12 y configurá tu timbrado electrónico. Todo desde el panel web, una sola vez. Sifende almacena tu certificado de forma segura y lo usa automáticamente para firmar cada documento. También te avisa cuando esté por vencer. **Enviá un JSON a nuestra API** Usá la API REST de Sifende para crear FE, AFE, NCE, NDE o NRE. Sin XML, sin SOAP: solo JSON. ```bash 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", ... }' ``` Un único endpoint maneja los tipos disponibles de documento: el campo `tipoDocumento` decide cuál emitís. **Consultá el resultado** Sifende firma tu documento con el certificado P12, lo transmite a SIFEN y consulta el resultado automáticamente. La respuesta inicial confirma que la emisión fue recibida. Después, [consultá el estado](/docs/guias/consultar-estado) para saber si SIFEN aprobó o rechazó el documento. El CDC es el identificador único de 44 caracteres que Sifende asigna al emitir. Guardalo: con eso consultás estado, descargás el KuDE o cancelás. ## ¿Qué hace Sifende detrás de escena? [#qué-hace-sifende-detrás-de-escena] Aunque vos solo ves un POST y un CDC, en cada emisión Sifende: 1. Valida tu JSON según el Manual Técnico de SIFEN. 2. Genera el XML según el formato exacto que exige SIFEN. 3. Firma digitalmente el XML con tu certificado P12. 4. Envía el documento a SIFEN. 5. Consulta el resultado del documento. 6. Mapea los códigos de respuesta de SIFEN a estados claros (`APROBADO`, `RECHAZADO`, etc.). 7. Notifica por email al receptor (si configuraste su correo) con el KuDE adjunto. Si SIFEN rechaza el documento, la consulta de estado devuelve `RECHAZADO` y el motivo en `mensajeRechazo`. Revisá cómo [corregir y emitir un documento nuevo](/docs/guias/reintentar-rechazados). ## Ambiente de pruebas [#ambiente-de-pruebas] Todos los planes (incluido el gratis) tienen acceso al ambiente de pruebas de la DNIT. Podés validar tu integración con datos de prueba antes de pasar a producción, sin gastar emisiones reales. Para probar sin enviar documentos a SIFEN, usá [SANDBOX](/docs/conceptos/ambientes#sandbox-de-sifende). Cuando estés listo para producción, solo cambiás de credenciales: el contrato de la API es idéntico. ## Próximos pasos [#próximos-pasos] # La Plataforma (/docs/plataforma) ## ¿Qué es Sifende? [#qué-es-sifende] Sifende es una plataforma SaaS paraguaya que se encarga de la integración con e-kuatia (SIFEN) de la DNIT: firma digital con certificado P12, generación de XML según el Manual Técnico V150, envío por lotes, transmisión vía SOAP y consulta de resultados, todo detrás de una API REST en JSON. En lugar de implementar SOAP, XSD, certificados y reintentos vos mismo, mandás un POST con JSON y recibís el CDC aprobado. Sifende corre la integración con la DNIT por vos. ## ¿Para quién? [#para-quién] * Equipos de desarrollo que necesitan integrar facturación electrónica en un ERP, e-commerce o software propio sin construir la integración SOAP desde cero. * Empresas con alto volumen que requieren procesamiento por lotes, reintentos automáticos y trazabilidad por CDC. * Contadores y consultores que gestionan varios contribuyentes (RUCs) desde una sola cuenta. * Negocios multi-establecimiento que necesitan más capacidad que la que ofrece e-kuatia'i de la DNIT. ## Recorrido por la plataforma [#recorrido-por-la-plataforma] ## ¿Listo para integrar? [#listo-para-integrar] Si ya conocés la plataforma y querés ir directo al código, andá al [Inicio Rápido](/docs/inicio-rapido) o a la [Referencia API](/docs/referencia). # Planes y Precios (/docs/plataforma/planes) Los **planes mensuales** son la opción principal para emitir habitualmente. Para emisión ocasional, también hay **packs de documentos por RUC**, con una compra y un vencimiento propios. Las modalidades son excluyentes: el saldo de un pack no se combina con el cupo mensual. Modelo de facturación: los precios son por contribuyente (RUC) por mes. Una sola cuenta de Sifende puede administrar varios contribuyentes; cada RUC se factura por separado según el plan asignado. El cupo mensual de documentos también es por RUC. Todos los precios están en guaraníes e incluyen IVA. ## Planes [#planes] | | FREE | PLUS | PRO | MAX | | --- | --- | --- | --- | --- | | **Documentos / mes** | Ilimitados, sólo en pruebas | 50 | 250 | 1.000 | | **Precio mensual (IVA incluido)** | Gs. 0 | Gs. 44.900 | Gs. 99.900 | Gs. 299.900 | | **Documento adicional (IVA incluido)** | No disponible | Gs. 900 | Gs. 400 | Gs. 300 | | **Acceso a los documentos** | 3 meses | 60 meses | 60 meses | 60 meses | ## Packs de documentos [#packs-de-documentos] Compra puntual por RUC, con precio final en PYG. Soporte confirma el pago por transferencia y activa el saldo; desde ese instante corre la vigencia del pack, en meses calendario de `America/Asuncion`. | | Pack 20 | Pack 40 | Pack 80 | | --- | --- | --- | --- | | **Documentos** | 20 | 40 | 80 | | **Precio (IVA incluido)** | Gs. 39.900 | Gs. 69.900 | Gs. 119.900 | | **Vigencia del saldo** | 12 meses | 12 meses | 12 meses | | **Acceso a los documentos** | 60 meses | 60 meses | 60 meses | ## Qué incluye cada nivel [#qué-incluye-cada-nivel] | | FREE | PLUS | PRO | MAX | Packs de documentos | | --- | --- | --- | --- | --- | --- | | DEV contra DNIT y SANDBOX local | ✓ | ✓ | ✓ | ✓ | ✓ | | Entorno de desarrollo | ✓ | ✓ | ✓ | ✓ | ✓ | | Emisión en producción, con validez fiscal | — | ✓ | ✓ | ✓ | ✓ | | Factura Electrónica (FE) | ✓ | ✓ | ✓ | ✓ | ✓ | | Nota de Crédito Electrónica (NCE) | ✓ | ✓ | ✓ | ✓ | ✓ | | Nota de Débito Electrónica (NDE) | ✓ | ✓ | ✓ | ✓ | ✓ | | Nota de Remisión Electrónica (NRE) | ✓ | — | ✓ | ✓ | — | | Autofactura Electrónica (AFE) | ✓ | — | ✓ | ✓ | — | | Panel web | ✓ | ✓ | ✓ | ✓ | ✓ | | App móvil | ✓ | ✓ | ✓ | ✓ | ✓ | | API REST y API keys | ✓ | — | ✓ | ✓ | — | | Personalización de marca en el KuDE | ✓ | — | ✓ | ✓ | — | | Control de inventario | ✓ | ✓ | ✓ | ✓ | ✓ | | Onboarding asistido | — | — | ✓ | ✓ | — | | Soporte prioritario | — | — | — | ✓ | — | El plan gratuito no emite en producción. Sirve para armar y validar la integración completa sin límite de documentos, pero lo que genera no tiene validez fiscal. Para emitir ante SIFEN hace falta un plan pago o un pack. En producción, los tipos de documento y la API de integración dependen del plan vigente: una operación que el plan no incluye recibe `403 plan-operation-not-allowed`. Si el plan no incluye la personalización, el KuDE se genera con la plantilla estándar. En pruebas, todos los planes y packs incluyen todas las funciones. Las funciones de un plan nuevo se habilitan cuando ese plan se activa. ## Detalle por nivel [#detalle-por-nivel] **FREE (Gs. 0, sin vencimiento)** Para armar la integración y probarla entera antes de pagar nada. Sin tarjeta y sin fecha de vencimiento. - Documentos ilimitados en el ambiente de pruebas: las emisiones de prueba nunca consumen cupo - Factura, nota de crédito, nota de débito, nota de remisión y autofactura - API REST y personalización del KuDE - No emite en producción: los documentos no tienen validez fiscal - Acceso a los documentos durante 3 meses **PLUS (Gs. 44.900 / mes)** Para el contribuyente que emite poco y factura desde el panel o la app. - 50 documentos electrónicos por mes, con validez fiscal - Documentos adicionales a Gs. 900 cada uno, sin bloquear la emisión al agotar el cupo - Factura, nota de crédito y nota de débito - Acceso a los documentos durante 60 meses **PRO (Gs. 99.900 / mes)** El salto grande: suma la integración por API y el resto de los tipos de documento. - 250 documentos electrónicos por mes, con validez fiscal - Documentos adicionales a Gs. 400 cada uno, sin bloquear la emisión al agotar el cupo - Factura, nota de crédito, nota de débito, nota de remisión y autofactura - API REST y personalización del KuDE - Acceso a los documentos durante 60 meses - Onboarding asistido **MAX (Gs. 299.900 / mes)** Todo lo de PRO, con más volumen y atención preferente. - 1.000 documentos electrónicos por mes, con validez fiscal - Documentos adicionales a Gs. 300 cada uno, sin bloquear la emisión al agotar el cupo - Factura, nota de crédito, nota de débito, nota de remisión y autofactura - API REST y personalización del KuDE - Acceso a los documentos durante 60 meses - Onboarding asistido - Soporte prioritario **Packs de documentos** Para volumen irregular o estacional: se compran una vez y no generan cuota mensual. - 20 documentos por Gs. 39.900, 40 documentos por Gs. 69.900 y 80 documentos por Gs. 119.900 - Factura, nota de crédito y nota de débito; panel web, app móvil y control de inventario - Sin nota de remisión, autofactura, API REST ni personalización del KuDE - Vigencia de 12 meses calendario desde la confirmación del pago por soporte - Acceso a los documentos durante 60 meses; la vigencia sólo limita el saldo para emitir * Un pack a la vez: la siguiente compra se habilita al consumir todos los documentos o al vencer * Las reservas en proceso no son consumo definitivo; las pruebas en DEV y SANDBOX no consumen saldo * Sin acumulación ni renovación automática: el saldo vencido se pierde Para pasar de un plan mensual a packs, solicitá el cambio en **Planes y facturación**. Se aplica al cierre del ciclo vigente y después habilita la compra. Programar o cancelar el cambio no genera un cobro. Para contratar un plan desde packs, no deben quedar documentos disponibles, reservas pendientes ni una compra pendiente de resolución. Los documentos reservados antes del vencimiento pueden terminar su procesamiento. Un rechazo libera la reserva, pero no recupera saldo utilizable de un pack vencido. La cancelación de un documento aprobado mantiene su consumo. El panel muestra comprados, consumidos, en proceso, disponibles y vencimiento. Al terminar el pack, podés **Contratar un plan** o, como alternativa, **Comprar otro pack**. Soporte también puede anular una compra pendiente; esto no otorga saldo. **A medida (a convenir)** Para empresas grandes y proveedores de software con alto volumen que necesitan un contrato con SLA y un costo por documento negociado. - Volúmenes por encima de MAX - Precio por documento negociado según volumen - SLA con penalidades contractuales - Implementación y onboarding dedicados - Soporte 24/7 por WhatsApp y teléfono - Contrato anual personalizado ## Cómo funciona el cupo mensual [#cómo-funciona-el-cupo-mensual] * Cada plan incluye una cantidad de documentos por mes. Cuentan las FE, AFE, NCE, NDE y NRE confirmadas en producción. * Un documento en proceso, con resultado pendiente o todavía reintentable reserva capacidad en su período original. Esa reserva no es consumo confirmado ni un documento adicional cobrado. * Los planes con precio por documento adicional en la [tabla de planes](#planes) permiten seguir emitiendo al agotar el cupo. Solo los documentos confirmados por encima del cupo generan adicionales; las reservas nunca generan cargos. * Al habilitar los adicionales en una suscripción existente, se conserva el consumo y la fecha de corte. Solo pueden cobrarse como adicionales las emisiones admitidas desde la entrada en vigencia de la nueva tarifa; los documentos anteriores no generan cargos retroactivos. * El plan gratuito no emite en producción: una nueva emisión recibe `403 plan-operation-not-allowed`. En un plan sin adicionales, cuando la suma de confirmados y reservas alcanza el cupo, una nueva emisión recibe `403 document-quota-exceeded`. En ambos casos no se crea documento, CDC ni numeración fiscal. * Un documento `RECHAZADO` por SIFEN libera su reserva. Un documento aprobado que después se cancela continúa como consumo confirmado. * El cupo se reinicia cada mes y no es acumulable. Las emisiones en DEV y SANDBOX nunca consumen ni reservan cupo. El plan se consulta, se cambia y se paga desde **Planes y facturación**; ver la [guía del panel](/docs/panel/planes-y-facturacion). ## Notas importantes [#notas-importantes] * Por contribuyente (RUC): el precio y el cupo son por cada RUC gestionado, no por cuenta. Una cuenta puede administrar varios contribuyentes; cada uno se factura según su plan. * Soporte: todos los planes tienen el canal de WhatsApp y email. Lo que suma cada plan está en [Qué incluye cada nivel](#qué-incluye-cada-nivel). * Sin contratos largos en planes mensuales: podés cambiar de plan desde el panel cuando quieras (excepto los planes a convenir, que se rigen por su contrato). Desde el plan gratuito o desde packs a un plan mensual, la activación es inmediata y empieza un ciclo nuevo. Entre planes mensuales pagos, tanto subir como bajar de plan se aplica en la próxima renovación. El período de acceso a documentos cambia cuando se activa el plan nuevo y puede volver a habilitar documentos archivados que todavía se conservan. * Acceso y conservación: el período de acceso de cada plan y de cada pack está en sus tablas; los planes a convenir usan el período acordado. Los documentos se conservan físicamente durante al menos 5 años desde su emisión, como fijan los [términos y condiciones](/terminos-y-condiciones), o más si el período del plan es superior. Al terminar el acceso, el documento queda archivado: sigue visible en los listados, pero su contenido y sus acciones no están disponibles. * Pago: cada cobro vence 5 días después de emitido. Un cobro vencido sin pagar suspende la emisión en producción hasta que confirmemos el pago; ver [Cómo se paga](/docs/panel/planes-y-facturacion#cómo-se-paga). * Pruebas sin límites: todos los planes tienen acceso al ambiente de pruebas para integrar y validar antes de pasar a producción, sin consumir cupo. Precios en Guaraníes (PYG), IVA incluido. ## ¿Qué nivel elegir? [#qué-nivel-elegir] Elegí por dos cosas: cuánto vas a emitir por mes y si necesitás integrar por API. | Si... | Nivel recomendado | | --- | --- | | todavía estás integrando y no emitís en producción | FREE | | emitís hasta 50 documentos al mes | PLUS | | emitís hasta 250 documentos al mes o necesitás nota de remisión, autofactura, API REST, personalización del KuDE, onboarding asistido | PRO | | emitís hasta 1.000 documentos al mes o necesitás soporte prioritario | MAX | | emitís de a ratos, sin volumen fijo todos los meses | un pack | | necesitás más volumen que MAX o condiciones negociadas | A medida | Si te equivocás de plan no pasa nada: cambiás cuando quieras desde el panel. ¿Listo para empezar? Mirá [Cómo funciona](/docs/plataforma/como-funciona) o saltá directo al [Inicio Rápido](/docs/inicio-rapido). # Autenticación (/docs/referencia/autenticacion) Enviá la API key completa mediante el header: ```http Authorization: Bearer {tu-api-key} ``` La clave identifica al contribuyente y determina el ambiente. Las claves nuevas usan estos prefijos: `sk_sandbox_` para Sandbox de Sifende, `sk_test_` para pruebas con SIFEN y `sk_live_` para producción. Todas usan `https://api.sifende.com.py`. El ambiente de una clave no cambia después de crearla. Las claves antiguas pueden tener un prefijo que no coincida con su ambiente. Verificá el ambiente en el panel; no lo deduzcas del prefijo. ## Crear y cambiar una clave [#crear-y-cambiar-una-clave] Entrá a **API Keys → Crear API Key** en el panel, completá el nombre y elegí el ambiente. La clave completa se muestra una sola vez. Consultá [API keys](/docs/panel/api-keys) para ver los requisitos de producción, la expiración y la eliminación. **Rotar** invalida la clave anterior al instante. Para cambiarla sin corte, creá otra, configurala en tu integración y eliminá la anterior cuando hayas verificado el cambio. ## Ejemplo [#ejemplo] ```bash curl "https://api.sifende.com.py/api/v1/documento-electronico/status/$CDC" \ -H "Authorization: Bearer $SIFENDE_API_KEY" ``` ## Errores de autenticación [#errores-de-autenticación] | Status | Qué revisar | | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `401 Unauthorized` | Clave ausente, inválida, expirada o revocada. Revisá el valor completo y el prefijo `Bearer` | | `403 Forbidden` | Permisos para el recurso u operación solicitada; revisá el detalle de la respuesta. Una clave de producción recibe [`plan-operation-not-allowed`](/docs/solucion-problemas/plan-operation-not-allowed) si el plan vigente no incluye la API de integración | Una clave inválida o expirada recibe: ```json {"error": "Invalid or expired API key"} ``` Esta respuesta `401` usa el campo `error`. Los [Problem Details](/docs/referencia/errores) se identifican por su campo `type`. # Changelog (/docs/referencia/changelog) ## 2026-10-10 [#2026-10-10] ### Nuevo [#nuevo] * [`GET /api/v1/contribuyente`](/docs/referencia/contribuyente) devuelve los datos del contribuyente asociado a la API key: RUC, razón social, dirección, actividades económicas, timbrado del ambiente de la clave, establecimientos y logo, con un `estadoConfiguracion` que indica si la emisión va a pasar los controles de configuración. * [`GET /api/v1/contribuyente/plan-consumo`](/docs/referencia/contribuyente/plan-consumo) es la nueva ruta de la consulta de plan y consumo, con la misma respuesta. ### Deprecado [#deprecado] * `GET /api/v1/documento-electronico/plan-consumo` sigue respondiendo igual hasta el 2027-01-15, cuando se remueve. Sus respuestas incluyen los headers `Deprecation`, `Sunset` y `Link` con la ruta nueva. Cambiá la URL a `/api/v1/contribuyente/plan-consumo`; la autenticación y la respuesta no cambian. *** ## 2026-10-05 [#2026-10-05] ### Comportamiento [#comportamiento] * Una `Idempotency-Key` ya registrada devuelve la operación original aunque cambien el body o el CDC. Antes respondía `422 idempotency-key-reused`; ahora ese error sólo aparece si usás la clave para otro tipo de operación. Si reutilizás una clave por error, recibís la operación anterior en lugar de un error. * El replay y la recuperación de eventos pendientes funcionan aunque el documento esté archivado. * La clave sigue reservada después de los 7 días de replay, hasta que termina la [conservación del documento](/docs/plataforma/planes). *** ## 2026-10-03 [#2026-10-03] ### Nuevo [#nuevo-1] * [Autofactura Electrónica](/docs/referencia/modelos/autofactura) disponible para compras a personas locales no contribuyentes, en guaraníes y al contado, con consulta de estado y KuDE. * `GET /api/v1/geografia/departamentos/{departamentoId}/ciudades` lista las ciudades del departamento sin elegir un distrito. En AFE, el distrito es opcional en el domicilio del vendedor y en el lugar de la operación. * `GET /api/v1/public/enums` incluye `tipoConstancia`. *** ## 2026-10-02 [#2026-10-02] ### Nuevo [#nuevo-2] * Cada API key pertenece a un ambiente fijo. Las claves nuevas usan `sk_sandbox_` para Sandbox de Sifende, `sk_test_` para pruebas con SIFEN y `sk_live_` para producción, con la misma URL base. Las claves anteriores conservan su ambiente aunque su prefijo no coincida; verificalo en el panel. * Timbrado y CSC configurables para DEV y PROD desde el panel. SANDBOX proporciona sus valores de prueba; el certificado activo sirve para los tres ambientes. * [Sandbox de Sifende](/docs/conceptos/ambientes#sandbox-de-sifende) permite probar emisión y notificaciones sin enviar documentos a SIFEN; su KuDE indica que no tiene validez fiscal. * [Filtro de ambiente en los documentos del panel](/docs/panel/documentos): Desarrollo, Producción y Sandbox. * [Webhooks por ambiente](/docs/panel/webhooks), con hasta cinco endpoints activos por contribuyente y ambiente. Las notificaciones nuevas incluyen `ambiente` en la raíz y mantienen `version: "1"`. * Las respuestas de emisión y consulta de estado incluyen `ambiente`: `DEV`, `PROD` o `SANDBOX`. Este valor permanece asociado al documento. * [`sandbox-operation-not-supported`](/docs/solucion-problemas/sandbox-operation-not-supported): respuesta 422 al intentar cancelar, inutilizar o nominar en SANDBOX. * [Nota de Remisión Electrónica](/docs/referencia/modelos/nota-remision) disponible, con consulta de estado y KuDE. ### Documentación [#documentación] * Se documentan las facturas a crédito en PYG por `PLAZO` o `CUOTA`. * Se documenta la [personalización del correo](/docs/panel/personalizacion), con logo, nombre comercial, colores, datos de contacto y correo de prueba. ### Si ya usás webhooks [#si-ya-usás-webhooks] Los endpoints existentes quedan asignados al ambiente que tenía el contribuyente al aplicar este cambio. Revisá el ambiente que muestra cada endpoint en **Webhooks**. Para recibir eventos de otro ambiente, creá otro endpoint y guardá su secreto. Las entregas anteriores conservan su payload y destinatario originales: pueden no incluir `ambiente` y corresponder a otro ambiente, incluso en un reintento. La firma y los reintentos se mantienen. ## 2026-09-08 [#2026-09-08] ### Nuevo [#nuevo-3] * [`GET /api/v1/padron/{documento}`](/docs/referencia/padron) consulta un RUC o cédula y devuelve razón social, estado, tipo de contribuyente y domicilio fiscal con los códigos geográficos de SIFEN * Los nombres de campo y las enumeraciones son los del receptor del documento electrónico (`tipoContribuyente`, `tipoContribuyenteReceptor`, `tipoDocumento`, `numeroDocumento`, `digitoVerificador`, `nombreRazonSocial`), y `estadoRuc` trae el código SET del estado * Acepta el documento con o sin puntos y con o sin dígito verificador; una cédula que no es RUC responde con `tipoContribuyente: NO_CONTRIBUYENTE` y `tipoDocumento: CEDULA_PARAGUAYA` * `domicilio` y `email` pueden venir en `null` cuando el padrón no los tiene * Límite de 60 consultas por minuto por API key y 120 por contribuyente, con `429 rate-limit-exceeded` y `Retry-After`; la consulta es de sólo lectura y no consume el plan de consumo *** ## 2026-08-18 [#2026-08-18] ### Nuevo [#nuevo-4] * [`GET /api/v1/documento-electronico/plan-consumo`](/docs/referencia/contribuyente/plan-consumo) consulta el plan, el ciclo, el cupo, las reservas y el costo adicional estimado del contribuyente asociado a la API key * `Idempotency-Key` opcional en emisión, cancelación e inutilización, con namespace único por contribuyente y replay exacto durante 7 días * Retries dirigidos por el cliente con la misma clave ante conexión sin respuesta, `409 idempotency-in-progress` o `503 idempotency-upstream-unknown` ### Comportamiento [#comportamiento-1] * Una clave cuyo replay venció queda reservada permanentemente y devuelve `409 idempotency-key-expired`; no puede reutilizarse * En cancelación, SIFEN `4003` se acepta como éxito equivalente; el protocolo puede ser `null` * En inutilización, SIFEN `4066` deja el evento `INDETERMINADA` y devuelve el terminal `409 idempotency-outcome-unknown` *** ## 2026-08-13 [#2026-08-13] ### Nuevo [#nuevo-5] * Webhooks salientes por contribuyente para `documento.aprobado`, `documento.rechazado`, `documento.cancelado` y `lote.procesado` * Firma verificable, entregas con reintentos e historial de 90 días * Panel para administrar endpoints, rotar secretos y consultar intentos de entrega *** ## 2026-08-10 [#2026-08-10] ### Nuevo [#nuevo-6] * `GET /api/v1/public/enums` expone la categoría `tipoContribuyenteReceptor` (`PERSONA_FISICA` / `PERSONA_JURIDICA`), obligatoria para receptores contribuyentes. El endpoint pasa de 18 a 19 categorías *** ## 2026-04-15 [#2026-04-15] ### Nuevo [#nuevo-7] * Notas de Débito Electrónicas (NDE) mediante `POST /api/v1/documento-electronico` con `tipoDocumento: "NOTA_DE_DEBITO_ELECTRONICA"` * Soporte para receptor B2B en Facturas Electrónicas ### Corrección [#corrección] * Corrección del cálculo de IVA incluido en el precio de los ítems gravados *** ## 2026-03-01 [#2026-03-01] ### Nuevo [#nuevo-8] * Soporte para Notas de Crédito Electrónicas (NCE) *** # Convenciones (/docs/referencia/convenciones) Esta página documenta las convenciones de datos específicas de Paraguay que aplican a toda la API de Sifende. ## RUC (Registro Único de Contribuyente) [#ruc-registro-único-de-contribuyente] El RUC es el número de identificación tributaria paraguayo. **Formato:** número + guión + dígito verificador ``` 80012345-0 ``` **En la API,** el RUC se envía en dos campos separados: * `numeroDocumento` o `ruc` — solo la parte numérica: `"80012345"` * `dv` o `digitoVerificador` — el dígito verificador: `"1"` **Validación:** Sifende valida el RUC contra el registro de SIFEN. Un RUC inválido o inexistente retorna `404 ruc-not-found`. ## Moneda — Guaraníes (PYG) [#moneda--guaraníes-pyg] El guaraní paraguayo **no tiene decimales** — todos los montos en PYG son enteros. ```json // Correcto "precioUnitario": 150000 // Incorrecto — no uses decimales en PYG "precioUnitario": 150000.00 ``` **Para otras monedas** (USD, BRL, etc.), sí se permiten decimales según la cantidad de decimales de la moneda. **Campos monetarios afectados:** `precioUnitario`, `montoPago`, `montoDescuento`, `montoTotal` y todos los sub-totales cuando `monedaOperacion` es `PYG`. ## Moneda extranjera y tipos de cambio [#moneda-extranjera-y-tipos-de-cambio] Los tipos de cambio son valores decimales expresados como PYG por una unidad de moneda extranjera. Admiten hasta 5 enteros y 4 decimales, deben ser mayores que cero y menores que `99999.9999`. * `tipoCambio` en la factura: modalidad GLOBAL. * `items[].tipoCambio`: modalidad POR\_ITEM, obligatorio en todos los ítems. * `condicionPago.tipoCambio`: cotización de la moneda extranjera del pago, independiente de la modalidad de la operación. La cotización comprador o vendedor del BCP es una decisión contable. Sifende valida la estructura y el formato, no que el valor coincida con una cotización específica del BCP. Ver [Facturar en Moneda Extranjera](/docs/guias/moneda-extranjera). ## Fechas y Timestamps [#fechas-y-timestamps] | Uso | Formato | Ejemplo | | ------------ | --------------------- | --------------------- | | Fecha y hora | ISO 8601 sin timezone | `2026-04-15T10:30:00` | | Solo fecha | ISO 8601 date | `2026-04-15` | No incluyas información de zona horaria en los timestamps. La API espera fecha y hora local de Paraguay, sin zona horaria. ## CDC (Código de Control del Documento Electrónico) [#cdc-código-de-control-del-documento-electrónico] El CDC es un identificador numérico de **44 dígitos** que identifica unívocamente cada documento en SIFEN. **Estructura del CDC (44 dígitos, 11 campos):** | Pos. | Largo | Campo | Descripción | | ----- | ----- | --------------------- | ------------------------------------------------------------------------------------------------ | | 1–2 | 2 | Tipo de documento | Tipo de documento (01=FE, 04=AFE, 05=NCE, 06=NDE, 07=NRE) | | 3–10 | 8 | RUC emisor | Parte numérica del RUC | | 11 | 1 | DV emisor | Dígito verificador del RUC | | 12–14 | 3 | Establecimiento | Código del establecimiento (001–999) | | 15–17 | 3 | Punto de expedición | Código del punto de expedición (001–999) | | 18–24 | 7 | Número de documento | Correlativo (0000001–9999999) | | 25 | 1 | Tipo de contribuyente | Tipo de contribuyente emisor (1=persona física, 2=jurídica) | | 26–33 | 8 | Fecha emisión | `AAAAMMDD` | | 34 | 1 | Tipo de emisión | Tipo de emisión: siempre `1` (normal). El `2` (contingencia) todavía no está habilitado en SIFEN | | 35–43 | 9 | Código de seguridad | Aleatorio generado al firmar | | 44 | 1 | DV CDC | Dígito verificador del CDC completo | **Ejemplo:** ``` 01800123451001001000000122026042710000000006 ``` El CDC es generado por Sifende y retornado como respuesta al emitir un documento. **Guardalo en tu sistema** — es el identificador principal para todas las operaciones posteriores. ## Numeración de Documentos [#numeración-de-documentos] El número de documento se forma con tres componentes: ``` {establecimiento}-{puntoExpedicion}-{número} 001-001-0000001 ``` * **Establecimiento:** 3 dígitos, identifica la sucursal * **Punto de expedición:** 3 dígitos, identifica el punto de venta dentro del establecimiento * **Número:** 7 dígitos, auto-incremental por establecimiento/punto Sifende asigna los números automáticamente según tu timbrado. ## Enumeraciones SIFEN [#enumeraciones-sifen] Los campos de tipo enumeración usan valores de cadena descriptivos en la API (no los códigos numéricos internos de SIFEN): ```json // En la API de Sifende "tipoDocumento": "FACTURA_ELECTRONICA" // Código numérico de SIFEN (no usar en la API) // tipo de documento = 1 ``` Para ver todos los valores disponibles, consultá [Enumeraciones](/docs/referencia/enumeraciones) o llamá a `GET /api/v1/public/enums`. ## Especificación OpenAPI [#especificación-openapi] La especificación OpenAPI 3.1 está disponible en `https://sifende.com.py/openapi/v1.json`. Consultá [OpenAPI y JSON Schema](/docs/referencia/openapi) para generar clientes y validar solicitudes. # Enumeraciones (/docs/referencia/enumeraciones) Esta página reúne las enumeraciones más usadas. La aceptación de cada valor depende de las reglas del documento y de la operación. También podés obtener estos valores en tiempo real llamando a `GET /api/v1/public/enums`. Cada página de modelo (ej: [Factura Electrónica](/docs/referencia/modelos/factura-electronica)) incluye inline los valores válidos para cada campo de ese modelo. Para consultar el catálogo completo, usá el endpoint público de enumeraciones. ## tipoDocumento [#tipodocumento] | Valor | Código SIFEN | Descripción | Estado | | ------------------------------ | ------------ | ---------------------------- | ------------ | | `FACTURA_ELECTRONICA` | 1 | Factura electrónica | ✅ Disponible | | `NOTA_DE_CREDITO_ELECTRONICA` | 5 | Nota de crédito electrónica | ✅ Disponible | | `NOTA_DE_DEBITO_ELECTRONICA` | 6 | Nota de débito electrónica | ✅ Disponible | | `AUTOFACTURA_ELECTRONICA` | 4 | Autofactura electrónica | ✅ Disponible | | `NOTA_DE_REMISION_ELECTRONICA` | 7 | Nota de remisión electrónica | ✅ Disponible | ## tipoEmision [#tipoemision] | Valor | Descripción | | -------- | --------------------------------- | | `NORMAL` | Emisión normal en línea con SIFEN | SIFEN todavía no habilita la emisión en contingencia: cualquier otro valor recibe `400` en `errores.tipoEmision`. ## tipoTransaccion [#tipotransaccion] | Valor | Descripción | | ---------------------- | ------------------------------- | | `VENTA_MERCADERIA` | Venta de mercadería | | `PRESTACION_SERVICIOS` | Prestación de servicios | | `MIXTO` | Venta de mercadería y servicios | | `VENTA_ACTIVO_FIJO` | Venta de activo fijo | | `VENTA_DIVISAS` | Venta de divisas | | `COMPRA_DIVISAS` | Compra de divisas | | `PROMOCION_O_MUESTRAS` | Promoción o entrega de muestras | | `DONACION` | Donación | | `ANTICIPO` | Anticipo | | `COMPRA_PRODUCTOS` | Compra de productos | | `COMPRA_SERVICIOS` | Compra de servicios | | `VENTA_CREDITO_FISCAL` | Venta de crédito fiscal | | `MUESTRAS_MEDICAS` | Muestras médicas | ## afectacionTributaria (ítems) [#afectaciontributaria-ítems] | Valor | Descripción | IVA | | ----------------- | ----------------------------------------------------------- | ------- | | `GRAVADO` | Gravado con IVA — indicar la tasa en `tasaIVA` (`5` o `10`) | Sí | | `EXENTO` | Exento de IVA | No | | `EXONERADO` | Exonerado por ley específica | No | | `GRAVADO_PARCIAL` | Solo una porción del ítem está gravada | Parcial | ## condicionOperacion [#condicionoperacion] | Valor | Descripción | | --------- | --------------- | | `CONTADO` | Pago al contado | | `CREDITO` | Pago a crédito | ## tipoPago [#tipopago] | Valor | Descripción | | ----------------------- | ---------------------------------------------------------------------- | | `EFECTIVO` | Efectivo | | `CHEQUE` | Cheque | | `TARJETA_DE_CREDITO` | Tarjeta de crédito | | `TARJETA_DE_DEBITO` | Tarjeta de débito | | `TRANSFERENCIA` | Transferencia bancaria | | `GIRO` | Giro | | `BILLETERA_ELECTRONICA` | Billetera electrónica (Tigo Money, Personal Pay, etc.) | | `TARJETA_EMPRESARIAL` | Tarjeta empresarial | | `VALE` | Vale | | `RETENCION` | Retención | | `PAGO_POR_ANTICIPO` | Pago por anticipo | | `VALOR_FISCAL` | Valor fiscal | | `VALOR_COMERCIAL` | Valor comercial | | `COMPENSACION` | Compensación | | `PERMUTA` | Permuta | | `PAGO_BANCARIO` | Pago bancario; sólo con `indicadorPresencia: "OPERACION_BANCARIA"` | | `PAGO_MOVIL` | Pago móvil | | `DONACION` | Donación | | `PROMOCION` | Promoción | | `CONSUMO_INTERNO` | Consumo interno | | `PAGO_ELECTRONICO` | Pago electrónico | | `OTRO` | Otro medio de pago; en `pagos[]` se describe con `descripcionTipoPago` | ## Pago con tarjeta [#pago-con-tarjeta] `tipoTarjeta` y `formaProcesamientoPago` sólo aplican cuando `tipoPago` es `TARJETA_DE_CREDITO` o `TARJETA_DE_DEBITO`, tanto al contado como en una entrega inicial a crédito. En `pagos[].tarjeta` ambos son obligatorios; en `condicionPago`, si omitís uno, se asume `OTRO` para ese campo. Ambos catálogos se publican en `/api/v1/public/enums`. ### tipoTarjeta [#tipotarjeta] | Valor | Descripción | | ------------------ | ---------------- | | `VISA` | Visa | | `MASTERCARD` | Mastercard | | `AMERICAN_EXPRESS` | American Express | | `MAESTRO` | Maestro | | `PANAL` | Panal | | `CABAL` | Cabal | | `OTRO` | Otro | ### formaProcesamientoPago [#formaprocesamientopago] | Valor | Descripción | | ------------------ | ---------------- | | `POS` | POS | | `PAGO_ELECTRONICO` | Pago Electrónico | | `OTRO` | Otro | ## indicadorPresencia (FE) [#indicadorpresencia-fe] | Valor | Descripción | | ------------------------- | ---------------------------------- | | `OPERACION_PRESENCIAL` | Operación presencial (por defecto) | | `OPERACION_ELECTRONICA` | Operación electrónica | | `OPERACION_TELEMARKETING` | Operación telemarketing | | `VENTA_A_DOMICILIO` | Venta a domicilio | | `OPERACION_BANCARIA` | Operación bancaria | | `OPERACION_CICLICA` | Operación cíclica | | `OTRO` | Otro, con `descripcionPresencia` | ## tipoImpuesto (FE) [#tipoimpuesto-fe] | Valor | Descripción | | ----------- | ----------------- | | `IVA` | IVA (por defecto) | | `RENTA` | Renta | | `NINGUNO` | Ninguno | | `IVA_RENTA` | IVA - Renta | ISC no se admite. ## condicionAnticipo (FE) [#condicionanticipo-fe] | Valor | Descripción | | ------------------- | ---------------------------------------- | | `ANTICIPO_GLOBAL` | Un porcentaje aplicado a todos los ítems | | `ANTICIPO_POR_ITEM` | Un importe por unidad en cada ítem | ## monedaOperacion [#monedaoperacion] | Valor | Descripción | | ----- | --------------------------------- | | `PYG` | Guaraní paraguayo (sin decimales) | | `USD` | Dólar estadounidense | | `BRL` | Real brasileño | | `ARS` | Peso argentino | | `EUR` | Euro | ## tipoOperacion (receptor) [#tipooperacion-receptor] | Valor | Descripción | | ----- | ----------------------------------------------------------------------------- | | `B2B` | Venta a contribuyente (requiere RUC del receptor) | | `B2C` | Venta a consumidor final | | `B2G` | Venta a organismo público | | `B2F` | Cliente del exterior; en FE sólo con `tipoTransaccion = PRESTACION_SERVICIOS` | ## receptor.tipoContribuyente [#receptortipocontribuyente] | Valor | Descripción | | ------------------ | ---------------------------------------------------------------------------------- | | `CONTRIBUYENTE` | Receptor con RUC activo en SET (B2B / B2G) | | `NO_CONTRIBUYENTE` | Receptor sin RUC — persona física, cliente del exterior (B2F) o consumo innominado | Un cliente del exterior es `NO_CONTRIBUYENTE` con `tipoDocumento = PASAPORTE` (u otro) y `pais` en código ISO. El valor `INNOMINADO` corresponde a `receptor.tipoDocumento`, no a `tipoContribuyente` — ver la tabla siguiente. ## tipoContribuyenteReceptor [#tipocontribuyentereceptor] | Valor | Código SIFEN | Descripción | | ------------------ | ------------ | -------------------------------------------------- | | `PERSONA_FISICA` | 1 | Unipersonal o profesional con RUC propio | | `PERSONA_JURIDICA` | 2 | S.A., S.R.L., EIRL, cooperativa, organismo público | Es **obligatorio cuando `receptor.tipoContribuyente = CONTRIBUYENTE`** y no se envía en ningún otro caso. No confundir con `tipoContribuyente` (`naturalezaReceptor`), que va siempre — ver [Receptor B2B y B2C](/docs/guias/receptor-b2b-b2c). ## receptor.tipoDocumento [#receptortipodocumento] | Valor | Descripción | | ---------------------- | ---------------------------------------- | | `CEDULA_PARAGUAYA` | Cédula de identidad paraguaya | | `PASAPORTE` | Pasaporte (nacionales y extranjeros) | | `CEDULA_EXTRANJERA` | Cédula de identidad extranjera | | `CARNET_DE_RESIDENCIA` | Carnet de residencia (inmigrantes) | | `INNOMINADO` | Sin identificación (solo FE bajo umbral) | | `TARJETA_DIPLOMATICA` | Tarjeta diplomática | | `OTRO` | Otro tipo de documento | ## unidadMedida [#unidadmedida] Consultá la categoría `unidadMedida` de [`GET /api/v1/public/enums`](/docs/referencia/catalogos/enumeraciones) para obtener los valores y sus abreviaturas. # Errores de la API (/docs/referencia/errores) Los errores de operación usan **Problem Details**: `type` identifica el problema, `status` indica el código HTTP y `detail` explica el caso. Usá `type` para decidir qué hacer; `title` y `detail` son mensajes para personas. ## Formato de respuesta [#formato-de-respuesta] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/validation-error", "title": "Error de validación", "status": 400, "detail": "La solicitud contiene 2 error(es) de validación", "errores": { "receptor.tipoContribuyenteReceptor": "Tipo de contribuyente receptor es obligatorio para un contribuyente", "receptor.digitoVerificador": "Dígito verificador es obligatorio y debe contener un dígito" }, "traceId": "8f1c2b3a4d5e6f70" } ``` | Campo | Uso | | ---------- | ------------------------------------------------------------------------------- | | `type` | URL que identifica el problema | | `title` | Resumen del problema | | `status` | Código HTTP | | `detail` | Explicación de este caso | | `instance` | Referencia a la solicitud, cuando aparece | | `traceId` | Identificador para soporte, cuando aparece; también puede estar en `X-Trace-Id` | Las extensiones dependen del error. Por ejemplo, la validación puede incluir `errores`; una enumeración inválida incluye `campo`, `valorRecibido` y `valoresAceptados`. No supongas que todas las respuestas tienen los mismos campos adicionales. ## Autenticación y permisos [#autenticación-y-permisos] Una API key inválida o vencida devuelve `401` con un JSON como este: ```json { "error": "Invalid or expired API key" } ``` Los errores de autenticación y permisos `401`/`403` pueden no usar Problem Details. Revisá las [credenciales y el ambiente](/docs/referencia/autenticacion) antes de repetir la solicitud. En NRE, el KuDE requiere que el documento esté `APROBADO` o `APROBADO_OBSERVACION`. ## Tipos de error de Sifende [#tipos-de-error-de-sifende] | HTTP | `type` (último segmento) | Significado | | --------------- | ----------------------------------------------------------------------------------------------------------- | -------------------------------------------- | | 400 / 409 | [`evento-cancelacion-error`](/docs/solucion-problemas/evento-cancelacion-error) | No se pudo cancelar el documento | | 400 / 409 | [`evento-inutilizacion-error`](/docs/solucion-problemas/evento-inutilizacion-error) | No se pudo inutilizar el rango | | 400 / 409 / 503 | [`evento-nominacion-error`](/docs/solucion-problemas/evento-nominacion-error) | No se pudo completar la nominación | | 400 | [`invalid-enum-value`](/docs/solucion-problemas/invalid-enum-value) | Valor de enumeración inválido | | 400 | [`invalid-format`](/docs/solucion-problemas/invalid-format) | Formato de campo inválido | | 400 | [`validation-error`](/docs/solucion-problemas/validation-error) | Datos de la solicitud inválidos | | 403 | [`document-archived`](/docs/solucion-problemas/document-archived) | Documento archivado | | 403 | [`document-quota-exceeded`](/docs/solucion-problemas/document-quota-exceeded) | Cupo mensual de documentos agotado | | 403 | [`emission-suspended`](/docs/solucion-problemas/emission-suspended) | Emisión suspendida por falta de pago | | 403 | [`plan-operation-not-allowed`](/docs/solucion-problemas/plan-operation-not-allowed) | El plan no permite esta operación | | 404 | [`certificate-not-found`](/docs/solucion-problemas/certificate-not-found) | Certificado o CSC sin configurar | | 404 | [`contribuyente-not-found`](/docs/solucion-problemas/contribuyente-not-found) | Contribuyente no encontrado | | 404 | [`documento-electronico-not-found`](/docs/solucion-problemas/documento-electronico-not-found) | Documento electrónico no encontrado | | 404 | [`evento-not-found`](/docs/solucion-problemas/evento-not-found) | Evento no encontrado | | 404 | [`resource-not-found`](/docs/solucion-problemas/resource-not-found) | Ruta no encontrada | | 404 | [`ruc-not-found`](/docs/solucion-problemas/ruc-not-found) | Documento no encontrado en el padrón | | 405 | [`method-not-allowed`](/docs/solucion-problemas/method-not-allowed) | Método HTTP no permitido | | 409 | [`idempotency-in-progress`](/docs/solucion-problemas/idempotency-in-progress) | La operación sigue en proceso | | 409 | [`idempotency-key-expired`](/docs/solucion-problemas/idempotency-key-expired) | La respuesta de la clave expiró | | 409 | [`idempotency-outcome-unknown`](/docs/solucion-problemas/idempotency-outcome-unknown) | Resultado de la operación indeterminado | | 409 | [`subscription-stale`](/docs/solucion-problemas/subscription-stale) | La suscripción cambió | | 415 | [`unsupported-media-type`](/docs/solucion-problemas/unsupported-media-type) | Tipo de contenido no admitido | | 422 | [`configuracion-incompleta`](/docs/solucion-problemas/configuracion-incompleta) | Configuración del contribuyente incompleta | | 422 | [`documento-electronico-generation-error`](/docs/solucion-problemas/documento-electronico-generation-error) | El documento no cumple una regla fiscal | | 422 | [`idempotency-key-reused`](/docs/solucion-problemas/idempotency-key-reused) | Clave utilizada para otro tipo de operación | | 422 | [`public-procurement-data-invalid`](/docs/solucion-problemas/public-procurement-data-invalid) | Datos de contratación pública inválidos | | 422 | [`public-recipient-requires-b2g`](/docs/solucion-problemas/public-recipient-requires-b2g) | El receptor público requiere B2G | | 422 | [`sandbox-operation-not-supported`](/docs/solucion-problemas/sandbox-operation-not-supported) | El ambiente SANDBOX no admite esta operación | | 422 | [`timbrado-no-vigente`](/docs/solucion-problemas/timbrado-no-vigente) | Timbrado aún no vigente | | 429 | [`rate-limit-exceeded`](/docs/solucion-problemas/rate-limit-exceeded) | Límite de consultas alcanzado | | 500 | [`internal-error`](/docs/solucion-problemas/internal-error) | Error al procesar la solicitud | | 500 | [`kude-generation-error`](/docs/solucion-problemas/kude-generation-error) | No se pudo obtener el KuDE | | 501 | [`kude-not-supported`](/docs/solucion-problemas/kude-not-supported) | El tipo de documento no admite KuDE | | 502 | [`padron-no-disponible`](/docs/solucion-problemas/padron-no-disponible) | Padrón no disponible | | 503 | [`idempotency-upstream-unknown`](/docs/solucion-problemas/idempotency-upstream-unknown) | SIFEN no confirmó el resultado | | 503 | [`kude-unavailable`](/docs/solucion-problemas/kude-unavailable) | KuDE no disponible | ## Reintentos [#reintentos] * Ante datos inválidos, corregí la causa antes de volver a enviar. * Ante `idempotency-in-progress` o `idempotency-upstream-unknown`, esperá `Retry-After` y repetí la misma solicitud con la misma clave. * Ante `idempotency-outcome-unknown` o `idempotency-key-expired`, detené los envíos y verificá el resultado original. * Un `500` en un `POST` puede tener efectos. Revisá `resultadoIndeterminado` y `accion`; no generes otra clave para recuperar la misma operación. * Un rechazo de SIFEN se consulta como `estado: "RECHAZADO"` y `mensajeRechazo`. No equivale a un error HTTP de validación. Seguí la guía de [idempotencia](/docs/guias/idempotencia) y consultá los [rechazos de SIFEN](/docs/solucion-problemas/rechazos-sifen). ## Documento archivado [#documento-archivado] [`document-archived`](/docs/solucion-problemas/document-archived) indica que terminó el período de acceso del plan. Su `type` es `https://api.sifende.com.py/problems/document-archived`. No reemitas el documento para resolver el acceso. ## Obtener el KuDE [#obtener-el-kude] Una respuesta `202` indica que el PDF se está preparando: seguí `Location` y respetá `Retry-After`. Consultar no acelera la preparación. Un `500` o `503` al descargar no cambia el estado fiscal del documento ni exige emitirlo de nuevo. Ver [Descargar KuDE](/docs/referencia/documentos-electronicos/descargar-kude). # Referencia API (/docs/referencia) ## URL base [#url-base] ``` https://api.sifende.com.py ``` Todos los endpoints usan el prefijo `/api/v1/`. ## Spec OpenAPI [#spec-openapi] El contrato completo, generado desde el código de la API, está publicado en una URL estable: ``` https://sifende.com.py/openapi/v1.json ``` Sirve para validar solicitudes antes de mandarlas y para generar clientes. Ver [OpenAPI y JSON Schema](/docs/referencia/openapi). ## Autenticación [#autenticación] Todas las llamadas a la API de integración requieren: ``` Authorization: Bearer {tu-api-key} ``` Ver [Autenticación](/docs/referencia/autenticacion) para más detalles. ## Secciones [#secciones] ### API de integración (API key) [#api-de-integración-api-key] La API principal para integraciones ERP: * [Documentos Electrónicos](/docs/referencia/documentos-electronicos) — emitir, consultar, cancelar, inutilizar * [Consultar el Padrón](/docs/referencia/padron) — validar un RUC o cédula en el padrón de la SET * [Modelos de Datos](/docs/referencia/modelos) — schemas de FE, AFE, NCE, NDE, NRE y entidades compartidas * [Eventos SIFEN](/docs/referencia/eventos) — cancelación, inutilización y nominación ### Datos de referencia [#datos-de-referencia] * [Catálogo de enumeraciones](/docs/referencia/catalogos/enumeraciones) — valores aceptados por la API * [Geografía](/docs/referencia/catalogos/geografia) — códigos de departamentos, distritos y ciudades ### Panel [#panel] * [Guías del panel](/docs/panel) — configuración y acceso del equipo * [API keys](/docs/panel/api-keys) — crear, rotar y eliminar claves ### Referencia global [#referencia-global] * [Autenticación](/docs/referencia/autenticacion) * [Convenciones](/docs/referencia/convenciones) — RUC, guaraníes, fechas, CDC * [Errores](/docs/referencia/errores) — Problem Details, códigos SIFEN * [Enumeraciones](/docs/referencia/enumeraciones) — todos los valores SIFEN válidos * [OpenAPI y JSON Schema](/docs/referencia/openapi) — spec generado desde el código, validación local y generación de clientes * [Versionado](/docs/referencia/versionado) * [Changelog](/docs/referencia/changelog) # OpenAPI y JSON Schema (/docs/referencia/openapi) El contrato de la API está publicado como un documento OpenAPI 3.1. La disponibilidad de los tipos de documento se detalla abajo. ## URLs [#urls] | Recurso | URL | | -------------------------------------- | ------------------------------------------------------------- | | Explorador interactivo | [/docs/referencia/api](/docs/referencia/api/emitir-documento) | | Spec OpenAPI (URL estable, versionada) | `https://sifende.com.py/openapi/v1.json` | | JSON Schema de un modelo | `https://sifende.com.py/schemas/v1/{Modelo}.json` | Las tres son públicas: no hace falta API key para leerlas. El [Explorador de la API](/docs/referencia/api/emitir-documento) se genera desde este mismo spec: trae el schema completo de cada endpoint, ejemplos en cURL, JavaScript, Python y Java, y un playground para probar las llamadas con tu API key. Para fijar en tu build usá `https://sifende.com.py/openapi/v1.json`. El `v1` es la versión de la API — la misma del prefijo `/api/v1/` — y no cambia mientras no haya una v2. Ver [Versionado](/docs/referencia/versionado). ## Nombres de JSON Schema [#nombres-de-json-schema] Reemplazá `{Modelo}` por el nombre exacto, respetando mayúsculas y sufijos. Estos identificadores forman parte de las URLs públicas: | Modelo | Nombre para la URL | | -------------------------------------- | --------------------------------------------------------------------- | | Factura electrónica | `FacturaElectronicaRequest` | | Nota de crédito | `NotaCreditoElectronicaRequest` | | Nota de débito | `NotaDebitoElectronicaRequest` | | Nota de remisión | `NotaRemisionElectronicaRequest` | | Receptor de emisión | `ReceptorDTO` | | Ítem de FE/NCE/NDE | `ItemDTO` | | Ítem de NRE | `ItemRemisionDTO` | | Condición de pago | `CondicionPagoDTO` | | Cuota y plazo estructurado | `CuotaCreditoDTO`, `PlazoEstructuradoDTO` | | Compras públicas | `ComprasPublicasDTO` | | Documento asociado de FE/NCE/NDE | `DocumentoAsociadoDTO` | | Documento asociado de NRE | `DocumentoAsociadoRemisionDTO` | | Transporte y locales de NRE | `TransporteRemisionDTO`, `LocalRemisionDTO` | | Vehículo, transportista y carga de NRE | `VehiculoRemisionDTO`, `TransportistaRemisionDTO`, `CargaRemisionDTO` | | Nominación y su receptor | `EventoNominacionRequest`, `ReceptorNominadoRequest` | | Cancelación | `CancelacionRequest` | | Inutilización | `EventoInutilizacionRequest` | | Respuesta de emisión | `DocumentoElectronicoEmisionResponseDTO` | | Estado del documento | `DocumentoElectronicoStatusDTO` | | Respuesta de evento | `EventoSifenDTO` | Por ejemplo, el schema de una FE está en `https://sifende.com.py/schemas/v1/FacturaElectronicaRequest.json`. Cada schema incluye sus dependencias en `$defs`; no necesitás descargar el receptor o los ítems por separado para resolver esas referencias. Para obtener todos los nombres disponibles en la versión publicada: ```bash curl --fail --silent --show-error https://sifende.com.py/openapi/v1.json \ | jq -r '.components.schemas | keys[]' ``` Un nombre inexistente devuelve `404`. La presencia de un schema no habilita por sí sola una operación: verificá la disponibilidad en el modelo correspondiente. ## Validar una solicitud antes de mandarla [#validar-una-solicitud-antes-de-mandarla] El spec expresa requisitos condicionales como `if`/`then` de JSON Schema, así que un validador puede verificarlos localmente sin llamar a la API. La validación local no sustituye las reglas de negocio de la API, como la elegibilidad de una nominación o la correspondencia entre el RUC fusionado y el CDC. El caso más común es el receptor: ```json { "allOf": [ { "if": { "properties": { "tipoContribuyente": { "const": "CONTRIBUYENTE" } }, "required": ["tipoContribuyente"] }, "then": { "required": ["tipoContribuyenteReceptor", "digitoVerificador"] } }, { "if": { "properties": { "tipoContribuyente": { "const": "NO_CONTRIBUYENTE" } }, "required": ["tipoContribuyente"] }, "then": { "required": ["tipoDocumento"] } } ] } ``` La validación local permite detectar si mandás un receptor `CONTRIBUYENTE` sin `tipoContribuyenteReceptor` antes de llamar a la API. Ver [Modelo Receptor](/docs/referencia/modelos/receptor). ## Generar un cliente [#generar-un-cliente] ```bash npx @openapitools/openapi-generator-cli generate \ -i https://sifende.com.py/openapi/v1.json \ -g typescript-fetch \ -o ./sifende-client ``` El spec usa OpenAPI 3.1 (JSON Schema 2020-12). Un generador que sólo soporte 3.0 puede ignorar `if`/`then` y `const`: la estructura sale bien, pero las reglas condicionales se pierden y hay que validarlas aparte. ## Cómo está armado [#cómo-está-armado] * **`tipoDocumento` es el discriminador.** Se admiten `FACTURA_ELECTRONICA`, `AUTOFACTURA_ELECTRONICA`, `NOTA_DE_CREDITO_ELECTRONICA`, `NOTA_DE_DEBITO_ELECTRONICA` y `NOTA_DE_REMISION_ELECTRONICA`; no envíes otros tipos. * **Los valores de enumeración son los que la API deserializa** (`CONTRIBUYENTE`, no `"CONTRIBUYENTE - Contribuyente"`). El catálogo completo, con las descripciones, está en [`GET /api/v1/public/enums`](/docs/referencia/catalogos/enumeraciones). * **Cada operación incluye sus respuestas de error**, con el formato Problem Details y ejemplos. Ver [Errores](/docs/referencia/errores). * **El spec cubre la API de integración y los catálogos públicos.** Para configurar tu cuenta, seguí las [guías del panel](/docs/panel). ## Para agentes de IA [#para-agentes-de-ia] `https://sifende.com.py/llms-full.txt` sirve la documentación completa **con el spec incluido** en un solo archivo, pensado para cargarlo como contexto. Es el punto de partida recomendado si estás integrando con un agente: la prosa da el contexto y el spec da el contrato exacto, incluidos los campos condicionales. # Consultar el Padrón (/docs/referencia/padron) ## GET /api/v1/padron/:documento [#get-apiv1padrondocumento] Busca un RUC o una cédula en el padrón de la SET y devuelve lo que la SET tiene registrado: nombre o razón social, estado, tipo de contribuyente y domicilio fiscal. Sirve para dos cosas concretas: 1. **Validar el RUC antes de facturar.** Si el documento no está en el padrón, SIFEN va a rechazar la factura con el código 1306. Consultar acá te evita el rechazo. 2. **Precargar el receptor.** El domicilio viene con los códigos geográficos de SIFEN, así que podés completar el bloque `receptor` de un documento electrónico sin pedirle la dirección al cliente. Es de sólo lectura: no emite nada, no consume tu plan de consumo y no altera el dato, que sale tal cual del padrón de la SET. ### Autenticación [#autenticación] `Authorization: Bearer {api-key}` (requerido) ### Path parameters [#path-parameters] | Parámetro | Tipo | Descripción | | ----------- | -------- | ------------------------------------------------------------- | | `documento` | `string` | RUC o cédula, con o sin puntos y con o sin dígito verificador | Sifende normaliza el valor antes de consultar: saca los puntos, saca el dígito verificador si viene y se queda con entre 5 y 12 dígitos. Estas tres formas consultan el mismo contribuyente: ``` GET /api/v1/padron/80002201 GET /api/v1/padron/80002201-7 GET /api/v1/padron/80.002.201-7 ``` El campo `numeroDocumento` de la respuesta siempre vuelve normalizado, sin DV. ### Ejemplo [#ejemplo] ```bash curl https://api.sifende.com.py/api/v1/padron/80002201-7 \ -H "Authorization: Bearer $SIFENDE_API_KEY" ``` ```typescript const documento = '80002201-7'; const response = await fetch( `https://api.sifende.com.py/api/v1/padron/${encodeURIComponent(documento)}`, { headers: { Authorization: `Bearer ${process.env.SIFENDE_API_KEY}`, }, }, ); if (response.status === 404) { throw new Error('El documento no figura en el padrón de la SET'); } const { data } = await response.json(); console.log(data.nombreRazonSocial, data.estado, data.tipoContribuyenteReceptor); ``` ```python import os import requests documento = "80002201-7" response = requests.get( f"https://api.sifende.com.py/api/v1/padron/{documento}", headers={"Authorization": f"Bearer {os.environ['SIFENDE_API_KEY']}"}, ) if response.status_code == 404: raise ValueError("El documento no figura en el padrón de la SET") response.raise_for_status() data = response.json()["data"] print(data["nombreRazonSocial"], data["estado"], data["tipoContribuyenteReceptor"]) ``` ### Respuesta exitosa [#respuesta-exitosa] **Status:** `200 OK` La respuesta usa el envelope estándar `{ data, timestamp, errors }`. Los nombres de campo y las enumeraciones son los mismos del [receptor](/docs/referencia/modelos/receptor) de un documento electrónico. ```json { "data": { "numeroDocumento": "80002201", "tipoContribuyente": "CONTRIBUYENTE", "tipoDocumento": null, "tipoContribuyenteReceptor": "PERSONA_JURIDICA", "digitoVerificador": "7", "nombreRazonSocial": "BANCO ITAU PARAGUAY S.A", "nombreComercial": null, "email": "contacto@ejemplo.com.py", "estado": "ACTIVO", "estadoRuc": "ACT", "tipoSociedad": { "codigo": "SOCIEDAD_ANONIMA", "descripcion": "SOCIEDAD ANONIMA" }, "esPersonaJuridica": true, "esEntidadPublica": false, "exportador": false, "domicilio": { "departamento": { "codigo": 1, "nombre": "CAPITAL" }, "distrito": { "codigo": 1, "nombre": "ASUNCION (DISTRITO)" }, "localidad": { "codigo": 1, "nombre": "ASUNCION (DISTRITO)" }, "barrio": null, "direccion": "SANTA TERESA ENTRE HERMINIO MALDONADO Y AVENIDA AVIADORES DEL CHACO", "numeroPuerta": null, "referencias": null }, "consultadoEn": "2026-09-08T14:30:12Z" }, "timestamp": "2026-09-08T14:30:12Z", "errors": null } ``` ### Campos [#campos] | Campo | Tipo | Descripción | | --------------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------- | | `numeroDocumento` | `string` | RUC base o número de cédula, normalizado: sólo dígitos, sin DV | | `tipoContribuyente` | `enum` | `CONTRIBUYENTE` si el documento está inscripto como tal; `NO_CONTRIBUYENTE` si sólo figura como ciudadano | | `tipoDocumento` | `enum \| null` | `CEDULA_PARAGUAYA` para un no contribuyente; `null` para un contribuyente, que se identifica por RUC | | `tipoContribuyenteReceptor` | `enum \| null` | `PERSONA_FISICA` o `PERSONA_JURIDICA`. `null` para un no contribuyente | | `digitoVerificador` | `string \| null` | Dígito verificador del RUC. `null` para una cédula que no es RUC | | `nombreRazonSocial` | `string` | Razón social o nombre completo, tal cual figura en la SET | | `nombreComercial` | `string \| null` | Nombre de fantasía, si está declarado | | `email` | `string \| null` | Correo registrado ante la SET, si existe | | `estado` | `string \| null` | Estado del contribuyente tal como lo informa la SET, por ejemplo `ACTIVO` | | `estadoRuc` | `enum \| null` | Código SET del estado: `ACT`, `SUS`, `SAD`, `BLQ`, `CAN` o `CDE`. Es el mismo valor que usa el contribuyente en Sifende | | `tipoSociedad` | `object \| null` | Tipo societario: `codigo` y `descripcion` | | `esPersonaJuridica` | `boolean` | Atajo de `tipoContribuyenteReceptor = PERSONA_JURIDICA` | | `esEntidadPublica` | `boolean` | `true` para organismos y entidades del Estado | | `exportador` | `boolean` | `true` si está registrado como exportador | | `domicilio` | `object \| null` | Domicilio fiscal con los códigos geográficos de SIFEN, si el padrón lo tiene | | `consultadoEn` | `string (RFC 3339)` | Momento en que Sifende obtuvo el dato del padrón | #### Objeto `domicilio` [#objeto-domicilio] | Campo | Tipo | Descripción | | -------------- | ---------------- | ------------------------------------------------------------------------ | | `departamento` | `object \| null` | `codigo` y `nombre`, con el nombre oficial del catálogo de departamentos | | `distrito` | `object \| null` | `codigo` y `nombre` | | `localidad` | `object \| null` | `codigo` y `nombre` | | `barrio` | `string \| null` | Barrio declarado | | `direccion` | `string \| null` | Calle y referencia de la dirección fiscal | | `numeroPuerta` | `string \| null` | Número de puerta | | `referencias` | `string \| null` | Referencias adicionales del domicilio | Los `codigo` de `departamento`, `distrito` y `localidad` son los códigos oficiales de SIFEN, los mismos que se usan en las direcciones del documento electrónico. ## Del padrón al receptor [#del-padrón-al-receptor] Los campos de identidad se copian al bloque `receptor` con el mismo nombre y el mismo valor, sin traducción. Sólo el domicilio cambia de forma: | Campo del padrón | Campo del [receptor](/docs/referencia/modelos/receptor) | | ------------------------------- | ------------------------------------------------------- | | `tipoContribuyente` | `tipoContribuyente` | | `tipoContribuyenteReceptor` | `tipoContribuyenteReceptor` | | `tipoDocumento` | `tipoDocumento` (sólo para `NO_CONTRIBUYENTE`) | | `numeroDocumento` | `numeroDocumento` | | `digitoVerificador` | `digitoVerificador` | | `nombreRazonSocial` | `nombreRazonSocial` | | `email` | `email` | | `domicilio.direccion` | `direccion` | | `domicilio.departamento.nombre` | `departamento` | | `domicilio.distrito.codigo` | `codigoDistrito` | | `domicilio.localidad.nombre` | `ciudad` | ```json { "receptor": { "tipoContribuyente": "CONTRIBUYENTE", "tipoOperacion": "B2B", "tipoContribuyenteReceptor": "PERSONA_JURIDICA", "numeroDocumento": "80002201", "digitoVerificador": "7", "nombreRazonSocial": "BANCO ITAU PARAGUAY S.A", "direccion": "SANTA TERESA ENTRE HERMINIO MALDONADO Y AVENIDA AVIADORES DEL CHACO", "departamento": "CAPITAL", "codigoDistrito": 1, "ciudad": "ASUNCION (DISTRITO)", "email": "contacto@ejemplo.com.py" } } ``` El padrón es la fuente de la verdad para el nombre y el estado, no para lo que tu cliente quiere ver impreso. Si el cliente te pide otra razón social o su nombre de fantasía, mandá el valor que corresponda al negocio; SIFEN valida el RUC y el DV, no el texto exacto de `nombreRazonSocial`. ## Datos parciales [#datos-parciales] `domicilio` y `email` pueden venir en `null` cuando el padrón no tiene el dato o la consulta se resolvió con datos parciales. Si tu integración arma el receptor con el domicilio, verificá que no sea `null` antes de usarlo, o reintentá la consulta más tarde. ## Cédula que no es contribuyente [#cédula-que-no-es-contribuyente] Cuando el documento figura como ciudadano pero no como contribuyente, la respuesta trae la identidad y nada más, ya con los valores que espera un receptor B2C: ```json { "data": { "numeroDocumento": "1234567", "tipoContribuyente": "NO_CONTRIBUYENTE", "tipoDocumento": "CEDULA_PARAGUAYA", "tipoContribuyenteReceptor": null, "digitoVerificador": null, "nombreRazonSocial": "JUAN PEREZ GONZALEZ", "nombreComercial": null, "email": null, "estado": null, "estadoRuc": null, "tipoSociedad": null, "esPersonaJuridica": false, "esEntidadPublica": false, "exportador": false, "domicilio": null, "consultadoEn": "2026-09-08T14:31:47Z" }, "timestamp": "2026-09-08T14:31:47Z", "errors": null } ``` Ese caso se factura como **B2C identificado**: `tipoContribuyente: "NO_CONTRIBUYENTE"` con `tipoDocumento: "CEDULA_PARAGUAYA"`, tal cual vienen. Ver [Receptor B2B y B2C](/docs/guias/receptor-b2b-b2c). `tipoContribuyente: "NO_CONTRIBUYENTE"` no es un error: significa que la persona existe pero no está inscripta en el IVA. No le emitas una factura B2B, porque SIFEN la rechaza. ## Caché y límites [#caché-y-límites] `consultadoEn` indica cuándo se obtuvo el dato. El resultado puede reflejar una consulta anterior; no implica una actualización con cada llamada. | Límite | Valor | | ----------------- | ------------------------ | | Por API key | 60 consultas por minuto | | Por contribuyente | 120 consultas por minuto | Al superarlos, la API responde `429 rate-limit-exceeded` con el header `Retry-After` en segundos. Esperá ese tiempo antes de reintentar en lugar de reintentar en loop. ### Errores [#errores] | Status | Tipo | Descripción | | ------ | ---------------------- | ----------------------------------------------------------------------- | | `400` | `invalid-format` | El documento no queda entre 5 y 12 dígitos después de sacar puntos y DV | | `401` | — | API key ausente, inválida o revocada | | `404` | `ruc-not-found` | El documento no está en el padrón | | `429` | `rate-limit-exceeded` | Se superó el límite por minuto. Incluye `Retry-After` en segundos | | `502` | `padron-no-disponible` | El padrón no respondió. Reintentá en unos minutos | ```json { "type": "https://sifende.com.py/docs/solucion-problemas/ruc-not-found", "title": "RUC no encontrado", "status": 404, "detail": "El documento 80099999 no figura en el padrón de la SET", "instance": "/api/v1/padron/80099999" } ``` El `404` es final: un documento que no figura en el padrón responde `404` en todas las consultas, no `502`. ## Próximos pasos [#próximos-pasos] * [Receptor B2B y B2C](/docs/guias/receptor-b2b-b2c) para armar el bloque con los datos que trajiste del padrón. * [Modelo Receptor](/docs/referencia/modelos/receptor) para el schema completo de campos. * [Geografía](/docs/referencia/catalogos/geografia) si necesitás poblar selectores de departamento, distrito y ciudad a mano. * [Rechazos SIFEN](/docs/solucion-problemas/rechazos-sifen) para los códigos 1306 y 1309, los rechazos que esta consulta previene. # Versionado (/docs/referencia/versionado) ## Versión actual [#versión-actual] **v1** — todos los endpoints usan el prefijo `/api/v1/`. ## Política de breaking changes [#política-de-breaking-changes] Un cambio **no** es breaking si: * Se agregan nuevos campos opcionales a la solicitud o respuesta * Se agregan nuevos endpoints * Se agregan nuevos valores a enumeraciones existentes Un cambio **es** breaking si: * Se eliminan o renombran campos existentes * Se cambia el tipo de un campo * Se cambia el comportamiento observable de un endpoint * Se remueve un endpoint Los breaking changes se anuncian con al menos **30 días de anticipación** vía email y en el [Changelog](/docs/referencia/changelog). ## Deprecación [#deprecación] Cuando un endpoint se depreca: * Se documenta con una nota de deprecación en esta documentación * Se retorna el header `Sunset` con la fecha de remoción planeada * Se retorna el header `Deprecation` con la fecha en que fue deprecado ## Deprecaciones vigentes [#deprecaciones-vigentes] | Ruta deprecada | Reemplazo | Deprecada | Remoción | | ------------------------------------------------ | --------------------------------------------------------------------------------------- | ---------- | ---------- | | `GET /api/v1/documento-electronico/plan-consumo` | [`GET /api/v1/contribuyente/plan-consumo`](/docs/referencia/contribuyente/plan-consumo) | 2026-10-10 | 2027-01-15 | ## Versiones futuras [#versiones-futuras] Cuando se lance v2, los endpoints v1 seguirán funcionando durante el período de migración. La documentación de v1 permanecerá disponible con un banner de deprecación. # Certificado Digital (/docs/solucion-problemas/certificado-digital) ## Certificado expirado [#certificado-expirado] Los certificados digitales tienen una fecha de vencimiento. Cuando el certificado expira, todos los intentos de emitir documentos fallan. **Síntomas:** Error `422 documento-electronico-generation-error` con mensaje de certificado inválido. **Solución:** Solicitá un nuevo certificado a tu [prestador de servicios de certificación autorizado](https://acraiz.gov.py/html/Certif_1PrestaServ.html) y subilo en [**Contribuyente → Certificado digital**](/docs/panel/certificado-y-csc). ## Contraseña incorrecta [#contraseña-incorrecta] **Síntomas:** Error al subir el certificado indicando contraseña incorrecta. **Solución:** Verificá que la contraseña sea la que definiste cuando obtuviste el certificado con tu prestador de certificación — no es la contraseña de Marangatu ni la de tu cuenta en Sifende. ## Formato incorrecto [#formato-incorrecto] Sifende acepta certificados en formato PKCS12 (extensión `.p12` o `.pfx`). **Síntomas:** Error al subir indicando formato inválido. **Solución:** Pedile a tu [prestador de servicios de certificación autorizado](https://acraiz.gov.py/html/Certif_1PrestaServ.html) el certificado en formato PKCS12 (extensión `.p12` o `.pfx`). # Certificado o CSC sin configurar (/docs/solucion-problemas/certificate-not-found) **HTTP: 404.** No se encontró el certificado activo junto con el CSC del ambiente de la API key. ## Efecto de la solicitud [#efecto-de-la-solicitud] En emisión no se creó un documento ni se consumió numeración o cupo. En cancelación, inutilización o nominación puede haberse creado un evento pendiente antes de detectar la falta de configuración; este intento no se envió a SIFEN. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Revisá el certificado activo y el CSC del ambiente en [Contribuyente → Certificado digital](/docs/panel/certificado-y-csc). En emisión, reintentá después de corregirlo. Para eventos, consultá primero el existente y conservá la clave y solicitud originales. Si permanece pendiente o hay un conflicto, contactá a soporte. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`, que podés compartir con soporte. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/certificate-not-found", "title": "Not Found", "status": 404, "detail": "No se encontró un certificado activo para el contribuyente con ID: 42", "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Configuración del contribuyente incompleta (/docs/solucion-problemas/configuracion-incompleta) **HTTP: 422.** Falta un dato del emisor necesario para emitir: timbrado, dirección, actividad económica o configuración del certificado. ## Efecto de la solicitud [#efecto-de-la-solicitud] La emisión no se ejecutó: no creó un documento ni consumió numeración o cupo. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Completá el dato indicado por `campo` en **Contribuyente**. Usá las guías de [timbrado](/docs/panel/timbrado) y [certificado y CSC](/docs/panel/certificado-y-csc). Reintentá después de corregir la configuración, con la misma solicitud y clave si usaste `Idempotency-Key`. ## Campos adicionales [#campos-adicionales] `campo`, `configuracion` y `accion` identifican el dato y el paso para resolverlo. Puede incluir `traceId`. ## Respuesta de ejemplo (extracto) [#respuesta-de-ejemplo-extracto] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/configuracion-incompleta", "title": "Configuración del contribuyente incompleta", "status": 422, "campo": "contribuyente.timbrado", "configuracion": "TIMBRADO_VIGENTE", "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Contribuyente no encontrado (/docs/solucion-problemas/contribuyente-not-found) **HTTP: 404.** El contribuyente asociado a la operación no está disponible. ## Efecto de la solicitud [#efecto-de-la-solicitud] La operación no se ejecutó: no creó documentos ni eventos y no consumió numeración ni cupo. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Verificá el contribuyente al que pertenece la API key desde el panel. Si continúa disponible allí, contactá a soporte con el `traceId`; no repitas la emisión sin resolver la causa. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`, que podés compartir con soporte. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/contribuyente-not-found", "title": "Not Found", "status": 404, "detail": "Contribuyente no encontrado con ID: 42", "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Documento archivado (/docs/solucion-problemas/document-archived) **HTTP: 403.** Terminó el período de acceso al documento incluido en el plan actual. ## Efecto de la solicitud [#efecto-de-la-solicitud] La consulta no modifica documentos ni consume numeración o cupo de emisión. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] No repitas la consulta en un ciclo. Revisá la [retención de tu plan](/docs/plataforma/planes) y contactá a soporte para consultar las opciones de acceso. No reemitas el documento. ## Campos adicionales [#campos-adicionales] No tiene extensiones propias. El identificador de seguimiento se obtiene del header `X-Trace-Id`. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://api.sifende.com.py/problems/document-archived", "title": "Documento archivado", "status": 403, "detail": "El período de acceso incluido en el plan actual ha finalizado." } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Cupo mensual de documentos agotado (/docs/solucion-problemas/document-quota-exceeded) La API devuelve este problema cuando el plan vigente no permite documentos adicionales y la ocupación del período ya alcanzó los documentos incluidos. ```http HTTP/1.1 403 Forbidden Content-Type: application/problem+json ``` Identificá el error comparando el URI completo de `type`: ```text https://sifende.com.py/docs/solucion-problemas/document-quota-exceeded ``` No uses `title` ni `detail` como identificadores: son textos para personas. ## Respuesta de ejemplo [#respuesta-de-ejemplo] Este ejemplo corresponde a un plan sin documentos adicionales que ya ocupó su cupo. Las emisiones en DEV y SANDBOX no consumen cupo ni generan este bloqueo. ```json { "type": "https://sifende.com.py/docs/solucion-problemas/document-quota-exceeded", "title": "Cupo mensual de documentos agotado", "status": 403, "detail": "El plan A medida tiene ocupados los 20000 documentos incluidos del período actual.", "codigoPlan": "A_MEDIDA", "nombrePlan": "A medida", "documentosIncluidos": 20000, "consumoConfirmado": 19998, "reservasActivas": 2, "documentosDisponibles": 0, "inicioPeriodo": "2026-08-10T04:00:00Z", "finPeriodo": "2026-09-10T04:00:00Z", "accion": "Esperá a que se libere capacidad o cambiá a un plan que permita documentos adicionales antes de volver a emitir.", "traceId": "f2f0333f78bfb6a4184cb5a5374685a5" } ``` ## Campos [#campos] | Campo | Significado | | ----------------------- | ---------------------------------------------------------------------------------------------- | | `codigoPlan` | Código estable del plan vigente | | `nombrePlan` | Nombre del plan para mostrar a una persona | | `documentosIncluidos` | Cupo efectivo del período | | `consumoConfirmado` | Documentos definitivos del período | | `reservasActivas` | Documentos en proceso, con resultado pendiente o todavía reintentables que conservan capacidad | | `documentosDisponibles` | Siempre `0` para este problema | | `inicioPeriodo` | Inicio inclusivo del período, en formato RFC 3339 | | `finPeriodo` | Fin exclusivo del período, en formato RFC 3339 | | `accion` | Próximo paso recomendado para una persona | | `traceId` | Identificador para correlacionar el error con soporte | Las reservas activas **no son consumo confirmado ni documentos adicionales cobrados**. Solo mantienen un lugar mientras se conoce el resultado del documento. ## Efecto de la solicitud bloqueada [#efecto-de-la-solicitud-bloqueada] La emisión bloqueada no se ejecutó: no creó documento ni CDC, no consumió numeración fiscal ni cupo. Si enviaste una `Idempotency-Key`, el `403` tampoco queda guardado como resultado terminal de esa intención. Para revisar la alerta y las acciones del panel, consultá [Si se agota el cupo](/docs/panel/planes-y-facturacion#si-se-agota-el-cupo). ## Cómo recuperar capacidad [#cómo-recuperar-capacidad] No reintentes inmediatamente en un loop y no esperes un header `Retry-After`: este error no representa un límite de frecuencia. Si el plan tiene cupo de producción positivo, podés volver a enviar la misma intención cuando un documento reservado termine `RECHAZADO` y libere su lugar, comience un nuevo período con capacidad o pases a un plan que permita documentos adicionales. Los planes mensuales con documentos adicionales permiten seguir emitiendo al agotar el cupo, con las [tarifas de documentos adicionales](/docs/plataforma/planes). El plan gratuito no emite en producción: recibe [`plan-operation-not-allowed`](/docs/solucion-problemas/plan-operation-not-allowed). Con `Idempotency-Key`, conservá la misma clave y el mismo payload al reintentar la intención que fue bloqueada. Un replay exitoso ya existente conserva su respuesta original aunque el cupo actual esté lleno. Para implementar la decisión en tu cliente, consultá [Manejar Errores](/docs/guias/manejar-errores). Para entender el cálculo del cupo, consultá [Planes y Precios](/docs/plataforma/planes). # El documento no cumple una regla fiscal (/docs/solucion-problemas/documento-electronico-generation-error) **HTTP: 422.** Sifende no pudo generar el documento con los datos recibidos. ## Efecto de la solicitud [#efecto-de-la-solicitud] La emisión no se ejecutó: no creó un documento ni consumió numeración o cupo. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Revisá el `detail` y el [modelo del documento](/docs/referencia/modelos). Corregí los datos; si cumplen las reglas publicadas, contactá a soporte con el `traceId` antes de repetir. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`, que podés compartir con soporte. ## Respuesta de ejemplo (extracto) [#respuesta-de-ejemplo-extracto] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/documento-electronico-generation-error", "title": "Unprocessable Entity", "status": 422, "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Documento electrónico no encontrado (/docs/solucion-problemas/documento-electronico-not-found) **HTTP: 404.** El documento no está disponible para el contribuyente y ambiente de esta API key. ## Efecto de la solicitud [#efecto-de-la-solicitud] La consulta no modifica documentos ni consume numeración o cupo de emisión. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Verificá el CDC completo y la API key del ambiente con el que emitiste. Para una cancelación o nominación, esta respuesta no modifica el documento. No reemitas para resolver un error de consulta. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`, que podés compartir con soporte. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/documento-electronico-not-found", "title": "Not Found", "status": 404, "detail": "Documento electrónico no encontrado con CDC: 01800123451001001000000122026042710000000006", "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Emisión suspendida por falta de pago (/docs/solucion-problemas/emission-suspended) **HTTP: 403.** El contribuyente tiene un cobro de Sifende vencido y sin pagar, así que la emisión en producción está suspendida. Cada cobro de la suscripción vence 5 días después de emitido; te avisamos por email al emitirlo y la fecha figura en **Planes y facturación**. ## Efecto de la solicitud [#efecto-de-la-solicitud] La emisión no se ejecutó: no creó un documento ni consumió numeración o cupo. Las emisiones en pruebas, las consultas, las descargas y los eventos sobre documentos ya emitidos siguen disponibles. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Transferí el monto de los cobros vencidos con su referencia en el concepto y mandanos el comprobante, como se explica en [Cómo se paga](/docs/panel/planes-y-facturacion#cómo-se-paga). La emisión se reactiva cuando confirmamos el pago. No repitas la emisión en un ciclo; reintentá después, con la misma solicitud y clave si usaste `Idempotency-Key`. ## Campos adicionales [#campos-adicionales] No tiene extensiones propias. Puede incluir `traceId`. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/emission-suspended", "title": "Emisión suspendida por falta de pago", "status": 403, "detail": "La emisión en producción está suspendida por un cobro vencido; se reactiva cuando confirmamos el pago.", "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Errores Comunes (/docs/solucion-problemas/errores-comunes) ## Error 401 — Invalid or expired API key [#error-401--invalid-or-expired-api-key] **Causa:** El API key es incorrecto, fue revocado, o el header está mal formateado. **Solución:** * Verificá que el header sea exactamente: `Authorization: Bearer {tu-api-key}` * No uses `X-API-Key` ni otros formatos * Si el key fue rotado, actualizá al nuevo valor ## Error 400 — validation-error en montos PYG [#error-400--validation-error-en-montos-pyg] **Causa:** Enviaste montos con decimales para PYG. **Solución:** Los montos en guaraníes son enteros. Cambiá `10000.00` → `10000`. ## Error 422 — documento-electronico-generation-error [#error-422--documento-electronico-generation-error] **Causa:** El documento no cumple con las validaciones de SIFEN. **Solución:** Revisá el campo `detail` del error Problem Details para el mensaje específico. Corregí los datos que no cumplen el modelo; si el problema persiste, contactá a soporte con el `traceId`. ## Error 422 — configuracion-incompleta [#error-422--configuracion-incompleta] **Causa:** Falta el timbrado del ambiente u otro dato de configuración del contribuyente. **Solución:** Revisá `campo` y completá el dato en **Contribuyente**. Para el timbrado, elegí el ambiente de la API key en **Contribuyente → Timbrado**. ## Error 404 — certificate-not-found [#error-404--certificate-not-found] **Causa:** No se encontró un certificado activo junto con el CSC del ambiente. **Solución:** Revisá el certificado y el CSC desde **Contribuyente → Certificado digital**. ## Documento queda en PENDIENTE por más de 5 minutos [#documento-queda-en-pendiente-por-más-de-5-minutos] **Causa:** SIFEN puede demorar en procesar. **Solución:** Consultá el estado nuevamente. Si persiste por más de 15 minutos, contactá [soporte](/docs/solucion-problemas/soporte). # No se pudo cancelar el documento (/docs/solucion-problemas/evento-cancelacion-error) **HTTP: 400 / 409.** Con `400`, el estado del documento o el plazo impide cancelar. Con `409`, ya existe una cancelación pendiente, enviada, indeterminada o aprobada. ## Efecto de la solicitud [#efecto-de-la-solicitud] No se crea un nuevo documento fiscal ni se consume numeración o cupo de emisión. Puede existir un evento anterior sobre el mismo documento o rango. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Revisá el estado y el evento existente antes de reenviar. El plazo es de 48 horas desde la aprobación para FE y 168 horas para NCE, NDE y NRE. Conservá la clave original si la enviaste; no crees otra para evitar un conflicto. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`, que podés compartir con soporte. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/evento-cancelacion-error", "title": "Conflict", "status": 409, "detail": "Ya existe una cancelación pendiente, enviada, indeterminada o aprobada para este documento electrónico.", "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # No se pudo inutilizar el rango (/docs/solucion-problemas/evento-inutilizacion-error) **HTTP: 400 / 409.** Con `400`, los datos del rango, el tipo de documento o el timbrado no son válidos. Con `409`, existe otra inutilización activa para el mismo rango. ## Efecto de la solicitud [#efecto-de-la-solicitud] No se crea un nuevo documento fiscal ni se consume numeración o cupo de emisión. Puede existir un evento anterior sobre el mismo documento o rango. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Revisá el `detail`. `numeroFin` debe ser mayor que `numeroInicio` y la diferencia no puede superar 1.000. Ante un conflicto, consultá el evento existente y conservá su clave; no envíes el mismo rango como una intención nueva. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`, que podés compartir con soporte. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/evento-inutilizacion-error", "title": "Conflict", "status": 409, "detail": "Ya existe una inutilización pendiente, enviada, indeterminada o aprobada para el mismo rango.", "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # No se pudo completar la nominación (/docs/solucion-problemas/evento-nominacion-error) **HTTP: 400 / 409 / 503.** La operación `POST /api/v1/documento-electronico/{cdc}/nominar` no pudo completar la identificación del receptor. `400` indica datos o condiciones inválidos; `409`, un conflicto con otra nominación; `503`, que SIFEN no confirmó el resultado. ## Efecto de la solicitud [#efecto-de-la-solicitud] Puede existir un evento creado o enviado. La nominación no crea otro documento ni reemplaza su CDC, XML o KuDE; no consume numeración ni cupo de emisión. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Ante `400`, revisá el `detail` y el evento antes de corregir datos. Ante `409`, consultá la nominación existente. Ante `503`, esperá `Retry-After: 2` y repetí la misma solicitud conservando la clave original, si la enviaste. No supongas que el envío falló sin efectos. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`. El `503` incluye `Retry-After: 2`. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```http Retry-After: 2 ``` ```json { "type": "https://sifende.com.py/docs/solucion-problemas/evento-nominacion-error", "title": "Service Unavailable", "status": 503, "detail": "No se pudo confirmar el resultado de la nominación en SIFEN; reintentá después del intervalo indicado", "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. Consultá el [contrato de nominación](/docs/referencia/documentos-electronicos/nominar) y la [guía paso a paso](/docs/guias/nominar-factura). # Evento no encontrado (/docs/solucion-problemas/evento-not-found) **HTTP: 404.** No existe un evento accesible con ese identificador para esta API key. ## Efecto de la solicitud [#efecto-de-la-solicitud] La consulta no modifica documentos ni consume numeración o cupo de emisión. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Usá el `eventoSifenId` de [Listar eventos](/docs/referencia/eventos/listar) y la misma clave de contribuyente y ambiente. No envíes otro evento para corregir el identificador. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`, que podés compartir con soporte. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/evento-not-found", "title": "Not Found", "status": 404, "detail": "Evento no encontrado con ID: 1024", "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Preguntas Frecuentes (/docs/solucion-problemas/faq) ## ¿Qué es Sifende y cómo se diferencia de e-kuatia'i? [#qué-es-sifende-y-cómo-se-diferencia-de-e-kuatiai] Sifende es una plataforma API para integrar facturación electrónica en tu software, ERP o e-commerce. e-kuatia'i, en cambio, es la herramienta gratuita oficial de la DNIT pensada para emitir manualmente desde un navegador. Las diferencias principales: * API REST: Sifende ofrece una integración programática vía JSON; e-kuatia'i no. * Multi-establecimiento: Sifende permite establecimientos y puntos de expedición ilimitados; e-kuatia'i está limitada a 1 establecimiento. * Alto volumen: Sifende procesa miles de DEs por minuto con reintentos automáticos. * Integración con ERP o software propio: flujo automatizado en vez de carga manual. * Soporte dedicado: Sifende incluye soporte humano por WhatsApp y email en todos los planes, con el mismo tiempo de respuesta. ## ¿Qué tipos de documentos electrónicos puedo emitir? [#qué-tipos-de-documentos-electrónicos-puedo-emitir] Sifende soporta: * Factura Electrónica (FE): disponible * Nota de Crédito Electrónica (NCE): disponible * Nota de Débito Electrónica (NDE): disponible * Nota de Remisión Electrónica (NRE): disponible * Autofactura Electrónica (AFE): disponible Todos los documentos se firman digitalmente y son rastreables por su CDC. DEV y PROD los envían a SIFEN; SANDBOX permite probar sin enviarlos. ## ¿Necesito saber SOAP o XML para integrar Sifende? [#necesito-saber-soap-o-xml-para-integrar-sifende] No. Solo necesitás hacer un POST con JSON a la API REST. Sifende se encarga del resto: 1. Genera el XML según el Manual Técnico V150. 2. Firma con tu certificado P12. 3. Envía el documento a SIFEN. 4. Consulta los resultados. Tu equipo trabaja con JSON; Sifende absorbe toda la complejidad de SOAP, XSD y firma digital. ## ¿Cómo manejo mi certificado digital P12? [#cómo-manejo-mi-certificado-digital-p12] Lo subís una sola vez desde el panel web. Sifende lo almacena de forma segura (cifrado en reposo) y lo usa automáticamente para firmar cada documento. Cuando esté próximo a vencer, recibís una notificación. Si tu certificado tiene problemas, mirá [Certificado Digital](/docs/solucion-problemas/certificado-digital). ## ¿Qué pasa si el servidor de la DNIT está caído? [#qué-pasa-si-el-servidor-de-la-dnit-está-caído] Sifende reintenta automáticamente los errores transitorios. Si el documento termina en `ERROR`, detené el polling y seguí la [guía para reintentar el lote](/docs/panel/lotes) o contactá a soporte; no lo reemitas. Sifende mantiene un 99.9% de disponibilidad en su propia plataforma. Los problemas de la DNIT no detienen tu operación, solo demoran la confirmación del CDC. ## ¿Cuánto tiempo toma integrar Sifende? [#cuánto-tiempo-toma-integrar-sifende] Una integración básica se completa en horas, no en semanas. Solo necesitás hacer un POST HTTP con JSON. Para validar sin compromiso: * El plan gratuito permite pruebas sin límite. El cupo, el precio, los adicionales y el período de acceso a los documentos de cada plan y de cada pack están en [Planes y precios](/docs/plataforma/planes). * Todos los planes tienen acceso al ambiente de pruebas de SIFEN. Andá al [Inicio Rápido](/docs/inicio-rapido) para emitir tu primer documento. ## ¿Sifende tiene un ambiente de sandbox? [#sifende-tiene-un-ambiente-de-sandbox] Sí. Usá una clave `sk_sandbox_` para probar emisión, KuDE y notificaciones sin enviar documentos a SIFEN. Necesitás un certificado activo y los datos del emisor; Sifende proporciona el timbrado y el CSC de prueba. Los documentos no tienen validez fiscal y no admiten cancelación, inutilización ni nominación. Para probar respuestas y rechazos de SIFEN, usá DEV con una clave `sk_test_`. Para producción, creá una clave `sk_live_` cuando cumplas sus requisitos. El certificado es el mismo y la URL base no cambia. Consultá [Ambientes](/docs/conceptos/ambientes) e [Ir a Producción](/docs/guias/ir-a-produccion). ## ¿Puedo usar Sifende sin tener el timbrado listo? [#puedo-usar-sifende-sin-tener-el-timbrado-listo] Podés probar en SANDBOX: Sifende proporciona el timbrado y el CSC de prueba. Necesitás un certificado activo, dirección y actividad económica. Para enviar documentos a SIFEN en DEV o PROD, cargá el timbrado y el CSC de ese ambiente. ## ¿Los precios incluyen IVA? ¿Hay contratos? [#los-precios-incluyen-iva-hay-contratos] * Los precios incluyen IVA. Se facturan en guaraníes (PYG). * Sin contratos a largo plazo en planes mensuales: se cancelan cuando quieras. * El plan gratuito no vence ni pide tarjeta, pero no emite en producción: sirve para probar la integración sin límite. * Los packs de documentos se compran una vez y no generan suscripción. * Los planes a convenir se rigen por un contrato con condiciones negociadas. Detalle completo en [Planes y precios](/docs/plataforma/planes). ## ¿Qué reglas aplica Sifende? [#qué-reglas-aplica-sifende] Sifende genera y firma los documentos según el Manual Técnico de SIFEN. La API valida los datos de la solicitud y devuelve el resultado que informa SIFEN. ## ¿Hay un límite de consultas por minuto? [#hay-un-límite-de-consultas-por-minuto] La consulta al padrón admite 60 consultas por minuto por API key y 120 por contribuyente. Si recibís `429 rate-limit-exceeded`, esperá el intervalo de `Retry-After`. Ver [Padrón](/docs/referencia/padron). ## ¿Sifende tiene SDKs oficiales? [#sifende-tiene-sdks-oficiales] No hay SDKs oficiales. Usá la [especificación OpenAPI](/docs/referencia/openapi) para generar un cliente. ## ¿Puedo descargar la especificación OpenAPI? [#puedo-descargar-la-especificación-openapi] Sí. Descargá la especificación OpenAPI 3.1 desde `https://sifende.com.py/openapi/v1.json` o consultá [OpenAPI y JSON Schema](/docs/referencia/openapi). ## ¿Cómo facturo a una empresa extranjera? [#cómo-facturo-a-una-empresa-extranjera] Usá `tipoDocumento: "PASAPORTE"` (o `"CARNET_DE_RESIDENCIA"` para residentes, `"CEDULA_EXTRANJERA"` cuando aplique) para el receptor extranjero, junto con `monedaOperacion` en la moneda correspondiente y `pais` con el código ISO del país. Los valores aceptados para `tipoDocumento` son: `CEDULA_PARAGUAYA`, `PASAPORTE`, `CEDULA_EXTRANJERA`, `CARNET_DE_RESIDENCIA`, `INNOMINADO`, `TARJETA_DIPLOMATICA`, `OTRO`. Consultá [Enumeraciones](/docs/referencia/enumeraciones#receptortipodocumento) para la referencia completa. Ver [Moneda Extranjera](/docs/guias/moneda-extranjera). # La operación sigue en proceso (/docs/solucion-problemas/idempotency-in-progress) **HTTP: 409.** Ya hay una solicitud en curso con esa `Idempotency-Key`. ## Efecto de la solicitud [#efecto-de-la-solicitud] Este intento no inició otra operación. La solicitud anterior puede seguir generando su resultado y sus efectos. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Esperá `Retry-After: 2` y repetí el mismo método, URL y body con la misma clave. No generes otra clave para recuperar esta intención. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`. El header `Retry-After` vale `2`. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```http Retry-After: 2 ``` ```json { "type": "https://sifende.com.py/docs/solucion-problemas/idempotency-in-progress", "title": "Solicitud idempotente en proceso", "status": 409, "detail": "Ya existe una solicitud con esta clave en proceso; reintentá después del intervalo indicado" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # La respuesta de la clave expiró (/docs/solucion-problemas/idempotency-key-expired) **HTTP: 409.** Pasaron los 7 días durante los que se podía recuperar la respuesta original. La clave permanece reservada. ## Efecto de la solicitud [#efecto-de-la-solicitud] Este intento no ejecutó otra operación. La original pudo crear un documento o evento y consumir numeración o cupo. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Detené el reintento. Consultá el documento o evento original y, si no tenés sus datos, pedí ayuda a soporte. No reemplaces la clave para repetir una operación cuyo resultado no confirmaste. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`, que podés compartir con soporte. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/idempotency-key-expired", "title": "Clave de idempotencia expirada", "status": 409, "detail": "El resultado asociado a la clave de idempotencia expiró y ya no puede reproducirse; la clave no puede reutilizarse" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Clave utilizada para otro tipo de operación (/docs/solucion-problemas/idempotency-key-reused) **HTTP: 422.** La clave ya identifica otro tipo de operación: emisión, cancelación, inutilización o nominación. Cambiar el body o el CDC dentro del mismo tipo de operación no produce este error. ## Efecto de la solicitud [#efecto-de-la-solicitud] Esta llamada no ejecutó una segunda operación. La solicitud original pudo consumir numeración o cupo. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Si querías recuperar la operación original, repetila en su endpoint. Si es una operación nueva (por ejemplo, cancelar un documento que emitiste con esta clave), generá una clave nueva. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`, que podés compartir con soporte. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/idempotency-key-reused", "title": "Clave de idempotencia reutilizada", "status": 422, "detail": "La clave de idempotencia ya fue usada para otro tipo de operación" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Resultado de la operación indeterminado (/docs/solucion-problemas/idempotency-outcome-unknown) **HTTP: 409.** No se pudo establecer un resultado definitivo que permita repetir la operación de forma segura. En inutilización, puede ocurrir al recibir `4066`. ## Efecto de la solicitud [#efecto-de-la-solicitud] Este intento no crea una operación distinta. La anterior pudo tener efectos; no supongas que el documento o rango quedó sin utilizar. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Detené los envíos. Consultá el documento o evento y contactá a soporte. No reenvíes con la misma clave ni con otra. Este error no incluye `Retry-After`. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`, que podés compartir con soporte. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/idempotency-outcome-unknown", "title": "Resultado idempotente indeterminado", "status": 409, "detail": "El resultado de la operación es indeterminado; no vuelvas a enviar la operación" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # SIFEN no confirmó el resultado (/docs/solucion-problemas/idempotency-upstream-unknown) **HTTP: 503.** No se pudo confirmar el resultado del envío a SIFEN. ## Efecto de la solicitud [#efecto-de-la-solicitud] El envío pudo llegar a SIFEN. Esta respuesta no demuestra que la operación haya quedado sin efectos. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Esperá `Retry-After: 2` y repetí exactamente la misma solicitud con la misma `Idempotency-Key`. No cambies la clave ni el contenido. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`. El header `Retry-After` vale `2`. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```http Retry-After: 2 ``` ```json { "type": "https://sifende.com.py/docs/solucion-problemas/idempotency-upstream-unknown", "title": "Resultado SIFEN no confirmado", "status": 503, "detail": "No se pudo confirmar el resultado en SIFEN; reintentá con la misma Idempotency-Key después del intervalo indicado" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Solución de Problemas (/docs/solucion-problemas) ## ¿Dónde está el problema? [#dónde-está-el-problema] Usá este árbol para encontrar la sección correcta: * **Error HTTP 400/422 al emitir un documento** → [Errores Comunes](/docs/solucion-problemas/errores-comunes) * **Recién te habilitaste y tus primeros documentos salen RECHAZADO** → [Rechazos comunes de SIFEN](/docs/solucion-problemas/rechazos-comunes) * **Documento en estado RECHAZADO por SIFEN** → [Rechazos SIFEN](/docs/solucion-problemas/rechazos-sifen) * **Problema con el certificado digital** → [Certificado Digital](/docs/solucion-problemas/certificado-digital) * **Error de autenticación (401)** → [Autenticación](/docs/referencia/autenticacion) * **Pregunta general** → [FAQ](/docs/solucion-problemas/faq) * **Necesitás ayuda humana** → [Soporte](/docs/solucion-problemas/soporte) # Error al procesar la solicitud (/docs/solucion-problemas/internal-error) **HTTP: 500.** La API no pudo completar la solicitud con una respuesta normal. ## Efecto de la solicitud [#efecto-de-la-solicitud] En una consulta `GET`, `resultadoIndeterminado: false` indica que no se modificaron datos. En un `POST`, el resultado puede ser indeterminado: la operación pudo ejecutarse y consumir numeración o cupo. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] En una consulta, esperá y reintentá con intervalos crecientes. En un envío, consultá primero el documento o evento. Si usaste `Idempotency-Key`, conservá la misma clave y solicitud para recuperarlo; sin clave, confirmá el resultado antes de reenviar. Si no podés determinarlo, contactá a soporte. ## Campos adicionales [#campos-adicionales] `resultadoIndeterminado`, `accion` y, cuando está disponible, `traceId`. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/internal-error", "title": "Error interno del servidor", "status": 500, "detail": "Ocurrió un error inesperado y el resultado de la operación es indeterminado: puede haberse aplicado o no. No reintentes el envío sin antes consultar el estado, porque un reintento a ciegas puede duplicar el documento.", "resultadoIndeterminado": true, "accion": "Consultá el estado del recurso antes de reenviar. Si no podés determinarlo, contactá a soporte con el traceId.", "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Valor de enumeración inválido (/docs/solucion-problemas/invalid-enum-value) **HTTP: 400.** Un campo recibió un valor que no pertenece a su enumeración. ## Efecto de la solicitud [#efecto-de-la-solicitud] La operación no se ejecutó: no creó documentos ni eventos y no consumió numeración ni cupo. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Elegí un valor de `valoresAceptados` o consultá [Enumeraciones](/docs/referencia/catalogos/enumeraciones). Corregí la solicitud antes de enviarla de nuevo. ## Campos adicionales [#campos-adicionales] `campo`, `valorRecibido` y `valoresAceptados`. Los valores aceptados pueden ser objetos con `codigo` y `descripcion`, o textos. Puede incluir `traceId`. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/invalid-enum-value", "title": "Valor de enumeración inválido", "status": 400, "detail": "El campo 'receptor.tipoDocumento' recibió 'RUC', que no es un valor permitido. Valores aceptados: [CEDULA_PARAGUAYA, PASAPORTE, CEDULA_EXTRANJERA, CARNET_DE_RESIDENCIA, INNOMINADO, TARJETA_DIPLOMATICA, OTRO]", "campo": "receptor.tipoDocumento", "valorRecibido": "RUC", "valoresAceptados": [ { "codigo": "CEDULA_PARAGUAYA", "descripcion": "Cédula paraguaya" }, { "codigo": "PASAPORTE", "descripcion": "Pasaporte" }, { "codigo": "CEDULA_EXTRANJERA", "descripcion": "Cédula extranjera" }, { "codigo": "CARNET_DE_RESIDENCIA", "descripcion": "Carnet de residencia" }, { "codigo": "INNOMINADO", "descripcion": "Innominado" }, { "codigo": "TARJETA_DIPLOMATICA", "descripcion": "Tarjeta Diplomática de exoneración fiscal" }, { "codigo": "OTRO", "descripcion": "Otro" } ], "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Formato de campo inválido (/docs/solucion-problemas/invalid-format) **HTTP: 400.** El JSON, un parámetro o un campo tiene un formato o tipo incorrecto. ## Efecto de la solicitud [#efecto-de-la-solicitud] La operación no se ejecutó: no creó documentos ni eventos y no consumió numeración ni cupo. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Revisá el formato y los tipos del [modelo](/docs/referencia/modelos). Corregí el dato antes de volver a enviar. ## Campos adicionales [#campos-adicionales] Según la causa puede incluir `campo`, `valorRecibido` y `tipoEsperado`. Puede incluir `traceId`. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/invalid-format", "title": "Formato de campo inválido", "status": 400, "detail": "El campo 'items[0].cantidad' recibió un valor de tipo incorrecto: se esperaba un número decimal", "campo": "items[0].cantidad", "tipoEsperado": "número decimal", "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # No se pudo obtener el KuDE (/docs/solucion-problemas/kude-generation-error) **HTTP: 500.** Falló la obtención o preparación del PDF. ## Efecto de la solicitud [#efecto-de-la-solicitud] La consulta no modifica documentos ni consume numeración o cupo de emisión. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Conservá el CDC y contactá a soporte con el `traceId` si persiste. No vuelvas a emitir. Si una consulta posterior responde `202`, seguí `Location` y respetá `Retry-After`. ## Campos adicionales [#campos-adicionales] Puede incluir `estado: "FALLIDO"` y `traceId`. No incluye un plazo de reintento propio. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/kude-generation-error", "title": "Internal Server Error", "status": 500, "detail": "No se pudo obtener el KuDE por un error interno.", "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # El tipo de documento no admite KuDE (/docs/solucion-problemas/kude-not-supported) **HTTP: 501.** No se puede preparar el PDF para el tipo de documento solicitado. ## Efecto de la solicitud [#efecto-de-la-solicitud] La consulta no modifica documentos ni consume numeración o cupo de emisión. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Verificá el tipo del documento. FE, NCE, NDE y NRE admiten KuDE. Repetir la descarga para un tipo sin soporte no cambia el resultado; no reemitas el documento. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`, que podés compartir con soporte. ## Respuesta de ejemplo (extracto) [#respuesta-de-ejemplo-extracto] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/kude-not-supported", "title": "Not Implemented", "status": 501, "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # KuDE no disponible (/docs/solucion-problemas/kude-unavailable) **HTTP: 503.** No se pudo obtener el PDF en este intento. ## Efecto de la solicitud [#efecto-de-la-solicitud] La consulta no modifica documentos ni consume numeración o cupo de emisión. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Reintentá la descarga más tarde con el mismo CDC. Si responde `202`, seguí `Location` y respetá `Retry-After`. Si el problema persiste, contactá a soporte con el `traceId`; no reemitas el documento. ## Campos adicionales [#campos-adicionales] Puede incluir `estado: "FALLIDO"` y `traceId`. El error `503` no incluye un header `Retry-After` propio. ## Respuesta de ejemplo (extracto) [#respuesta-de-ejemplo-extracto] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/kude-unavailable", "title": "Service Unavailable", "status": 503, "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Método HTTP no permitido (/docs/solucion-problemas/method-not-allowed) **HTTP: 405.** La ruta existe, pero no acepta el método enviado. ## Efecto de la solicitud [#efecto-de-la-solicitud] La operación no se ejecutó ni consumió numeración o cupo. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Usá el método indicado para ese endpoint en la [referencia](/docs/referencia). Reintentá sólo con el método correcto. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`, que podés compartir con soporte. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/method-not-allowed", "title": "Método no permitido", "status": 405, "detail": "El método DELETE no está soportado en este endpoint. Métodos permitidos: [GET]", "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Padrón no disponible (/docs/solucion-problemas/padron-no-disponible) **HTTP: 502.** No se pudo completar la consulta al padrón. ## Efecto de la solicitud [#efecto-de-la-solicitud] La consulta no modifica documentos ni consume numeración o cupo de emisión. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Reintentá la consulta en unos minutos. Si persiste, contactá a soporte con el `traceId`. Esta respuesta no indica que el documento consultado sea inexistente. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`, que podés compartir con soporte. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/padron-no-disponible", "title": "Bad Gateway", "status": 502, "detail": "El padrón de contribuyentes no está disponible en este momento. Reintentá en unos minutos.", "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # El plan no permite esta operación (/docs/solucion-problemas/plan-operation-not-allowed) **HTTP: 403.** El plan vigente del contribuyente no incluye en producción la función que pide la solicitud: la API de integración o un tipo de documento. Una clave de producción recibe este error en todas las rutas de la API si el plan no incluye la API, también al consultar o descargar documentos anteriores. Las claves de pruebas funcionan con todos los planes. ## Efecto de la solicitud [#efecto-de-la-solicitud] La operación no se ejecutó: no creó documentos ni eventos y no consumió numeración o cupo. Los documentos emitidos antes siguen su procesamiento y conservan sus PDF. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Cambiá a uno de los planes de `planesIncluidos` desde **Planes y facturación**; ver [planes y precios](/docs/plataforma/planes). Desde el plan gratuito o desde Packs el plan nuevo se activa en el momento; entre planes mensuales, en la próxima renovación. La clave sigue vigente: reintentá cuando el plan nuevo esté activo, con la misma solicitud y clave si usaste `Idempotency-Key`. ## Campos adicionales [#campos-adicionales] `funcionalidad` identifica lo que falta (`API_INTEGRACION`, `EMITIR_FACTURA`, `EMITIR_NOTA_CREDITO`, `EMITIR_NOTA_DEBITO`, `EMITIR_REMISION` o `EMITIR_AUTOFACTURA`), `nombre` es su nombre para mostrar, `codigoPlan` el plan vigente, `ambiente` el de la operación y `planesIncluidos` los planes que la incluyen. Puede incluir `traceId`. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/plan-operation-not-allowed", "title": "Tu plan no incluye esta función", "status": 403, "detail": "API de integración no está incluida en el plan PLUS en producción.", "funcionalidad": "API_INTEGRACION", "nombre": "API de integración", "codigoPlan": "PLUS", "ambiente": "PROD", "planesIncluidos": ["PRO", "MAX", "A_MEDIDA"], "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Datos de contratación pública inválidos (/docs/solucion-problemas/public-procurement-data-invalid) **HTTP: 422.** La fecha del código de contratación (`comprasPublicas.fechaEmisionCodigo`) no es anterior a la fecha de emisión del documento. ## Efecto de la solicitud [#efecto-de-la-solicitud] La emisión no se ejecutó: no creó un documento ni consumió numeración o cupo. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Corregí `comprasPublicas.fechaEmisionCodigo` para que sea anterior a la fecha de emisión, según el [modelo de factura](/docs/referencia/modelos/factura-electronica#compras-públicas). Los datos DNCP se admiten en cualquier tipo de operación. ## Campos adicionales [#campos-adicionales] `errores` relaciona rutas de campos con mensajes. Puede incluir `traceId`. ## Respuesta de ejemplo (extracto de los campos con error) [#respuesta-de-ejemplo-extracto-de-los-campos-con-error] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/public-procurement-data-invalid", "title": "Datos de contratación pública inválidos", "status": 422, "detail": "Los datos de contratación pública contradicen la fecha de emisión", "errores": { "comprasPublicas.fechaEmisionCodigo": "Fecha de emisión del código debe ser anterior a la fecha efectiva del documento" }, "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # El receptor público requiere B2G (/docs/solucion-problemas/public-recipient-requires-b2g) **HTTP: 422.** El receptor fue identificado como un organismo o entidad del Estado. ## Efecto de la solicitud [#efecto-de-la-solicitud] La emisión no se ejecutó: no creó un documento ni consumió numeración o cupo. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Enviá `receptor.tipoOperacion: "B2G"` y verificá las [reglas del receptor B2G](/docs/referencia/modelos/receptor#reglas-clave). Si informás datos de contratación, seguí el [modelo de compras públicas](/docs/referencia/modelos/factura-electronica#compras-públicas). No repitas el mismo contenido sin corregirlo. ## Campos adicionales [#campos-adicionales] `errores` incluye `receptor.tipoOperacion`. Puede incluir `traceId`. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/public-recipient-requires-b2g", "title": "El receptor público requiere una operación B2G", "status": 422, "detail": "TuRUC confirmó que el receptor es un organismo o entidad del Estado", "errores": { "receptor.tipoOperacion": "Seleccione B2G para un receptor público" }, "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Límite de consultas alcanzado (/docs/solucion-problemas/rate-limit-exceeded) **HTTP: 429.** Se alcanzó el límite de consultas al padrón: 60 por minuto por API key o 120 por contribuyente. ## Efecto de la solicitud [#efecto-de-la-solicitud] La consulta no modifica documentos ni consume numeración o cupo de emisión. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Esperá los segundos indicados en `Retry-After` y repetí la consulta. Coordiná el límite entre las llamadas de tu integración; no cambies de clave para eludirlo. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`. El header `Retry-After` indica cuántos segundos esperar. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```http Retry-After: 30 ``` ```json { "type": "https://sifende.com.py/docs/solucion-problemas/rate-limit-exceeded", "title": "Too Many Requests", "status": 429, "detail": "Superaste el límite de consultas por minuto. Reintentá en 30 segundo(s).", "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Rechazos comunes de SIFEN (/docs/solucion-problemas/rechazos-comunes) Cuando recién empezás a emitir (habilitación o ambiente de prueba), casi todos los rechazos de SIFEN caen en el mismo patrón: **El principio que explica casi todos estos rechazos:** el documento electrónico tiene que coincidir **exactamente** con lo que **SET** tiene registrado para tu RUC — el timbrado, su fecha de inicio de vigencia, las actividades económicas, el CSC y el establecimiento / punto de expedición. Si un solo dato no coincide con el registro de SET, SIFEN rechaza el documento. Por eso estos rechazos **casi nunca son un bug de Sifende**: Sifende arma y firma el XML con los datos que vos cargaste, pero es SET quien valida esos datos contra su padrón. Si el rechazo dice "timbrado inválido", "establecimiento incorrecto" o "actividad económica incorrecta", el arreglo casi siempre está del lado de tu registro en Marangatu, no en el código. Esta página es la guía de diagnóstico para los rechazos más frecuentes en onboarding, con el detalle de **por qué** pasan y **cómo** resolverlos. Si buscás la tabla completa de códigos de SIFEN, andá a [Rechazos SIFEN](/docs/solucion-problemas/rechazos-sifen). Si el error es un `400`/`422` **antes** de llegar a SIFEN (formato de la solicitud), mirá [Errores comunes](/docs/solucion-problemas/errores-comunes). ## Cómo ves el mensaje de rechazo [#cómo-ves-el-mensaje-de-rechazo] Cuando SIFEN rechaza un documento, queda en estado `RECHAZADO` y el motivo aparece en el campo `mensajeRechazo` de [`GET /status/:cdc`](/docs/referencia/documentos-electronicos/consultar-estado): ```json { "estado": "RECHAZADO", "mensajeRechazo": "[1101] Número de timbrado inválido" } ``` El código entre corchetes es lo que te dice en qué sección de abajo mirar. ## El ambiente de prueba (TEST) [#ambiente-prueba] La mayoría de los rechazos de onboarding aparecen en el ambiente de prueba, así que conviene entender cómo se habilita. Para poder **emitir en TEST**, tu RUC tiene que estar habilitado como facturador electrónico en Marangatu. Presentá el **Formulario N° 364 (Solicitud de Habilitación como Facturador Electrónico)** en Marangatu y esperá a que quede en estado **"Aceptado"**. Al aceptarse, SET provisiona automáticamente tu dataset de prueba y te lo notifica en **Marangatu**. Cargá esos datos en Sifende (timbrado, establecimiento, punto de expedición, CSC) y recién ahí empezá a emitir en TEST. El dataset que SET provisiona en TEST tiene una convención fija: | Dato | Valor en TEST | | --------------------------- | -------------------------------------------------------------------------------------- | | Número de timbrado | Tu **RUC sin dígito verificador** (rellenado con ceros a la izquierda hasta 8 dígitos) | | Establecimiento | `001` | | Puntos de expedición | `001`, `002`, `003` | | Fecha de inicio de vigencia | La fecha en que el Formulario 364 quedó **"Aceptado"** | | CSC — IdCSC `1` | `ABCD0000...` (genérico, en la notificación de Marangatu) | | CSC — IdCSC `2` | `EFGH0000...` (genérico, en la notificación de Marangatu) | **Hay una demora de propagación (\~24–72 h)** entre que el Formulario 364 queda "Aceptado" en Marangatu y que el timbrado se vuelve válido en el servicio de recepción de SIFEN. Los documentos que envíes **antes** de que termine la propagación reciben `1101`, aunque todos los datos estén perfectos. Si acabás de habilitarte, esperá y reintentá. ## 1101 — Número de timbrado inválido [#rechazo-1101] **Síntoma.** DE en estado `RECHAZADO` con el mensaje "Número de timbrado inválido". **Causa.** SET valida que el timbrado enviado pertenezca a tu RUC **y** al tipo de documento que estás emitiendo. El `1101` aparece cuando esa verificación de propiedad falla, y eso pasa por una de dos razones: * El RUC **todavía no está habilitado** como facturador electrónico en ese ambiente, o * Recién te habilitaste y el timbrado **aún no propagó** al padrón del servicio de recepción de SIFEN (ver la demora de arriba). **Solución.** 1. Confirmá que el Formulario 364 esté en estado **"Aceptado"** en Marangatu. 2. Si recién se aceptó, **esperá \~24–72 h** y reenviá el **mismo** documento, sin cambiar nada. 3. Verificá que el número de timbrado cargado en Sifende sea tu **RUC sin dígito verificador** (en TEST) y que coincida con el que figura en Marangatu. 4. Si persiste pasadas las 72 h, contactá a **soporte de SET** citando el número de habilitación (Formulario 364). El `1101` se evalúa **antes** que el establecimiento, el punto de expedición y las fechas. Mientras esté presente el `1101`, cambiar el establecimiento, el punto o la fecha **no va a ayudar** — SIFEN ni siquiera llega a validar esos campos. Primero resolvé el `1101`. ## 1107 — Fecha de inicio de vigencia del timbrado incorrecta [#rechazo-1107] **Síntoma.** DE `RECHAZADO` con "Fecha de inicio de vigencia del timbrado incorrecta". **Causa.** La fecha de inicio de vigencia que enviás no es exactamente igual a la que SET registró para ese timbrado. **Solución.** Poné la fecha de inicio del timbrado (en Sifende: [Contribuyente → Timbrado](https://app.sifende.com.py/timbrado)) **exactamente** igual al valor que figura en Marangatu. En TEST, esa fecha es el **día en que el Formulario 364 quedó "Aceptado"**. ## 1103 — Timbrado no vigente a la fecha de emisión [#rechazo-1103] **Síntoma.** DE `RECHAZADO` con "Timbrado no vigente a la fecha de emisión". **Causa.** La fecha de emisión del documento es **anterior** a la fecha de inicio de vigencia del timbrado. El timbrado electrónico no tiene fecha de fin. **Solución.** Emití con una fecha igual o posterior al inicio de vigencia. Revisá que la fecha de inicio cargada en Sifende sea la registrada en la SET. ## 1105 / 1106 — Establecimiento o punto de expedición no autorizado [#rechazo-1105-1106] **Síntoma.** DE `RECHAZADO` con "Código de establecimiento incorrecto" (`1105`) o "Punto de expedición incorrecto" (`1106`). **Causa.** El establecimiento o el punto de expedición que enviaste no está entre los registrados para ese timbrado. En **TEST solo se provisiona el establecimiento `001`** con los puntos **`001`, `002` y `003`**. **Solución.** Usá un establecimiento y punto de expedición **registrados**. En TEST, `numeroEstablecimiento` = `001` y `puntoExpedicion` en `001`/`002`/`003`. En producción, tienen que coincidir con lo que SET autorizó para tu timbrado. Si obtenés `1101` incluso usando `001`/`001`, el problema **no** es el establecimiento — es el timbrado (ver [1101](/docs/solucion-problemas/rechazos-comunes#rechazo-1101)). SIFEN valida el timbrado antes que el establecimiento. ## Código de actividad económica incorrecto [#actividad-economica] **Síntoma.** DE `RECHAZADO` porque una actividad económica (código CIIU) enviada no corresponde al emisor. **Causa.** Uno o más de los códigos de actividad económica que enviás **no están** entre las actividades que SET tiene registradas para tu RUC. En TEST, los datos del emisor tienen que coincidir con el registro **real** de Marangatu. **Solución.** Alineá las actividades económicas del contribuyente en Sifende (**Contribuyente → Editar → Actividades económicas**) con la lista de códigos CIIU **registrados** para tu RUC en Marangatu. Quitá cualquier actividad que no figure en tu registro; no agregues actividades "de más". ## Hash del código QR inválido [#hash-qr] **Síntoma.** DE `RECHAZADO` con "El hash del código QR incluido el de la cadena de caracteres es inválido". **Causa.** El CSC usado para calcular el hash del código QR **no coincide** con el CSC que SET tiene registrado para ese IdCSC. **Solución.** Configurá el **IdCSC** y el **CSC** del contribuyente con los valores que SET te asignó: * En **TEST**: los CSC genéricos que llegan en la notificación de **Marangatu** (`ABCD0000...` para IdCSC `1`, `EFGH0000...` para IdCSC `2`). * En **producción**: el CSC que SET te provee al habilitarte. **¿El contribuyente también emite con e-Kuatia'i?** SET asigna **dos** CSC (IdCSC `1` y `2`). El facturador gratuito de SET, **e-Kuatia'i**, usa el **IdCSC `1`**. Si el mismo RUC emite además desde Sifende, configurá el **IdCSC `2`** (con su CSC correspondiente — `EFGH0000...` en TEST) para no reutilizar el mismo CSC en dos sistemas distintos y evitar el rechazo del hash del QR. El CSC se carga junto con el certificado en [Contribuyente → Certificado digital](https://app.sifende.com.py/certificado-digital). Ver también [Requisitos previos → CSC](/docs/inicio-rapido/requisitos-previos). ## Checklist rápido [#checklist-rápido] Antes de reenviar un documento rechazado, verificá que **todo** coincida con SET: * [ ] El RUC está **habilitado** como facturador electrónico (Formulario 364 "Aceptado") en ese ambiente. * [ ] Ya pasaron **\~24–72 h** desde la habilitación (propagación del timbrado). * [ ] El **número de timbrado** coincide con Marangatu (en TEST: tu RUC sin DV). * [ ] La **fecha de inicio de vigencia** es idéntica a la de SET (en TEST: la fecha de aceptación del 364). * [ ] La **fecha de emisión** no es anterior al inicio de vigencia del timbrado. * [ ] El **establecimiento / punto** están registrados (en TEST: `001` y `001`/`002`/`003`). * [ ] Las **actividades económicas** son las registradas para tu RUC. * [ ] El **IdCSC + CSC** son los que SET asignó. ## ¿Seguís con problemas? [#seguís-con-problemas] * Buscá el código exacto en la [tabla completa de Rechazos SIFEN](/docs/solucion-problemas/rechazos-sifen). * Revisá cómo obtener cada dato en [Requisitos previos](/docs/inicio-rapido/requisitos-previos). * Si todo coincide con SET y el rechazo persiste, [contactá soporte](/docs/solucion-problemas/soporte) con el **CDC** y el `mensajeRechazo` completo. # Rechazos SIFEN (/docs/solucion-problemas/rechazos-sifen) Cuando SIFEN procesa un documento, devuelve un código de respuesta y un mensaje. Sifende guarda esos datos en el documento y los expone vía [`GET /status/:cdc`](/docs/referencia/documentos-electronicos/consultar-estado). Esta es la tabla de referencia completa. Si recién te habilitaste y tus primeros documentos salen rechazados, empezá por [Rechazos comunes de SIFEN](/docs/solucion-problemas/rechazos-comunes): explica los rechazos típicos de onboarding (timbrado, actividades económicas, CSC) con el detalle de por qué pasan y cómo resolverlos. ## Tipos de resultado SIFEN [#tipos-de-resultado-sifen] SIFEN clasifica cada respuesta con un tipo: | Tipo | Significado | Resultado en Sifende | | ---- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | A | Aprobado | `estado: APROBADO`. DE registrado y válido. | | AO | Aprobado con Observación | `estado: APROBADO_OBSERVACION`. DE registrado y legalmente válido, pero con advertencia (`mensajeRechazo` contiene el detalle). No hay que reemitirlo. | | R | Rechazado | `estado: RECHAZADO`. El DE no quedó registrado en SIFEN; hay que corregir y reenviar. | ## Formato del rechazo [#formato-del-rechazo] Cuando un DE es rechazado, el campo `mensajeRechazo` contiene el código y la descripción retornados por SIFEN: ```json { "estado": "RECHAZADO", "mensajeRechazo": "[1107] Fecha de inicio de vigencia del timbrado incorrecta" } ``` El mismo campo transporta las observaciones de un `APROBADO_OBSERVACION`. SIFEN puede devolver más de una por documento; en ese caso van concatenadas y separadas por `|`: ```json { "estado": "APROBADO_OBSERVACION", "mensajeRechazo": "[0300] Autorización del DE satisfactoria | [2001] RUC del receptor no activo en Marangatú" } ``` ## Timbrado y numeración [#timbrado-y-numeración] Errores que indican un problema con el timbrado, el establecimiento, el punto de expedición o el correlativo asignado. | Código | Tipo | Descripción | Solución | | ------ | ---- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `1003` | R | DV del CDC inválido (el DV calculado no coincide) | No deberías ver esto: Sifende calcula el DV. Si aparece, contactá soporte. | | `1101` | R | Número de timbrado inválido | Verificá el timbrado configurado en **Contribuyente → Timbrado**, en el ambiente de la API key, y que coincida con el del Registro de SIFEN. Común al recién habilitarse — ver [Rechazos comunes → 1101](/docs/solucion-problemas/rechazos-comunes#rechazo-1101). | | `1103` | R | El timbrado no está vigente a la fecha de emisión | Revisá que la fecha de emisión no sea anterior al inicio de vigencia del timbrado y que la fecha de inicio cargada coincida con la de la SET. Ver [Rechazos comunes → 1103](/docs/solucion-problemas/rechazos-comunes#rechazo-1103). | | `1105` | R | Código de establecimiento incorrecto | Confirmá que `numeroEstablecimiento` esté registrado en tu timbrado activo. | | `1106` | R | Punto de expedición incorrecto | Confirmá que `puntoExpedicion` esté autorizado para ese establecimiento. | | `1107` | R | Fecha de inicio de vigencia del timbrado incorrecta | Es una comparación **exacta** contra la vigencia registrada en SET, no un rango: `fechaInicio` tiene que ser idéntica a la del timbrado autorizado. En pruebas es la que la SET envía junto con el juego de datos de prueba; en producción, la del timbrado en Marangatú. | | `1109` | R | Número de documento ha sido inutilizado anteriormente | Ese correlativo ya fue inutilizado vía evento. Verificá el rango inutilizado y contactá a soporte antes de volver a emitir si el problema persiste. | ## Datos del receptor [#datos-del-receptor] Errores relacionados con el receptor del documento. La mayoría se debe a discrepancias entre `tipoOperacion` (B2B / B2C / B2G / B2F) y los datos enviados. | Código | Tipo | Descripción | Solución | | ------ | ---- | ------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `1150` | R | Fecha y hora de emisión con más de 30 días de atraso | SIFEN solo acepta DEs con `fechaEmision` hasta 720 horas (30 días) antes del envío. Emitilo con una fecha dentro de esa ventana. | | `1300` | R | Tipo de operación no compatible con la naturaleza del receptor | Revisá la combinación `tipoOperacion` × `tipoContribuyente` (ej: B2B requiere `CONTRIBUYENTE`). | | `1301` | R | Descripción del país receptor no corresponde al código | El código ISO de `pais` no coincide con la descripción almacenada. Usá el catálogo `pais` de `/public/enums`. | | `1302` | R | Es obligatorio informar el tipo de contribuyente receptor | Con `tipoContribuyente: "CONTRIBUYENTE"`, en cualquier `tipoOperacion`, enviá `tipoContribuyenteReceptor` (`PERSONA_FISICA` o `PERSONA_JURIDICA`). | | `1303` | R | Tipo de contribuyente receptor inválido (informado cuando es NO\_CONTRIBUYENTE) | Se informó `tipoContribuyenteReceptor` (`PERSONA_FISICA` / `PERSONA_JURIDICA`) para un receptor `NO_CONTRIBUYENTE`. Eliminá ese campo — no es lo mismo que `tipoContribuyente`, que siempre se envía. | | `1304` | R | Es obligatorio informar el RUC del receptor contribuyente | Con `tipoContribuyente: "CONTRIBUYENTE"`, en cualquier `tipoOperacion`, `numeroDocumento` debe ser el RUC y `digitoVerificador` el DV correspondiente. | | `1305` | R | RUC del receptor no requerido (informado cuando es NO\_CONTRIBUYENTE) | No es que falte eliminar `numeroDocumento` — ese campo sigue siendo obligatorio y para un receptor `NO_CONTRIBUYENTE` pasa a ser el número de CI/pasaporte, no el RUC. El rechazo aparece si tu integración envía el RUC para un receptor no contribuyente: confirmá que no estés mandando datos de RUC/contribuyente en ese caso y que uses `tipoDocumento` (`CEDULA_PARAGUAYA`, `PASAPORTE`, `INNOMINADO`…). | | `1306` | R | RUC del receptor inexistente en Marangatu | El RUC no está registrado en SET. Verificalo o pedile al cliente que lo confirme. | | `1307` | R | RUC del receptor en estado cancelado o suspendido | El RUC del cliente no está activo. No podés facturarle como B2B hasta que regularice. | | `1309` | R | DV del RUC del receptor incorrecto | Recalculá el DV del RUC del receptor con el algoritmo oficial. | | `1319` | R | Documento INNOMINADO no permitido para esta operación | El receptor `INNOMINADO` sólo se admite con `tipoOperacion: "B2C"`. Identificá al receptor con CI, RUC u otro documento. | | `1321` | R | INNOMINADO no permitido cuando el total supera el umbral | El monto supera el umbral DNIT para receptor sin identificación (Gs. 7.000.000). Pedí los datos al cliente e identificalo con CI o RUC. | ## Contenido del documento [#contenido-del-documento] Errores en los datos específicos del documento y en sus totales. | Código | Tipo | Descripción | Solución | | ------ | ---- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | | `1503` | R | Condición de operación inválida | Revisá `condicionOperacion` (`CONTADO` o `CREDITO`) y los campos asociados. | | `1907` | R | Tasa de IVA inválida | Las tasas válidas son `0`, `5` y `10`. Verificá `tasaIVA` en cada ítem. | | `2362` | R | Cálculo del total de la operación incorrecto | Sifende calcula los totales; si ves esto, hay datos inconsistentes en los ítems. Contactá soporte con el CDC. | ## Eventos (cancelación / inutilización) [#eventos-cancelación--inutilización] | Código | Tipo | Descripción | Solución | | ------ | ---- | --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | `4001` | R | CDC inválido en evento de cancelación/inutilización | Verificá que el CDC tenga 44 dígitos y corresponda a un DE aprobado. Cancelaciones solo aplican a DEs en estado `APROBADO` o `APROBADO_OBSERVACION`. | ## ¿El código no está en la tabla? [#el-código-no-está-en-la-tabla] SIFEN tiene cientos de códigos. Si tu mensaje no aparece arriba: 1. Revisá [Errores comunes](/docs/solucion-problemas/errores-comunes) por si el problema está en la solicitud HTTP (antes de SIFEN). 2. Consultá el Manual Técnico de SIFEN. 3. [Contactá soporte](/docs/solucion-problemas/soporte) con el CDC y el `mensajeRechazo` completo. # Ruta no encontrada (/docs/solucion-problemas/resource-not-found) **HTTP: 404.** La ruta solicitada no existe. ## Efecto de la solicitud [#efecto-de-la-solicitud] No se ejecutó una operación en esa ruta ni se consumió numeración o cupo. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Revisá la URL base, el prefijo `/api/v1` y la ruta de la [referencia](/docs/referencia). Reintentá después de corregir la URL. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`, que podés compartir con soporte. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/resource-not-found", "title": "Recurso no encontrado", "status": 404, "detail": "La ruta solicitada no existe: api/v1/ruta-inexistente", "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Documento no encontrado en el padrón (/docs/solucion-problemas/ruc-not-found) **HTTP: 404.** El RUC o documento consultado no figura en el padrón. ## Efecto de la solicitud [#efecto-de-la-solicitud] La consulta no modifica documentos ni consume numeración o cupo de emisión. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Verificá el número con tu cliente antes de repetir la [consulta al padrón](/docs/referencia/padron). ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`, que podés compartir con soporte. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/ruc-not-found", "title": "Not Found", "status": 404, "detail": "RUC no encontrado: 80012345", "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Operación no disponible en Sandbox (/docs/solucion-problemas/sandbox-operation-not-supported) **HTTP: 422.** SANDBOX no admite cancelaciones, inutilizaciones ni nominaciones. Esas operaciones requieren comunicarse con SIFEN. ## Efecto de la solicitud [#efecto-de-la-solicitud] No se creó ni envió un evento. El documento no cambió y la solicitud no consumió numeración ni cupo. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] No reintentes la misma operación en SANDBOX: esperar o cambiar `Idempotency-Key` no resuelve este error. Para probar cancelación o nominación, emití un documento en **DEV** con una clave `sk_test_` y operá sobre ese CDC. Para probar inutilización, usá la clave y el timbrado de DEV. Cambiar de clave no traslada un documento de SANDBOX a otro ambiente. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`, que podés compartir con soporte. No incluye `Retry-After`. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/sandbox-operation-not-supported", "title": "Unprocessable Entity", "status": 422, "detail": "La operación cancelación no está disponible en SANDBOX", "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá las diferencias entre [ambientes](/docs/conceptos/ambientes) y la [referencia de errores](/docs/referencia/errores). # Soporte (/docs/solucion-problemas/soporte) ## Canales de soporte [#canales-de-soporte] ### Email técnico [#email-técnico] Para problemas de integración, errores no documentados o preguntas sobre la API: **[soporte@sifende.com.py](mailto:soporte@sifende.com.py)** Incluí en tu mensaje: * Tu RUC de contribuyente * El CDC del documento afectado (si aplica) * El body completo de la solicitud y la respuesta de error * El ambiente (QA / Producción) ### Panel de Sifende [#panel-de-sifende] Para problemas de configuración (certificado, timbrado, API keys): **[app.sifende.com.py](https://app.sifende.com.py)** ## Antes de contactar soporte [#antes-de-contactar-soporte] Revisá primero: 1. [Errores Comunes](/docs/solucion-problemas/errores-comunes) 2. [Rechazos SIFEN](/docs/solucion-problemas/rechazos-sifen) 3. [FAQ](/docs/solucion-problemas/faq) 4. La [Referencia de Errores](/docs/referencia/errores) para interpretar el código de error # La suscripción cambió (/docs/solucion-problemas/subscription-stale) **HTTP: 409.** La configuración del plan cambió mientras se procesaba la solicitud. ## Efecto de la solicitud [#efecto-de-la-solicitud] La operación no se ejecutó: no creó documentos ni eventos y no consumió numeración ni cupo. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Consultá de nuevo el [plan y consumo](/docs/referencia/contribuyente/plan-consumo). Después reintentá la misma solicitud con la misma `Idempotency-Key`, si la enviaste. Si persiste, contactá a soporte. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`, que podés compartir con soporte. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/subscription-stale", "title": "La suscripción cambió mientras tanto", "status": 409, "detail": "La modalidad cambió mientras se admitía la emisión; volvé a intentar", "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Timbrado aún no vigente (/docs/solucion-problemas/timbrado-no-vigente) **HTTP: 422.** La fecha de emisión es anterior a la fecha de inicio de vigencia del timbrado del ambiente. El timbrado electrónico no tiene fecha de fin, así que no vence. ## Efecto de la solicitud [#efecto-de-la-solicitud] La emisión no se ejecutó: no creó un documento ni consumió numeración o cupo. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Revisá el número y la fecha de inicio desde [Contribuyente → Timbrado](/docs/panel/timbrado). Deben coincidir con la SET. Emití con una fecha igual o posterior al inicio de vigencia. Si la solicitud no cambia, conservá su `Idempotency-Key`. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`, que podés compartir con soporte. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/timbrado-no-vigente", "title": "Unprocessable Entity", "status": 422, "detail": "El timbrado 12557896 no está vigente. Inicio de vigencia: 2026-11-01", "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Tipo de contenido no admitido (/docs/solucion-problemas/unsupported-media-type) **HTTP: 415.** El `Content-Type` de la solicitud no es compatible con la operación. ## Efecto de la solicitud [#efecto-de-la-solicitud] La operación no se ejecutó: no creó documentos ni eventos y no consumió numeración ni cupo. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Para enviar JSON, usá `Content-Type: application/json` y un cuerpo JSON válido. Corregí el header antes de reintentar. ## Campos adicionales [#campos-adicionales] Puede incluir `traceId`, que podés compartir con soporte. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/unsupported-media-type", "title": "Content-Type no soportado", "status": 415, "detail": "El Content-Type 'text/plain' no está soportado. Tipos permitidos: [application/json]", "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # Datos de la solicitud inválidos (/docs/solucion-problemas/validation-error) **HTTP: 400.** La solicitud no cumple los requisitos de campos o del header `Idempotency-Key`. ## Efecto de la solicitud [#efecto-de-la-solicitud] La operación no se ejecutó: no creó documentos ni eventos y no consumió numeración ni cupo. ## Qué hacer y cuándo reintentar [#qué-hacer-y-cuándo-reintentar] Corregí los campos indicados. Si el problema está en el header, enviá una sola clave de 1 a 255 caracteres visibles, sin espacios en los extremos. No repitas automáticamente datos inválidos. ## Campos adicionales [#campos-adicionales] `errores` relaciona campos con mensajes de validación. Algunas causas usan `campo` en su lugar. Puede incluir `traceId`. ## Respuesta de ejemplo [#respuesta-de-ejemplo] ```json { "type": "https://sifende.com.py/docs/solucion-problemas/validation-error", "title": "Error de validación", "status": 400, "detail": "La solicitud contiene 2 error(es) de validación", "errores": { "receptor.tipoContribuyenteReceptor": "Tipo de contribuyente receptor es obligatorio para un contribuyente", "receptor.digitoVerificador": "Dígito verificador es obligatorio y debe contener un dígito" }, "traceId": "8f1c2b3a4d5e6f70" } ``` Consultá la [referencia de errores](/docs/referencia/errores) y las [reglas de idempotencia](/docs/guias/idempotencia) para manejar la respuesta en tu integración. # API keys (/docs/panel/api-keys) Una API key permite operar con el contribuyente seleccionado. Guardala como un secreto: quien la tenga puede usarla para acceder a su API. ## Crear una clave [#crear-una-clave] 1. Abrí **API Keys** y elegí **Crear API Key**. 2. Completá **Nombre** con algo que te permita reconocer la integración. 3. En **Ambiente**, elegí **SANDBOX — Simulador de Sifende** (`sk_sandbox_`), **DEV — Pruebas con SIFEN** (`sk_test_`) o **PROD — Documentos con validez fiscal** (`sk_live_`). 4. Si querés, elegí una **Expiración (opcional)**. 5. Presioná **Crear API Key** y copiá la clave completa. Se muestra una sola vez. Para crear una clave de producción, el contribuyente debe estar habilitado para producción y tener timbrado de producción vigente, CSC de producción y certificado activo. Si falta alguno, completá la configuración que indica el panel y volvé a crearla. El ambiente queda fijo al crear la clave. Todas usan `https://api.sifende.com.py`; para cambiar de ambiente, creá otra clave. Consultá [Ambientes](/docs/conceptos/ambientes). ## Rotar una clave [#rotar-una-clave] Elegí **Rotar** junto a la clave y confirmá con **Rotar clave**. La nueva clave conserva el ambiente y se muestra una sola vez. La anterior deja de funcionar al instante. Actualizá la credencial de tu integración para volver a usarla. ## Cambiar de clave sin interrumpir la integración [#cambiar-de-clave-sin-interrumpir-la-integración] 1. Creá otra clave para el mismo ambiente. 2. Configurala en tu integración y verificá que funcione. 3. Elegí **Eliminar** en la clave anterior. ## Eliminar o dejar vencer una clave [#eliminar-o-dejar-vencer-una-clave] **Eliminar** revoca el acceso de inmediato. Una clave que llega a su fecha de expiración también deja de funcionar. Antes de eliminarla o de que venza, actualizá las integraciones que la usen. Si perdiste una clave, creá otra o rotala: el panel no vuelve a mostrar su valor completo. Si se quita a un miembro del contribuyente, sus API keys se desactivan de inmediato. Antes, actualizá las integraciones que las usen. # Certificado y CSC (/docs/panel/certificado-y-csc) En **Contribuyente → Certificado digital**, configurá el certificado y el CSC del contribuyente seleccionado. ## Cargar el certificado [#cargar-el-certificado] Necesitás un certificado vigente emitido por un prestador de servicios de certificación autorizado. Sifende lo usa para firmar los documentos; el mismo certificado sirve para Sandbox, pruebas con SIFEN y producción. 1. Seleccioná el archivo PKCS12 (`.p12` o `.pfx`). 2. Completá **Contraseña del certificado**. 3. Completá también **ID CSC** y **CSC**. 4. Presioná **Guardar y continuar**. El CSC que enviás junto al certificado se guarda para el ambiente actual del contribuyente. El certificado y ese CSC se actualizan juntos; si la carga falla, ninguno cambia. Tu certificado se guarda cifrado. Conservá una copia del archivo y su contraseña en un lugar seguro. ## Configurar el CSC por ambiente [#configurar-el-csc-por-ambiente] En **Código de Seguridad (CSC)**, elegí pruebas o producción. Presioná **Configurar CSC** o **Actualizar CSC**, ingresá **ID CSC** y **CSC**, y confirmá con **Guardar CSC**. El ID tiene cuatro dígitos y el CSC, 32 caracteres alfanuméricos. Los valores de DEV y PROD se guardan por separado. En SANDBOX, Sifende proporciona el CSC de prueba; no tenés que cargarlo. En pruebas podés usar **Usar valores DEV**; para producción, cargá los valores que te proporcionó la SET. Si también emitís con e-Kuatia'i, usá el IdCSC 2 (`0002`) y su CSC correspondiente para Sifende. ## Renovar el certificado [#renovar-el-certificado] El panel muestra la vigencia y avisa cuando el certificado está **Próximo a vencer** o **Vencido**. Para renovarlo, elegí **Reemplazar certificado**, cargá el nuevo archivo con su contraseña, completá **ID CSC** y **CSC**, y presioná **Guardar certificado**. Hay un solo certificado activo por contribuyente. Al cargar otro, reemplazás el anterior para los tres ambientes. # Consultar documentos (/docs/panel/documentos) Seleccioná el contribuyente y abrí **Documentos electrónicos**. Elegí **Factura electrónica**, **Nota de Crédito**, **Nota de Débito** o **Nota de Remisión**, según el documento que buscás. ## Elegir el ambiente [#elegir-el-ambiente] En **Ambiente**, elegí dónde se emitió el documento: | Opción | Documentos que muestra | | -------------- | --------------------------------------------------------- | | **Desarrollo** | Pruebas enviadas a SIFEN en DEV | | **Producción** | Documentos emitidos en PROD | | **Sandbox** | Pruebas de Sifende emitidas en SANDBOX, sin envío a SIFEN | Al entrar, el listado muestra **Producción** si el contribuyente está configurado para producción; en los demás casos muestra **Desarrollo**. Si no encontrás una prueba de Sandbox, seleccioná ese ambiente. Cambiar **Ambiente** actualiza el listado y vuelve a la primera página. Este filtro sólo cambia los documentos que ves: no modifica el ambiente de tus claves ni de las nuevas emisiones. ## Filtrar y abrir un documento [#filtrar-y-abrir-un-documento] 1. Elegí **Estado**, **Desde** o **Hasta** para acotar la búsqueda. 2. Presioná **Buscar**. 3. Seleccioná una fila para abrir el documento. Los documentos archivados siguen visibles, pero no se pueden abrir. **Actualizar** vuelve a consultar con los filtros actuales. **Limpiar** borra el estado y las fechas y restaura el ambiente con el que abriste el listado. Si el documento sigue en proceso, consultá su [ciclo de vida](/docs/conceptos/ciclo-de-vida). Para interpretar una prueba de Sandbox, revisá [Ambientes](/docs/conceptos/ambientes#sandbox-de-sifende). # Equipo (/docs/panel/equipo) Los miembros comparten el acceso al contribuyente seleccionado. Pueden emitir y consultar documentos y administrar sus API keys. ## Invitar un miembro [#invitar-un-miembro] 1. Abrí **Miembros** y elegí **Invitar miembro**. 2. Completá **Email del colaborador** con la dirección que usa o usará para registrarse en Sifende. 3. Presioná **Enviar invitación**. El colaborador recibe un enlace válido por siete días. Si no tiene cuenta, puede crearla desde ese enlace. ## Quitar un miembro [#quitar-un-miembro] Elegí **Remover** junto al miembro y confirmá con **Sí, remover**. Pierde el acceso al contribuyente y sus API keys asociadas se desactivan de inmediato. Actualizá antes las integraciones que las usen. Los documentos que emitió se conservan. Podés volver a invitarlo. El **Propietario** no se puede quitar; para transferir la propiedad, [contactá a soporte](/docs/solucion-problemas/soporte). # Establecimientos y puntos de expedición (/docs/panel/establecimientos) Seleccioná el contribuyente y abrí **Contribuyente → Establecimientos** para administrar las sucursales y sus puntos de expedición. ## Crear un establecimiento [#crear-un-establecimiento] 1. Presioná **Nuevo establecimiento**. 2. Completá **Código** con un número entre 1 y 999. No se puede cambiar después de crear el establecimiento. 3. Si querés identificar la sucursal en el documento, completá **Nombre de sucursal**. Es opcional y admite hasta 30 caracteres. 4. Presioná **Guardar establecimiento**. El establecimiento se crea activo. Para cambiar su nombre o su **Estado** (`Activo` o `Inactivo`), usá **Editar**. ## Agregar puntos de expedición [#agregar-puntos-de-expedición] Abrí el establecimiento y buscá **Puntos de expedición**. Ingresá el número en **Nuevo punto** y presioná **Agregar punto**. Cada punto puede activarse o desactivarse con **Activar** o **Desactivar**. ## Efecto en las emisiones por API [#efecto-en-las-emisiones-por-api] En cada solicitud indicá `numeroEstablecimiento` y `puntoExpedicion`. Si existe un establecimiento con ese código y tiene **Nombre de sucursal**, ese nombre se incluye en el documento. La dirección del emisor se toma de los datos del contribuyente. El establecimiento no define una dirección de emisión distinta. El estado activo o inactivo del establecimiento y del punto restringe la emisión desde el panel. No bloquea una emisión por API con esos números. La numeración se mantiene por ambiente, tipo de documento, establecimiento y punto. Si migrás desde otro sistema, [configurá el próximo número](/docs/panel/numeracion) antes de emitir. Ver también [Múltiples establecimientos](/docs/guias/multiples-establecimientos). # Panel (/docs/panel) Entrá al [panel de Sifende](https://app.sifende.com.py) y seleccioná el contribuyente con el que vas a trabajar. Las opciones del menú se aplican a ese contribuyente. | Tarea | Dónde ir | | ----------------------------------------------------------------- | --------------------------------------- | | [Consultar documentos por ambiente](/docs/panel/documentos) | **Documentos electrónicos** | | [Reintentar un envío fallido](/docs/panel/lotes) | **Documentos electrónicos → Lotes** | | [Crear o cambiar una API key](/docs/panel/api-keys) | **API Keys** | | [Cargar el certificado y el CSC](/docs/panel/certificado-y-csc) | **Contribuyente → Certificado digital** | | [Configurar el timbrado](/docs/panel/timbrado) | **Contribuyente → Timbrado** | | [Continuar la numeración de otro sistema](/docs/panel/numeracion) | **Contribuyente → Numeración** | | [Configurar sucursales y puntos](/docs/panel/establecimientos) | **Contribuyente → Establecimientos** | | [Personalizar el KuDE y los correos](/docs/panel/personalizacion) | **Contribuyente → Personalización** | | [Recibir notificaciones en tu sistema](/docs/panel/webhooks) | **Webhooks** | | [Invitar colaboradores](/docs/panel/equipo) | **Miembros** | En [Planes y facturación](/docs/panel/planes-y-facturacion) podés consultar el plan, el consumo y los cobros. Mirá [Planes y precios](/docs/plataforma/planes) para conocer las funciones de cada plan. # Reintentar un envío fallido (/docs/panel/lotes) Un lote **Fallido** no se reintenta automáticamente. El panel muestra **Envío fallido permanentemente** y el motivo del fallo. Revisalo antes de solicitar otro intento. ## Encontrar el lote [#encontrar-el-lote] 1. Abrí **Documentos electrónicos** y elegí **Factura electrónica**, **Nota de Crédito**, **Nota de Débito** o **Nota de Remisión**, según el documento. 2. Abrí su detalle, buscá la tarjeta **Historial de Lotes** y abrí el lote. También podés entrar directamente por **Documentos electrónicos → Lotes**. ## Reintentar [#reintentar] 1. Confirmá que el estado del lote sea **Fallido**. 2. Presioná **Reintentar Lote**. Esta acción sólo está disponible para lotes **Fallido**; otros estados no admiten reintento manual. 3. Retomá las [consultas de estado](/docs/guias/consultar-estado) con los mismos CDC. Los documentos en `ERROR` vuelven a `EN_LOTE`. Los que ya estaban en `EN_LOTE` siguen así: ese estado abarca el envío y la espera del resultado de SIFEN. No emitas documentos nuevos para reemplazar este intento. Si el lote está en **Error**, Sifende reintenta solo: el panel muestra **Reintento programado** y, cuando está disponible, **Próximo intento:**. Consultá los [estados de los lotes](/docs/conceptos/lotes) para distinguirlos de los estados de cada documento. # Continuar la numeración (/docs/panel/numeracion) Si migrás desde otro sistema, fijá el próximo número antes de emitir por API. La numeración es independiente por contribuyente, ambiente, establecimiento, punto de expedición y tipo de documento. ## Antes de empezar [#antes-de-empezar] Cargá el [timbrado del ambiente](/docs/panel/timbrado). Para cambiar la numeración, tenés que ser propietario del contribuyente. El próximo número debe estar entre **1 y 9.999.999** y no puede retroceder respecto de la secuencia actual. ## Fijar el próximo número [#fijar-el-próximo-número] 1. Seleccioná el contribuyente y abrí **Contribuyente → Numeración**. 2. Elegí **Ambiente**: `DEV` o `PROD`. 3. Presioná **Agregar Numeración**, o **Editar** en una secuencia existente. 4. En **Fijar el próximo número**, completá **Establecimiento**, **Punto de expedición**, **Tipo de documento** y **Próximo número a emitir**. El establecimiento y el punto van de 1 a 999. 5. En **Escribí … para confirmar**, ingresá el RUC con su dígito verificador, tal como aparece en la indicación. 6. Presioná **Fijar numeración** y verificá el valor en **Próximo a emitir**. Por ejemplo, si ya emitiste hasta el número `125` para una combinación, fijá `126` como próximo número. Repetí el ajuste para cada combinación que necesites continuar. Al emitir por API, enviá `numeroEstablecimiento` y `puntoExpedicion`. Sifende asigna el número del documento; no lo envíes en la solicitud. Consultá [Timbrado y numeración](/docs/conceptos/timbrado-numeracion) para entender la secuencia. # Personalización (/docs/panel/personalizacion) Abrí **Contribuyente → Personalización** para configurar la marca del contribuyente seleccionado. Consultá la disponibilidad en [Planes y precios](/docs/plataforma/planes). ## Logo del negocio [#logo-del-negocio] Arrastrá un PNG o JPG de hasta 2 MB, con al menos 64 píxeles de ancho y alto. El logo se ajusta a una caja apaisada sin deformarse ni recortarse. Para retirarlo, elegí **Quitar logo**. Un logo nuevo puede tardar hasta una hora en verse en correos ya enviados. Los KuDE ya emitidos conservan el logo que tenían al emitirse. ## Marca y contacto [#marca-y-contacto] | Opción | Qué cambia | | ------------------------------ | ------------------------------------------------------- | | **Nombre comercial** | Nombre con el que se presenta el remitente del correo | | **Color de acento** | Color primario de botones, bordes y enlaces | | **Color de fondo** | Color secundario de la franja del encabezado y el total | | **Redes sociales y sitio web** | Enlaces al pie del correo; WhatsApp abre el chat | | **Contacto comercial** | Teléfono, email y dirección para contactar al negocio | | **Mensaje al pie del correo** | Texto de hasta 500 caracteres | Usá las opciones de **Marca y visibilidad** para elegir qué datos mostrar u ocultar. Después presioná **Guardar cambios**. Los datos de contacto comercial no reemplazan los del RUC: el KuDE conserva la dirección y el teléfono declarados ante la SET. ## Enviar un correo de prueba [#enviar-un-correo-de-prueba] Guardá los cambios y elegí **Enviar correo de prueba**. Llega al email de tu usuario, con datos de ejemplo y marcado como prueba. Puede tardar unos segundos. Podés enviar hasta 20 correos de prueba por hora por usuario. Si alcanzás el límite, esperá el tiempo que indica el mensaje antes de volver a enviarlo. # Planes y facturación (/docs/panel/planes-y-facturacion) ## Qué muestra la sección Planes y facturación [#qué-muestra-la-sección-planes-y-facturación] **Planes y facturación**, en el menú lateral del panel, reúne todo lo del plan del contribuyente seleccionado: el plan vigente, el consumo del ciclo, lo que está pendiente de pago y el historial de cobros. El panel **Plan actual** presenta por separado: * **Incluidos:** el cupo efectivo del ciclo. * **Consumidos:** documentos confirmados; son los únicos que pueden convertirse en adicionales. * **En proceso:** reservas que ocupan capacidad mientras se conoce el resultado, pero no son consumo cobrado. * **Disponibles:** capacidad incluida restante. La presentación cambia según el plan y el ambiente: | Caso | Presentación | | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | | Plan sin documentos adicionales | Cuando quedan cero disponibles, avisa que las nuevas emisiones serán bloqueadas hasta el próximo ciclo y ofrece **Contactar soporte** | | Plan con adicionales | Muestra cantidad adicional × precio unitario efectivo = costo adicional estimado en PYG | | Pruebas | Prioriza **Sandbox ilimitado**: las emisiones de prueba no consumen cupo ni se presentan como bloqueadas | El costo adicional es una **estimación**, no un cobro ejecutado. Los datos también están disponibles mediante la [consulta con API key](/docs/referencia/contribuyente/plan-consumo). ## Cómo se paga [#cómo-se-paga] Cada ciclo genera sus cobros y todos se pagan igual: transferencia con la referencia en el concepto, y nos mandás el comprobante. | Cobro | Cuándo se emite | | ----------------------------------- | --------------------------------------------------------------------------------------- | | **Cuota del plan** | Al abrir cada ciclo, por el importe mensual del plan. El plan gratuito no genera cuota. | | **Documentos adicionales** | Al cerrar un ciclo, si hubo documentos confirmados por encima del cupo. | | **Contratación de un plan mensual** | Al activar un plan mensual desde el plan gratuito o desde Packs, con un ciclo nuevo. | **Cobros pendientes** lista lo que se debe con su importe, su referencia y su vencimiento, junto a la cuenta a la que transferir, y suma el total. Cada cobro trae un botón que abre WhatsApp con la referencia y el importe ya escritos, que es la vía más rápida para mandar el comprobante; el mail sigue disponible. Un cobro queda saldado cuando verificamos el comprobante. Cada cobro vence 5 días después de emitido, y te avisamos por email al emitirlo. Si vence sin pagar, se suspende la emisión en producción hasta que confirmemos el pago: el panel lo muestra y la API responde [`emission-suspended`](/docs/solucion-problemas/emission-suspended). Las pruebas, las consultas y los documentos ya emitidos no se ven afectados. Un pack sin pagar no suspende nada: sólo queda sin activar. **Historial de cobros** muestra todos los cobros emitidos —pendientes, pagados y anulados— del más nuevo al más viejo. ## Cambiar de plan [#cambiar-de-plan] Abrí **Cambiar plan** en **Planes y facturación** y elegí el plan de destino. La fecha de aplicación depende del plan actual: | Cambio | Cuándo se aplica | Cobro | | -------------------------------------------------------------- | ------------------------------------------------------------ | --------------------------------------------------------------------------- | | Del plan gratuito o de Packs a un plan mensual | En el momento, con un ciclo nuevo que empieza ese día | Se emite el cobro de contratación | | Entre planes mensuales pagos, tanto para subir como para bajar | En la próxima renovación; hasta entonces rige el plan actual | No hay cobro por programarlo; el plan nuevo se cobra al renovar | | De un plan mensual a Packs | En la próxima renovación | Programar el cambio no genera cobro; después se habilita la compra de packs | Para una activación inmediata, el botón es **Contratar y ver datos de pago**. Para un cambio al cierre del ciclo, es **Confirmar programación**. Un cambio pendiente aparece como **Cambio programado**, con el plan de destino y la fecha de aplicación. Podés usar **Cancelar programación** mientras siga pendiente o **Reemplazar** para elegir otro destino. Una programación nueva reemplaza a la anterior. Programar o cancelar no genera un cobro, y las deudas anteriores se mantienen por separado. Desde Packs, no podés contratar un plan mensual mientras queden saldo disponible, reservas o una compra pendiente. Los planes a convenir se gestionan con el equipo comercial. Al activarse el plan nuevo, el acceso a los documentos pasa a depender de su período de acceso. Un plan con un período mayor puede volver a habilitar documentos archivados que todavía se conservan. Un cambio programado no modifica ese acceso antes de su fecha de aplicación. Si el pago no se concreta, contactá a soporte. La contratación activa no vuelve automáticamente al plan anterior por anular su cobro. ## Si se agota el cupo [#si-se-agota-el-cupo] La alerta muestra el plan, los documentos incluidos, el consumo, los documentos en proceso, la capacidad disponible y la fecha de renovación. Ofrece las acciones **Ver planes** y **Contactar soporte**. # Timbrado (/docs/panel/timbrado) 1. Abrí **Contribuyente → Timbrado**. 2. En **Ambiente del timbrado**, elegí el ambiente que vas a configurar. 3. Completá **Número de Timbrado** y **Fecha de Inicio**. 4. Presioná **Guardar y continuar**. El timbrado se configura por ambiente. La fecha de inicio debe coincidir exactamente con la registrada ante la SET. En pruebas, SIFEN utiliza el RUC sin dígito verificador como número de timbrado; consultá los [datos de prueba](/docs/solucion-problemas/rechazos-comunes#ambiente-prueba). Los números de establecimiento y punto de expedición se envían en cada emisión. No se cargan como parte del timbrado. En [SANDBOX](/docs/conceptos/ambientes#sandbox-de-sifende), Sifende proporciona el timbrado de prueba; no tenés que cargarlo. Estos pasos corresponden a DEV y PROD. ## Cambiar el timbrado [#cambiar-el-timbrado] El timbrado electrónico no tiene fecha de fin, así que no hace falta renovarlo. Si la SET te asigna uno nuevo, actualizá el número y la fecha de inicio en esta misma pantalla, en el ambiente correspondiente. Revisá **Estado del Timbrado** para comprobar lo que quedó guardado. Si SIFEN rechaza un documento por su timbrado, compará el número y la fecha de inicio con los de la SET. Mirá [Rechazos comunes](/docs/solucion-problemas/rechazos-comunes). # Webhooks (/docs/panel/webhooks) En **Webhooks**, podés configurar hasta cinco endpoints activos por contribuyente y ambiente. Los eventos nuevos se entregan únicamente a los endpoints del ambiente elegido. ## Agregar un endpoint [#agregar-un-endpoint] 1. Elegí **Agregar endpoint**. 2. Elegí **Ambiente**: **Producción**, **Pruebas SIFEN** o **Sandbox**. 3. Completá **URL de entrega** con una dirección HTTPS accesible desde internet. 4. Seleccioná **Eventos que recibirá**. 5. Confirmá con **Agregar endpoint**. 6. Copiá el secreto `whsec_` y guardalo en tu integración. Se muestra al crear o rotar el secreto. Usá ese secreto para verificar cada notificación. La [referencia de webhooks](/docs/referencia/webhooks) explica la firma, los datos de cada evento, los reintentos y cómo evitar procesar una entrega repetida. ## Elegir el ambiente [#elegir-el-ambiente] La tarjeta de cada endpoint muestra `PROD`, `DEV` o `SANDBOX`. El ambiente queda fijo al crearlo: para recibir eventos de otro ambiente, agregá otro endpoint. Podés usar la misma URL en ambientes distintos; cada endpoint tiene su propio secreto. Si el endpoint ya existía antes de la separación por ambiente, las entregas anteriores conservan su destinatario original y pueden corresponder a otro ambiente. Consultá el [detalle de la actualización](/docs/referencia/changelog#si-ya-usás-webhooks). ## Activar, desactivar o eliminar [#activar-desactivar-o-eliminar] En **Editar endpoint**, marcá o desmarcá **Recibir eventos en este endpoint** y elegí **Guardar cambios**. Un endpoint desactivado aparece como **Pausado**. **Eliminar endpoint** lo retira de la configuración. **Rotar secreto** genera uno nuevo; guardalo y actualizá la verificación de tu integración. ## Consultar las entregas [#consultar-las-entregas] **Entregas recientes** muestra el historial de los últimos 90 días. Filtrá por endpoint, estado o evento y abrí el detalle para consultar los intentos y la respuesta de tu sistema. # Enumeraciones SIFEN (Endpoint) (/docs/referencia/catalogos/enumeraciones) ## GET /api/v1/public/enums [#get-apiv1publicenums] Devuelve todas las enumeraciones SIFEN soportadas con sus valores y etiquetas. Endpoint **público** — no requiere autenticación. CORS habilitado para uso desde cualquier frontend. ### Autenticación [#autenticación] Ninguna. No envíes `Authorization`. ### Respuesta exitosa [#respuesta-exitosa] **Status:** `200 OK` La respuesta es un objeto cuyas claves identifican las categorías. Este extracto muestra dos de ellas: ```json { "tipoDocumento": [ { "name": "FACTURA_ELECTRONICA", "label": "Factura electrónica", "val": 1 }, { "name": "AUTOFACTURA_ELECTRONICA", "label": "Autofactura electrónica", "val": 4 }, { "name": "NOTA_DE_CREDITO_ELECTRONICA", "label": "Nota de crédito electrónica", "val": 5 }, { "name": "NOTA_DE_DEBITO_ELECTRONICA", "label": "Nota de débito electrónica", "val": 6 }, { "name": "NOTA_DE_REMISION_ELECTRONICA", "label": "Nota de remisión electrónica", "val": 7 } ], "departamento": [ { "name": "CAPITAL", "label": "CAPITAL", "val": 1 }, { "name": "PTE_HAYES", "label": "PTE. HAYES", "val": 15 } ] } ``` ### Campos de cada valor [#campos-de-cada-valor] | Campo | Tipo | Descripción | | ------- | ----------------- | ------------------------------------------------------- | | `name` | `string` | Identificador en mayúsculas usado al enviar solicitudes | | `label` | `string` | Texto legible para mostrar en UI | | `val` | `integer \| null` | Código numérico SIFEN, o `null` cuando no aplica | `extra` contiene la abreviatura en la categoría `unidadMedida`; puede ser `null`. Para los campos de tipo enum, enviá `name` como texto. Los campos numéricos conservan su tipo: por ejemplo, `transporte.vehiculos[].tipoIdentificacion` usa `1` o `2`, y `tipoDocumento` en una inutilización usa el código numérico. Consultá el modelo de la operación. `receptor.departamento` acepta el `name` (`PTE_HAYES`), el `label` (`PTE. HAYES`) o el código como texto (`"15"`). ### Categorías disponibles [#categorías-disponibles] | Clave | Descripción | Uso | | --------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | | `tipoDocumento` | Tipo de documento electrónico | Campo `tipoDocumento` | | `tipoEmision` | Tipo de emisión | Campo `tipoEmision` | | `tipoTransaccion` | Tipo de transacción | Campo `tipoTransaccion` (solo FE) | | `condicionOperacion` | Condición de operación | Campo `condicionOperacion` | | `condicionCredito` | Modalidad de crédito | `condicionPago.condicionCredito` | | `unidadPlazoCredito` | Días o meses | `condicionPago.plazoEstructurado.unidad` | | `tipoPago` | Tipo de pago | Campo `condicionPago.tipoPago` o `pagos[].tipoPago` | | `tipoTarjeta` | Denominación de la tarjeta | Campo `pagos[].tarjeta.tipoTarjeta` | | `formaProcesamientoPago` | Forma de procesamiento de la tarjeta | Campo `pagos[].tarjeta.formaProcesamientoPago` | | `indicadorPresencia` | Presencia del comprador | Campo `indicadorPresencia` (sólo FE) | | `tipoImpuesto` | Impuesto afectado | Campo `tipoImpuesto` (sólo FE) | | `condicionAnticipo` | Anticipo global o por ítem | Campo `condicionAnticipo` (sólo FE) | | `tipoOperacionVehiculo` | Tipo de operación de venta de vehículo nuevo | Campo `items[].vehiculoNuevo.tipoOperacion` | | `tipoCombustible` | Tipo de combustible | Campo `items[].vehiculoNuevo.tipoCombustible` | | `naturalezaReceptor` | Naturaleza del receptor | Campo `receptor.tipoContribuyente` | | `tipoContribuyenteReceptor` | Persona física o jurídica | Campo `receptor.tipoContribuyenteReceptor` (sólo receptores contribuyentes) | | `tipoOperacion` | Tipo de operación B2B/B2C | Campo `receptor.tipoOperacion` | | `tipoDocumentoReceptor` | Tipo de documento del receptor | Campo `receptor.tipoDocumento` | | `unidadMedida` | Unidades de medida (con abreviatura) | Campo `items[].unidadMedida` | | `afectacionIVA` | Afectación tributaria | Campo `items[].afectacionTributaria` | | `motivoEmision` | Motivo de emisión (NCE/NDE) | Campo `motivoEmision` | | `tipoDocumentoAsociado` | Tipo de documento asociado | Campos `documentoAsociado.tipoDocumento` y `documentosAsociados[].tipoDocumento` | | `tipoDocumentoImpreso` | Tipo de comprobante impreso: `FACTURA`, `NOTA_DE_CREDITO`, `NOTA_DE_DEBITO`, `NOTA_DE_REMISION` | Campo `documentosAsociados[].tipoDocumentoImpreso`; la FE admite `FACTURA` y `NOTA_DE_REMISION` | | `departamento` | Departamentos del Paraguay | Campo `receptor.departamento`; las ciudades se consultan en [geografía](/docs/referencia/catalogos/geografia) | | `moneda` | Monedas comunes (15 valores) | Campo `monedaOperacion` | | `monedaCompleta` | Catálogo completo de monedas ISO 4217 | Campo `monedaOperacion` | | `pais` | Países comunes (16 valores) | Campo `receptor.pais` | | `paisCompleto` | Catálogo completo de países ISO 3166 | Campo `receptor.pais` | Las categorías de remisión son `caracteristicaCarga`, `motivoTraslado`, `responsableEmision`, `tipoTransporte`, `modalidadTransporte`, `responsableFlete`, `incoterm`, `tipoDocumentoImpresoRemision`, `relevanciaMercaderia`, `tipoDocumentoTransportista`, `tipoDocumentoAsociadoRemision` y `tipoIdentificacionVehiculo`. También se devuelve `obligacionAfectada`. Usá este endpoint para poblar dropdowns y selects en tu UI. Los valores se mantienen sincronizados con las versiones de SIFEN aceptadas por la API. Para la referencia estática completa, ver [Enumeraciones](/docs/referencia/enumeraciones). ### Errores [#errores] Este endpoint no produce errores de autenticación. Solo `500` en caso de fallo del servidor. ### Ejemplo [#ejemplo] ```bash curl https://api.sifende.com.py/api/v1/public/enums ``` Filtrar una categoría específica con `jq`: ```bash curl https://api.sifende.com.py/api/v1/public/enums | jq '.tipoDocumento' ``` # Geografía (/docs/referencia/catalogos/geografia) El catálogo público permite elegir departamentos, distritos y ciudades de Paraguay. No requiere API key. Usá el campo `codigo` de cada resultado para los códigos geográficos de las direcciones. Los identificadores terminados en `Id` sirven para recorrer este catálogo; no son los códigos SIFEN. ## Consultas [#consultas] | Ruta | Resultado | | ---------------------------------------------------------------- | ------------------------------------------------ | | `GET /api/v1/geografia/departamentos` | Departamentos | | `GET /api/v1/geografia/departamentos/{departamentoId}/distritos` | Distritos del departamento seleccionado | | `GET /api/v1/geografia/distritos/{distritoId}/ciudades` | Ciudades del distrito seleccionado | | `GET /api/v1/geografia/departamentos/{departamentoId}/ciudades` | Ciudades de todos los distritos del departamento | Las cuatro consultas devuelven `200 OK` con los resultados dentro de `data`. La respuesta también incluye `timestamp` y `errors`. Si no hay resultados, `data` es una lista vacía. ## Ejemplos de respuesta [#ejemplos-de-respuesta] Estos extractos muestran el formato de las respuestas. Las ciudades por departamento tienen los mismos campos que las ciudades por distrito. Capital tiene código `1`; Concepción, `2`; y Central, `12`. `GET /api/v1/geografia/departamentos`: ```json { "data": [ { "departamentoId": 1, "codigo": 1, "nombre": "CAPITAL" }, { "departamentoId": 2, "codigo": 2, "nombre": "CONCEPCION" }, { "departamentoId": 12, "codigo": 12, "nombre": "CENTRAL" } ], "timestamp": "2026-10-02T10:30:00-03:00", "errors": null } ``` `GET /api/v1/geografia/departamentos/1/distritos`: ```json { "data": [ { "distritoId": 1, "departamentoId": 1, "codigo": 1, "nombre": "ASUNCION (DISTRITO)" } ], "timestamp": "2026-10-02T10:30:00-03:00", "errors": null } ``` `GET /api/v1/geografia/distritos/1/ciudades`: ```json { "data": [ { "ciudadId": 1, "distritoId": 1, "codigo": 1, "nombre": "ASUNCION (DISTRITO)" } ], "timestamp": "2026-10-02T10:30:00-03:00", "errors": null } ``` ## Campos de cada resultado [#campos-de-cada-resultado] | Campo | Tipo | Presencia y uso | | ---------------- | --------- | ------------------------------------------------------------ | | `codigo` | `integer` | Código geográfico SIFEN | | `nombre` | `string` | Nombre para mostrar en el selector | | `departamentoId` | `integer` | Departamentos y distritos; usalo en la consulta de distritos | | `distritoId` | `integer` | Distritos y ciudades; usalo en la consulta de ciudades | | `ciudadId` | `integer` | Identifica un resultado de ciudad | ## Recorrer el catálogo [#recorrer-el-catálogo] ```bash curl -s https://api.sifende.com.py/api/v1/geografia/departamentos | jq '.data' curl -s "https://api.sifende.com.py/api/v1/geografia/departamentos/$DEPARTAMENTO_ID/distritos" | jq '.data' curl -s "https://api.sifende.com.py/api/v1/geografia/distritos/$DISTRITO_ID/ciudades" | jq '.data' ``` 1. Cargá los departamentos y mostrá su `nombre`. 2. Al elegir uno, usá su `departamentoId` para consultar los distritos. 3. Al elegir el distrito, usá su `distritoId` para consultar las ciudades. 4. Conservá los `codigo` de los resultados elegidos para completar la dirección. Si la dirección no necesita distrito, como en una autofactura, consultá las ciudades directamente con `/departamentos/{departamentoId}/ciudades`. En el [receptor](/docs/referencia/modelos/receptor), `departamento` y `ciudad` aceptan nombres o códigos expresados como texto; `codigoDistrito` es numérico. Respetá los tipos indicados en el modelo de cada dirección, incluidas las de [nota de remisión](/docs/referencia/modelos/nota-remision). En [autofactura](/docs/referencia/modelos/autofactura), `departamento` y `ciudad` aceptan sólo códigos SIFEN expresados como texto. # Consultar Contribuyente (/docs/referencia/contribuyente) ## GET /api/v1/contribuyente [#get-apiv1contribuyente] Devuelve los datos del contribuyente emisor tal como se usan al emitir en el ambiente de la API key, y si su configuración permite emitir. ### Autenticación [#autenticación] `Authorization: Bearer {api-key}` — requerido La API key determina el contribuyente y el ambiente consultados. El endpoint no acepta RUC ni ID de contribuyente en el path, query o body. ### Ejemplo [#ejemplo] ```bash curl https://api.sifende.com.py/api/v1/contribuyente \ -H "Authorization: Bearer $SIFENDE_API_KEY" ``` ### Respuesta exitosa [#respuesta-exitosa] **Status:** `200 OK` La respuesta es el objeto del contribuyente directamente, sin envelope. ```json { "ruc": "80012345", "digitoVerificador": "1", "razonSocial": "Ejemplo S.A.", "nombreFantasia": "Ejemplo", "tipoContribuyente": "PERSONA_JURIDICA", "ambiente": "PROD", "actividadesEconomicas": [ { "codigo": "56101", "descripcion": "Restaurantes" } ], "direccion": "Av. Mcal. López", "numeroCasa": 1234, "departamento": { "codigo": 1, "descripcion": "CAPITAL" }, "distrito": { "codigo": 1, "descripcion": "ASUNCION (DISTRITO)" }, "ciudad": { "codigo": 1, "descripcion": "ASUNCION (DISTRITO)" }, "telefono": "021123456", "email": "facturacion@ejemplo.com.py", "timbrado": { "numero": 12345678, "fechaInicioVigencia": "2026-01-15" }, "establecimientos": [ { "numeroEstablecimiento": 1, "nombreSucursal": "Casa central", "activo": true, "puntosExpedicion": [ { "puntoExpedicion": 1, "activo": true } ] } ], "logoUrl": "https://storage.googleapis.com/sifende-assets/logos/112/3f0c8f5e-6b2a-4d7e-9a51-2c4e8b7d9f10.png", "estadoConfiguracion": { "certificadoConfigurado": true, "certificadoVence": "2027-03-01", "certificadoVigente": true, "cscConfigurado": true, "timbradoVigente": true, "direccionConfigurada": true, "actividadEconomicaConfigurada": true, "listoParaEmitir": true } } ``` ### Campos [#campos] Todos los campos están siempre presentes; los marcados `| null` valen `null` cuando el dato no está cargado. | Campo | Tipo | Descripción | | ----------------------- | ----------------- | --------------------------------------------------------------------------------------------------------- | | `ruc` | `string` | RUC sin dígito verificador | | `digitoVerificador` | `string` | Dígito verificador del RUC | | `razonSocial` | `string` | Razón social del emisor | | `nombreFantasia` | `string \| null` | Nombre de fantasía | | `tipoContribuyente` | `string` | `PERSONA_FISICA` o `PERSONA_JURIDICA` | | `ambiente` | `string` | Ambiente de la API key: `DEV`, `PROD` o `SANDBOX` | | `actividadesEconomicas` | `array` | Actividades económicas (`codigo`, `descripcion`) que se informan en el documento; vacío si no hay ninguna | | `direccion` | `string \| null` | Dirección del emisor | | `numeroCasa` | `integer \| null` | Número de casa | | `departamento` | `object \| null` | `codigo` y `descripcion` SIFEN del departamento | | `distrito` | `object \| null` | `codigo` y `descripcion` SIFEN del distrito; es opcional aunque haya dirección | | `ciudad` | `object \| null` | `codigo` y `descripcion` SIFEN de la ciudad | | `telefono` | `string` | Teléfono del emisor | | `email` | `string` | Email del emisor | | `timbrado` | `object \| null` | Timbrado del ambiente de la API key: `numero` y `fechaInicioVigencia` | | `establecimientos` | `array` | Establecimientos con sus puntos de expedición | | `logoUrl` | `string \| null` | URL pública y estable del logo cargado en [Personalización](/docs/panel/personalizacion) | | `estadoConfiguracion` | `object` | Estado de la configuración necesaria para emitir | El timbrado electrónico no tiene fecha de fin, así que no hay `fechaFinVigencia`. `numeroEstablecimiento` y `puntoExpedicion` son los valores que enviás en la [emisión](/docs/referencia/documentos-electronicos/emitir). `activo` refleja el estado configurado en el [panel](/docs/panel/establecimientos); la emisión por API no lo valida. ### Estado de la configuración [#estado-de-la-configuración] | Campo | Tipo | Descripción | | ------------------------------- | ------------------------ | -------------------------------------------------------------------------------------------------- | | `certificadoConfigurado` | `boolean` | Hay un certificado digital activo | | `certificadoVence` | `string (fecha) \| null` | Fin de vigencia del certificado, en hora de Paraguay; `null` sin certificado o si no se puede leer | | `certificadoVigente` | `boolean` | El certificado es válido en este momento | | `cscConfigurado` | `boolean` | Hay un CSC con su ID cargado para el ambiente de la API key | | `timbradoVigente` | `boolean` | El timbrado del ambiente ya comenzó su vigencia, según la fecha de Paraguay | | `direccionConfigurada` | `boolean` | Hay una dirección del emisor cargada | | `actividadEconomicaConfigurada` | `boolean` | Hay al menos una actividad económica | | `listoParaEmitir` | `boolean` | La emisión no va a fallar por configuración del emisor | `listoParaEmitir` reproduce los controles de configuración que la emisión hace antes de asignar número. Con `false`, `POST /api/v1/documento-electronico` responde, según el dato faltante, [`configuracion-incompleta`](/docs/solucion-problemas/configuracion-incompleta), [`certificate-not-found`](/docs/solucion-problemas/certificate-not-found), `certificado-no-vigente` o [`timbrado-no-vigente`](/docs/solucion-problemas/timbrado-no-vigente). No contempla el cupo del plan, que se consulta en [Consultar Plan y Consumo](/docs/referencia/contribuyente/plan-consumo). En [SANDBOX](/docs/conceptos/ambientes#sandbox-de-sifende), Sifende genera el timbrado y el CSC de prueba en la primera emisión y no exige la vigencia del certificado, pero sí un certificado activo. Antes de esa emisión, `timbrado` puede ser `null` con `timbradoVigente: true`. ### Errores [#errores] | Status | Descripción | | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | `401` | API key ausente, inválida o revocada | | `403` | [`plan-operation-not-allowed`](/docs/solucion-problemas/plan-operation-not-allowed): con una API key de PROD, el plan no incluye la API de integración | | `500` | Error interno al consultar el contribuyente | # Consultar Plan y Consumo (/docs/referencia/contribuyente/plan-consumo) ## GET /api/v1/contribuyente/plan-consumo [#get-apiv1contribuyenteplan-consumo] Devuelve un snapshot del plan vigente y del consumo del ciclo actual. **Ruta deprecada:** `GET /api/v1/documento-electronico/plan-consumo` sigue respondiendo lo mismo hasta el **15 de enero de 2027**, cuando se remueve. Sus respuestas incluyen `Deprecation: @1791590400`, `Sunset: Fri, 15 Jan 2027 00:00:00 GMT` y `Link: ; rel="successor-version"`. Cambiá la URL; la autenticación y la respuesta no cambian. Ver [Versionado](/docs/referencia/versionado#deprecaciones-vigentes). ### Autenticación [#autenticación] `Authorization: Bearer {api-key}` — requerido La API key determina el contribuyente consultado. El endpoint no acepta RUC, ID de contribuyente ni suscripción en el path, query o body; una integración no puede seleccionar otro contribuyente. ### Ejemplo [#ejemplo] ```bash curl https://api.sifende.com.py/api/v1/contribuyente/plan-consumo \ -H "Authorization: Bearer $SIFENDE_API_KEY" ``` ### Respuesta exitosa [#respuesta-exitosa] **Status:** `200 OK` La respuesta es el objeto de plan y consumo directamente, sin envelope. ```json { "codigoPlan": "PRO", "nombrePlan": "PRO", "inicioPeriodo": "2026-10-02T03:00:00Z", "finPeriodo": "2026-11-02T03:00:00Z", "documentosIncluidos": 250, "consumoConfirmado": 262, "reservasActivas": 3, "documentosDisponibles": 0, "permiteAdicionales": true, "precioDocumentoAdicionalPyg": 400, "adicionalesFacturables": 12, "costoEstimadoPyg": 4800 } ``` ### Campos [#campos] | Campo | Tipo | Descripción | | ----------------------------- | ------------------- | --------------------------------------------------------------------- | | `codigoPlan` | `string` | Código estable del plan vigente | | `nombrePlan` | `string` | Nombre del plan apto para mostrar | | `inicioPeriodo` | `string (RFC 3339)` | Inicio inclusivo del ciclo | | `finPeriodo` | `string (RFC 3339)` | Fin exclusivo del ciclo | | `documentosIncluidos` | `integer` | Cupo efectivo incluido en el ciclo | | `consumoConfirmado` | `integer` | Documentos definitivos del ciclo | | `reservasActivas` | `integer` | Documentos en proceso que conservan capacidad mientras se resuelven | | `documentosDisponibles` | `integer` | Capacidad incluida restante; nunca es negativa | | `permiteAdicionales` | `boolean` | Indica si el plan permite superar el cupo como adicional | | `precioDocumentoAdicionalPyg` | `integer \| null` | Precio unitario efectivo en PYG; `null` si no se permiten adicionales | | `adicionalesFacturables` | `integer` | Confirmados por encima del cupo que pueden facturarse | | `costoEstimadoPyg` | `integer` | Costo adicional estimado en PYG | `finPeriodo` es exclusivo: el ciclo siguiente comienza en ese instante. Las reservas no son consumo confirmado ni adicionales cobrados. `costoEstimadoPyg` es una estimación calculada con los confirmados adicionales y el precio efectivo; consultar el endpoint no ejecuta un cobro ni cambia el plan. Las emisiones en DEV y SANDBOX son ilimitadas: no consumen ni reservan cupo y no alteran estos contadores. El snapshot refleja la ocupación del ciclo de producción. Consultá también [Planes y Precios](/docs/plataforma/planes) y el manejo de [`document-quota-exceeded`](/docs/solucion-problemas/document-quota-exceeded). ### Errores [#errores] | Status | Descripción | | ------ | ---------------------------------------------- | | `401` | API key ausente, inválida o revocada | | `500` | Error interno al resolver el plan o el consumo | # Cancelar Documento (/docs/referencia/documentos-electronicos/cancelar) ## POST /api/v1/documento-electronico/:cdc/cancelar [#post-apiv1documento-electronicocdccancelar] Envía el evento de cancelación a SIFEN. Solo se pueden cancelar documentos registrados en SIFEN, o sea en estado `APROBADO` o `APROBADO_OBSERVACION`. Esta operación requiere DEV o PROD. En SANDBOX devuelve [`422 sandbox-operation-not-supported`](/docs/solucion-problemas/sandbox-operation-not-supported) sin crear ni enviar un evento. ### Autenticación [#autenticación] `Authorization: Bearer {api-key}` — requerido ### Idempotencia [#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](/docs/guias/idempotencia). ```http Idempotency-Key: 72f42d5e-366d-4f67-a9da-764a3f02cf55 ``` En cancelación, el reintento reutiliza el evento original. Si SIFEN responde `4003` porque el CDC ya tiene la cancelación registrada, Sifende lo conserva como éxito equivalente. ### Path parameters [#path-parameters] | Parámetro | Tipo | Descripción | | --------- | -------- | ---------------------------- | | `cdc` | `string` | CDC del documento a cancelar | ### Cuerpo de la solicitud [#cuerpo-de-la-solicitud] ```json { "motivo": "Error en datos del cliente" } ``` | Campo | Tipo | Req. | Descripción | | -------- | -------- | ---- | -------------------------------------- | | `motivo` | `string` | Sí | Motivo de la cancelación (texto libre) | El plazo es de 48 horas desde la aprobación para FE y 168 horas para NCE, NDE y NRE. ### Respuesta exitosa [#respuesta-exitosa] **Status:** `200 OK` Revisá `estadoEvento`: sólo `APROBADO` confirma la cancelación. SIFEN puede rechazar el evento y la API devolverlo con `estadoEvento: "RECHAZADO"` y HTTP `200`. `0600` representa la aprobación original. `4003` también produce `estadoEvento: APROBADO`: confirma que el mismo tipo de evento ya estaba registrado para el CDC, normalmente porque SIFEN aplicó un intento cuya respuesta se perdió. En ese éxito equivalente, `protocoloAutorizacion` puede ser `null`; `codigoRespuesta` y `mensajeRespuesta` conservan la evidencia `4003`. ### Errores [#errores] | Status | Tipo | Descripción | | ------ | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | | 400 | `evento-cancelacion-error` | El estado, el plazo o los datos del documento no permiten cancelar | | 400 | `validation-error` | `Idempotency-Key` vacía, repetida o con formato inválido | | 403 | `document-archived` | El período de acceso del plan actual finalizó; no se envía el evento. No aplica a una clave ya registrada | | 404 | `documento-electronico-not-found` | CDC no encontrado o documento cuya conservación física venció | | 409 | `evento-cancelacion-error` | Ya existe una cancelación activa o aprobada; consultá el evento | | 409 | `idempotency-in-progress` | La misma intención sigue en curso. Incluye `Retry-After: 2` | | 409 | `idempotency-outcome-unknown` | Resultado terminal indeterminado. No incluye `Retry-After` | | 409 | `idempotency-key-expired` | Venció el replay de 7 días; la clave permanece reservada | | 422 | [`sandbox-operation-not-supported`](/docs/solucion-problemas/sandbox-operation-not-supported) | La operación no está disponible en SANDBOX | | 422 | `idempotency-key-reused` | La clave ya corresponde a otro tipo de operación | | 503 | `idempotency-upstream-unknown` | SIFEN no confirmó el resultado. Incluye `Retry-After: 2`; reintentá con la misma clave | Un documento archivado responde el [Problem Detail `document-archived`](/docs/referencia/errores#documento-archivado) antes de enviar la cancelación, salvo que la clave ya esté registrada: en ese caso se recupera la cancelación original. Estado y KuDE aplican el mismo comportamiento. ### Ejemplos del ciclo idempotente [#ejemplos-del-ciclo-idempotente] #### Primera ejecución [#primera-ejecución] ```http POST /api/v1/documento-electronico/01800123451001001000000122026042710000000006/cancelar HTTP/1.1 Idempotency-Key: 72f42d5e-366d-4f67-a9da-764a3f02cf55 Content-Type: application/json { "motivo": "Error en datos del cliente" } HTTP/1.1 200 OK { "eventoSifenId": 91, "tipoEvento": "CANCELACION", "estadoEvento": "APROBADO", "cdc": "01800123451001001000000122026042710000000006", "protocoloAutorizacion": "123456789", "codigoRespuesta": "0600" } ``` #### Replay dentro de 7 días [#replay-dentro-de-7-días] La misma solicitud devuelve el `200` y body originales sin otro envío a SIFEN. ```http HTTP/1.1 200 OK { "eventoSifenId": 91, "tipoEvento": "CANCELACION", "estadoEvento": "APROBADO", "cdc": "01800123451001001000000122026042710000000006", "protocoloAutorizacion": "123456789", "codigoRespuesta": "0600" } ``` #### Mismatch de payload u operación [#mismatch-de-payload-u-operación] ```http HTTP/1.1 422 Unprocessable Entity Content-Type: application/problem+json { "type": "https://sifende.com.py/docs/solucion-problemas/idempotency-key-reused", "title": "Clave de idempotencia reutilizada", "status": 422, "detail": "La clave de idempotencia ya fue usada para otro tipo de operación" } ``` #### Primera ejecución todavía en curso [#primera-ejecución-todavía-en-curso] ```http HTTP/1.1 409 Conflict Retry-After: 2 Content-Type: application/problem+json { "type": "https://sifende.com.py/docs/solucion-problemas/idempotency-in-progress", "title": "Solicitud idempotente en proceso", "status": 409, "detail": "Ya existe una solicitud con esta clave en proceso; reintentá después del intervalo indicado" } ``` #### Timeout reintentable [#timeout-reintentable] ```http HTTP/1.1 503 Service Unavailable Retry-After: 2 Content-Type: application/problem+json { "type": "https://sifende.com.py/docs/solucion-problemas/idempotency-upstream-unknown", "title": "Resultado SIFEN no confirmado", "status": 503, "detail": "No se pudo confirmar el resultado en SIFEN; reintentá con la misma Idempotency-Key después del intervalo indicado" } ``` #### Éxito equivalente después del timeout [#éxito-equivalente-después-del-timeout] ```http HTTP/1.1 200 OK { "eventoSifenId": 91, "tipoEvento": "CANCELACION", "estadoEvento": "APROBADO", "cdc": "01800123451001001000000122026042710000000006", "protocoloAutorizacion": null, "codigoRespuesta": "4003", "mensajeRespuesta": "[4003] CDC ya se encuentra con el mismo evento solicitado" } ``` #### Replay expirado [#replay-expirado] ```http HTTP/1.1 409 Conflict Content-Type: application/problem+json { "type": "https://sifende.com.py/docs/solucion-problemas/idempotency-key-expired", "title": "Clave de idempotencia expirada", "status": 409, "detail": "El resultado asociado a la clave de idempotencia expiró y ya no puede reproducirse; la clave no puede reutilizarse" } ``` # Consultar Estado (/docs/referencia/documentos-electronicos/consultar-estado) ## GET /api/v1/documento-electronico/status/:cdc [#get-apiv1documento-electronicostatuscdc] Consultá el documento con su CDC de 44 dígitos y una API key del mismo contribuyente y ambiente. ```bash curl "https://api.sifende.com.py/api/v1/documento-electronico/status/$CDC" \ -H "Authorization: Bearer $SIFENDE_API_KEY" ``` ## Respuesta exitosa [#respuesta-exitosa] **Status:** `200 OK` ```json { "cdc": "01800123451001001000000122026042710000000006", "estado": "APROBADO", "ambiente": "DEV", "iTiDe": 1, "numeroDocumento": 1, "fechaCreacion": "2026-04-27T10:30:00", "protocoloAutorizacion": "01202604150000123456", "mensajeRechazo": null } ``` | Campo | Tipo | Descripción | | ----------------------- | ---------------- | -------------------------------------------------------------------------------------------- | | `cdc` | `string` | Identificador de 44 dígitos del documento | | `estado` | `string` | Estado de procesamiento | | `ambiente` | `string` | Ambiente en que se emitió el documento: `DEV`, `PROD` o `SANDBOX`. No cambia | | `iTiDe` | `integer` | Tipo de documento: 1 para FE, 5 para NCE, 6 para NDE y 7 para NRE | | `numeroDocumento` | `integer` | Número correlativo del documento | | `fechaCreacion` | `datetime` | Fecha y hora de creación, sin zona horaria | | `protocoloAutorizacion` | `string \| null` | Protocolo de SIFEN en DEV/PROD; en SANDBOX, `SBX-` seguido del CDC | | `mensajeRechazo` | `string \| null` | Rechazos u observaciones, en formato `[código] mensaje`; varias entradas se separan por `\|` | `numeroDocumento` es un número. El valor con formato `001-001-0000001` está en `numeroFormateado`, que devuelve la respuesta de emisión. En [SANDBOX](/docs/conceptos/ambientes#sandbox-de-sifende), la consulta puede pasar de `PENDIENTE` a `APROBADO` sin envío a SIFEN. El protocolo es `SBX-` seguido del CDC y no tiene validez fiscal. Los estados de envío y respuestas de SIFEN de esta tabla corresponden a DEV y PROD. ## Estados posibles [#estados-posibles] | Estado | Qué significa | Qué hacer | | ---------------------- | -------------------------------------------------------- | ------------------------------------------------------------------ | | `PENDIENTE` | Sifende recibió el documento y está preparando su envío | Seguí consultando | | `EN_LOTE` | En proceso de envío o a la espera del resultado de SIFEN | Seguí consultando | | `APROBADO` | SIFEN aceptó el documento | Detené las consultas; guardá el protocolo | | `APROBADO_OBSERVACION` | SIFEN aceptó el documento con observaciones | Detené las consultas y revisá `mensajeRechazo`; no lo reemitas | | `RECHAZADO` | SIFEN rechazó el documento | Detené las consultas y corregí el motivo antes de emitir uno nuevo | | `CANCELADO` | Se confirmó la cancelación de un documento aprobado | Detené las consultas | | `ERROR` | El envío falló de forma definitiva | Detené las consultas y revisá el panel; no lo reemitas | En `ERROR`, el documento no se reintenta solo. Pedí el reintento a [soporte](/docs/solucion-problemas/soporte) o seguí la [guía para reintentar el lote](/docs/panel/lotes). Al reintentarlo vuelve a `EN_LOTE` y podés retomar las consultas con el mismo CDC. Si después de varias horas sigue en `EN_LOTE`, puede pertenecer a un lote **Fallido**. Revisá **Historial de Lotes** en el detalle del documento y, si el lote está **Fallido**, seguí la [guía de reintento](/docs/panel/lotes). Conservá el mismo CDC. ## Errores [#errores] | Status | Tipo | Qué significa | | ------ | --------------------------------------------------------------------------------------------- | ---------------------------------------------- | | 401 | — | API key ausente o inválida | | 403 | [`document-archived`](/docs/solucion-problemas/document-archived) | Terminó el período de acceso del plan | | 404 | [`documento-electronico-not-found`](/docs/solucion-problemas/documento-electronico-not-found) | El documento no está disponible para esa clave | Para automatizar la espera, consultá [Polling de resultados](/docs/guias/polling-resultados). # Descargar KuDE (/docs/referencia/documentos-electronicos/descargar-kude) El KuDE de SANDBOX lleva el rótulo **SANDBOX — SIN VALIDEZ FISCAL**. Descargalo con una clave del mismo contribuyente y ambiente; el CDC y la ruta de descarga se usan igual que en los otros ambientes. ## GET /api/v1/documento-electronico/:cdc/kude [#get-apiv1documento-electronicocdckude] Retorna el KuDE (Kuatia Ñe'ẽ Mba'eporu — comprobante electrónico) en formato PDF binario cuando ya existe una copia legible. Si falta el PDF, la llamada inicial puede solicitar su preparación y responder `202 Accepted`. ### Autenticación [#autenticación] `Authorization: Bearer {api-key}` — requerido ### Path parameters [#path-parameters] | Parámetro | Tipo | Descripción | | --------- | -------- | -------------------------- | | `cdc` | `string` | CDC del documento aprobado | ### Query parameters [#query-parameters] | Parámetro | Tipo | Default | Descripción | | -------------- | --------- | ------- | -------------------------------------------------------- | | `soloConsulta` | `boolean` | `false` | Si es `true`, consulta el estado de preparación del PDF. | ### Respuestas [#respuestas] #### 200 OK [#200-ok] **Content-Type:** `application/pdf` El body es el PDF binario del KuDE. Conserva `Content-Disposition` y `Content-Length`. #### 202 Accepted [#202-accepted] **Content-Type:** `application/json` La preparación del PDF está pendiente. Esta respuesta **no es un PDF** y no debe guardarse como archivo. ```http HTTP/1.1 202 Accepted Content-Type: application/json Location: /api/v1/documento-electronico/01800123451001001000000122026042710000000006/kude?soloConsulta=true Retry-After: 5 Cache-Control: no-store ``` ```json { "estado": "PENDIENTE", "url": null } ``` Seguí exactamente el `Location` recibido; consultar no acelera la preparación. `Retry-After: 5` indica el intervalo mínimo recomendado para volver a consultar. Si sigue en `202` después de 2 minutos, repetí una vez la descarga sin `soloConsulta`: el `Location` sólo consulta y no vuelve a pedir la preparación. Si después de otros 2 minutos sigue pendiente, dejá de consultar y contactá a soporte con el CDC. ### Errores [#errores] | Status | Tipo | Descripción | | ------ | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | 403 | `document-archived` | El período de acceso del plan actual finalizó | | 403 | — (sin Problem Details) | La NRE no está en `APROBADO` ni `APROBADO_OBSERVACION`. Consultá su estado y esperá la aprobación sólo si sigue en proceso | | 404 | `documento-electronico-not-found` | Documento no encontrado o no accesible para esta clave | | 500 | `kude-generation-error` | Error técnico interno al obtener o preparar el KuDE | | 501 | `kude-not-supported` | El tipo no admite KuDE; los tipos disponibles son FE, NCE, NDE y NRE | | 503 | `kude-unavailable` | No se pudo obtener el PDF en este intento; ver [`kude-unavailable`](/docs/solucion-problemas/kude-unavailable) | Los errores técnicos de KuDE se informan como `500` o `503` según la causa. No se clasifican como `422`, porque no son problemas semánticos del documento enviado. Un documento archivado responde el [Problem Detail `document-archived`](/docs/referencia/errores#documento-archivado) y no entrega el PDF. Estado y cancelación aplican el mismo comportamiento. ### Ejemplo — polling seguro y guardar sólo el 200 [#ejemplo--polling-seguro-y-guardar-sólo-el-200] ```typescript type KuDePendiente = { estado: 'PENDIENTE'; url: null; }; type ProblemDetail = { type: string; title: string; status: number; detail: string; traceId?: string; estado?: 'FALLIDO'; }; async function descargarKuDE(cdc: string): Promise { const urlInicial = `https://api.sifende.com.py/api/v1/documento-electronico/${cdc}/kude`; let url = urlInicial; let limite = Date.now() + 2 * 60_000; let volvioAPedir = false; for (;;) { const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.SIFENDE_API_KEY}` }, }); if (res.status === 200 && res.headers.get('content-type')?.includes('application/pdf')) { return new Uint8Array(await res.arrayBuffer()); } if (res.status === 202) { const location = res.headers.get('location'); if (!location) throw new Error('KuDE pendiente sin Location'); await res.json() as KuDePendiente; await new Promise(resolve => setTimeout(resolve, Number(res.headers.get('retry-after') ?? '5') * 1000)); if (Date.now() < limite) { url = new URL(location, url).toString(); } else if (!volvioAPedir) { volvioAPedir = true; url = urlInicial; limite = Date.now() + 2 * 60_000; } else { throw new Error('KuDE pendiente por más de 4 minutos; contactá a soporte'); } continue; } const problem = await res.json() as ProblemDetail; throw new Error(`No se pudo descargar KuDE (${problem.status}): ${problem.type}`); } } ``` # Emitir Documento Electrónico (/docs/referencia/documentos-electronicos/emitir) ## POST /api/v1/documento-electronico [#post-apiv1documento-electronico] Recibe un documento electrónico para firmarlo y enviarlo a SIFEN. La respuesta es **asíncrona**: la API retorna inmediatamente con `estado: PENDIENTE` y un CDC ya calculado. La respuesta de SIFEN llega después. Usá [`GET /status/:cdc`](/docs/referencia/documentos-electronicos/consultar-estado) o el `statusUrl` retornado para hacer polling del estado final. Con una clave `sk_sandbox_`, el documento se procesa sin envío a SIFEN. La respuesta inicial sigue siendo `202` con `PENDIENTE`; consultá el [comportamiento de SANDBOX](/docs/conceptos/ambientes#sandbox-de-sifende). ### Autenticación [#autenticación] `Authorization: Bearer {api-key}` — requerido ### Idempotencia [#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](/docs/guias/idempotencia). ```http Idempotency-Key: 7d444840-9dc0-11d1-b245-5ffdce74fad2 ``` En emisión, el replay devuelve el mismo `202`, documento, CDC, correlativo y `Location`; nunca reserva otro número. ### Cuerpo de la solicitud [#cuerpo-de-la-solicitud] El campo `tipoDocumento` determina el schema completo de la solicitud. Ver los modelos: * [Factura Electrónica](/docs/referencia/modelos/factura-electronica) * [Autofactura Electrónica](/docs/referencia/modelos/autofactura) * [Nota de Crédito Electrónica](/docs/referencia/modelos/nota-credito) * [Nota de Débito Electrónica](/docs/referencia/modelos/nota-debito) * [Nota de Remisión Electrónica](/docs/referencia/modelos/nota-remision) ### Campos de facturas y notas de crédito o débito [#campos-de-facturas-y-notas-de-crédito-o-débito] La NRE tiene un contrato propio de carga y transporte, sin importes comerciales. Usá sus [tablas de campos](/docs/referencia/modelos/nota-remision). La AFE también tiene un contrato propio: informa `vendedor`, `lugarOperacion` y `constancia`, y no admite `receptor`. Usá sus [tablas de campos](/docs/referencia/modelos/autofactura). | Campo | Tipo | Req. | Descripción | | --------------------------- | ---------- | ---- | ------------------------------------------------------------------------------------------------------------------------ | | `tipoDocumento` | `enum` | Sí | Tipo de documento — ver la lista de modelos arriba | | `fechaEmision` | `datetime` | No | Fecha y hora de Paraguay (`YYYY-MM-DDTHH:mm:ss`). Si se omite, se usa la fecha y hora en que Sifende recibe la solicitud | | `tipoEmision` | `enum` | No | Sólo `NORMAL`, valor por defecto. SIFEN todavía no habilita la emisión en 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](#campos-del-receptor) | | `items` | `array` | Sí | Lista de ítems — ver [Modelo Ítem](/docs/referencia/modelos/item) | | `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, de 1 a 3000 caracteres en una sola línea | ### Campos condicionales según el tipo de documento [#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` o `AUTOFACTURA_ELECTRONICA` | `CONTADO` o `CREDITO`. En AFE sólo se admite `CONTADO`, que es el valor por defecto. No aplica a NCE ni NDE | | `condicionPago` | `object` | `condicionOperacion` es `CONTADO` o `CREDITO`, salvo que uses `pagos`/`credito` | Medio de pago o modalidad de crédito — ver [Modelo Condición de Pago](/docs/referencia/modelos/condicion-pago) | | `pagos` / `credito` | `array` / `object` | Alternativa de la FE a `condicionPago` | Varios medios de pago y crédito con entrega — ver [Forma completa](/docs/referencia/modelos/condicion-pago#forma-completa-pagos-y-credito) | | `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 — ver [Modelo Documento Asociado](/docs/referencia/modelos/documento-asociado). La FE usa la lista `documentosAsociados` | ### Campos del receptor [#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](/docs/referencia/modelos/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`. 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](/docs/guias/receptor-b2b-b2c) cubre cada caso con su ejemplo. ### Respuesta exitosa [#respuesta-exitosa] **Status:** `202 Accepted` La respuesta incluye el CDC, el ambiente efectivo y URLs auxiliares para seguimiento. ```json { "id": "550e8400-e29b-41d4-a716-446655440000", "cdc": "01800123451001001000000122026042710000000006", "estado": "PENDIENTE", "ambiente": "DEV", "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 [#headers-de-respuesta] | Header | Valor | Descripción | | ---------- | ------------- | --------------------------------------------------- | | `Location` | `{statusUrl}` | URL absoluta para consultar el estado del documento | #### Campos de la respuesta [#campos-de-la-respuesta] | 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 | | `ambiente` | `string` | Ambiente de la emisión: `DEV`, `PROD` o `SANDBOX`, determinado por la API key. No cambia para este documento | | `tipoDocumento` | `enum` | Tipo del documento creado (eco de la solicitud) | | `iTiDe` | `integer` | Código numérico SIFEN del tipo (1=FE, 4=AFE, 5=NCE, 6=NDE, 7=NRE) | | `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 en estado `APROBADO` o `APROBADO_OBSERVACION`. En SANDBOX, el PDF indica que no tiene validez fiscal | El estado inicial es siempre `PENDIENTE`. Hacé polling a `statusUrl` o `GET /status/:cdc` cada 5 segundos, durante un máximo de 5 minutos, hasta llegar a un estado terminal: `APROBADO`, `APROBADO_OBSERVACION`, `RECHAZADO`, `CANCELADO` o `ERROR`. `APROBADO_OBSERVACION` es un resultado exitoso: el DE quedó registrado, con observaciones en `mensajeRechazo`. Ver [Polling de resultados](/docs/guias/polling-resultados). ### Errores comunes [#errores-comunes] | Status | Tipo | Cuándo ocurre | Acción | | ------ | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------- | | 400 | `validation-error` | Campos inválidos, faltantes o ramas de pago incompatibles; en `CONTADO`, pagos que no cubren exactamente el total | Corregí las rutas incluidas en `errores` y reenviá la solicitud | | 400 | `validation-error` | En `CREDITO`: falta `condicionCredito`, se mezclan `PLAZO`/`CUOTA`, no coincide `cuotas` con `detalleCuotas`, las cuotas no suman el saldo financiado o la entrega es inválida | Ajustá `condicionPago` según la [referencia](/docs/referencia/modelos/condicion-pago) | | 400 | `invalid-enum-value` | Valor de enumeración no reconocido | Usá un valor publicado por `GET /api/v1/public/enums` | | 422 | `configuracion-incompleta` | Falta el timbrado u otro dato del emisor | Completá el dato indicado por `campo` | | 404 | `certificate-not-found` | Falta certificado activo o CSC del ambiente | Revisá ambos desde el panel | | 422 | `documento-electronico-generation-error` | El documento no cumple una regla fiscal; revisá el `detail` | Revisá el detalle y contactá soporte si la solicitud 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 [#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-b2c--consumidor-final-identificado] ```bash 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-04-15T10:30:00", "tipoEmision": "NORMAL", "numeroEstablecimiento": 1, "puntoExpedicion": 1, "tipoTransaccion": "VENTA_MERCADERIA", "monedaOperacion": "PYG", "receptor": { "tipoContribuyente": "NO_CONTRIBUYENTE", "tipoOperacion": "B2C", "tipoDocumento": "CEDULA_PARAGUAYA", "numeroDocumento": "1234567", "nombreRazonSocial": "Juan Pérez" }, "condicionOperacion": "CONTADO", "condicionPago": { "tipo": "CONTADO", "tipoPago": "EFECTIVO", "monedaPago": "PYG", "montoPago": 110000 }, "items": [ { "codigo": "PROD-001", "descripcion": "Resma de papel A4 75g", "cantidad": 10, "unidadMedida": "UNI", "precioUnitario": 11000, "afectacionTributaria": "GRAVADO", "tasaIVA": 10 } ] }' ``` ```typescript const response = await fetch( 'https://api.sifende.com.py/api/v1/documento-electronico', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.SIFENDE_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ tipoDocumento: 'FACTURA_ELECTRONICA', fechaEmision: '2026-04-15T10:30:00', tipoEmision: 'NORMAL', numeroEstablecimiento: 1, puntoExpedicion: 1, tipoTransaccion: 'VENTA_MERCADERIA', monedaOperacion: 'PYG', receptor: { tipoContribuyente: 'NO_CONTRIBUYENTE', tipoOperacion: 'B2C', tipoDocumento: 'CEDULA_PARAGUAYA', numeroDocumento: '1234567', nombreRazonSocial: 'Juan Pérez', }, condicionOperacion: 'CONTADO', condicionPago: { tipo: 'CONTADO', tipoPago: 'EFECTIVO', monedaPago: 'PYG', montoPago: 110000, }, items: [ { codigo: 'PROD-001', descripcion: 'Resma de papel A4 75g', cantidad: 10, unidadMedida: 'UNI', precioUnitario: 11000, afectacionTributaria: 'GRAVADO', tasaIVA: 10, }, ], }), } ); const data = await response.json(); // data.cdc → "01800123451001001000000122026042710000000006" // data.estado → "PENDIENTE" // data.statusUrl → "https://api.sifende.com.py/api/v1/documento-electronico/status/..." ``` ```python import requests, os response = requests.post( 'https://api.sifende.com.py/api/v1/documento-electronico', headers={ 'Authorization': f'Bearer {os.environ["SIFENDE_API_KEY"]}', 'Content-Type': 'application/json', }, json={ 'tipoDocumento': 'FACTURA_ELECTRONICA', 'fechaEmision': '2026-04-15T10:30:00', 'tipoEmision': 'NORMAL', 'numeroEstablecimiento': 1, 'puntoExpedicion': 1, 'tipoTransaccion': 'VENTA_MERCADERIA', 'monedaOperacion': 'PYG', 'receptor': { 'tipoContribuyente': 'NO_CONTRIBUYENTE', 'tipoOperacion': 'B2C', 'tipoDocumento': 'CEDULA_PARAGUAYA', 'numeroDocumento': '1234567', 'nombreRazonSocial': 'Juan Pérez', }, 'condicionOperacion': 'CONTADO', 'condicionPago': { 'tipo': 'CONTADO', 'tipoPago': 'EFECTIVO', 'monedaPago': 'PYG', 'montoPago': 110000, }, 'items': [{ 'codigo': 'PROD-001', 'descripcion': 'Resma de papel A4 75g', 'cantidad': 10, 'unidadMedida': 'UNI', 'precioUnitario': 11000, 'afectacionTributaria': 'GRAVADO', 'tasaIVA': 10, }], } ) data = response.json() # data['cdc'] → "01800123451001001000000122026042710000000006" # data['estado'] → "PENDIENTE" # data['statusUrl'] → "https://api.sifende.com.py/api/v1/documento-electronico/status/..." ``` #### Factura a crédito por cuotas [#factura-a-crédito-por-cuotas] Ejemplo de solicitud: ```bash 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": "0", "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`. #### Factura B2B — receptor contribuyente con RUC [#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. ```bash 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-04-15T10:30:00", "tipoEmision": "NORMAL", "numeroEstablecimiento": 1, "puntoExpedicion": 1, "tipoTransaccion": "VENTA_MERCADERIA", "monedaOperacion": "PYG", "receptor": { "tipoContribuyente": "CONTRIBUYENTE", "tipoOperacion": "B2B", "tipoContribuyenteReceptor": "PERSONA_JURIDICA", "numeroDocumento": "80012345", "digitoVerificador": "0", "nombreRazonSocial": "Comercial Guaraní S.A.", "direccion": "Av. Mariscal López 4567, Asunción" }, "condicionOperacion": "CONTADO", "condicionPago": { "tipo": "CONTADO", "tipoPago": "TRANSFERENCIA", "monedaPago": "PYG", "montoPago": 1100000 }, "items": [ { "codigo": "PROD-001", "descripcion": "Resma de papel A4 75g", "cantidad": 100, "unidadMedida": "UNI", "precioUnitario": 11000, "afectacionTributaria": "GRAVADO", "tasaIVA": 10 } ] }' ``` ```typescript const response = await fetch( 'https://api.sifende.com.py/api/v1/documento-electronico', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.SIFENDE_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ tipoDocumento: 'FACTURA_ELECTRONICA', fechaEmision: '2026-04-15T10:30:00', tipoEmision: 'NORMAL', numeroEstablecimiento: 1, puntoExpedicion: 1, tipoTransaccion: 'VENTA_MERCADERIA', monedaOperacion: 'PYG', receptor: { tipoContribuyente: 'CONTRIBUYENTE', tipoOperacion: 'B2B', tipoContribuyenteReceptor: 'PERSONA_JURIDICA', numeroDocumento: '80012345', digitoVerificador: '1', nombreRazonSocial: 'Comercial Guaraní S.A.', direccion: 'Av. Mariscal López 4567, Asunción', }, condicionOperacion: 'CONTADO', condicionPago: { tipo: 'CONTADO', tipoPago: 'TRANSFERENCIA', monedaPago: 'PYG', montoPago: 1100000, }, items: [ { codigo: 'PROD-001', descripcion: 'Resma de papel A4 75g', cantidad: 100, unidadMedida: 'UNI', precioUnitario: 11000, afectacionTributaria: 'GRAVADO', tasaIVA: 10, }, ], }), } ); const data = await response.json(); // data.cdc → "01800123451001001000000122026042710000000006" // data.estado → "PENDIENTE" ``` ```python import requests, os response = requests.post( 'https://api.sifende.com.py/api/v1/documento-electronico', headers={ 'Authorization': f'Bearer {os.environ["SIFENDE_API_KEY"]}', 'Content-Type': 'application/json', }, json={ 'tipoDocumento': 'FACTURA_ELECTRONICA', 'fechaEmision': '2026-04-15T10:30:00', 'tipoEmision': 'NORMAL', 'numeroEstablecimiento': 1, 'puntoExpedicion': 1, 'tipoTransaccion': 'VENTA_MERCADERIA', 'monedaOperacion': 'PYG', 'receptor': { 'tipoContribuyente': 'CONTRIBUYENTE', 'tipoOperacion': 'B2B', 'tipoContribuyenteReceptor': 'PERSONA_JURIDICA', 'numeroDocumento': '80012345', 'digitoVerificador': '1', 'nombreRazonSocial': 'Comercial Guaraní S.A.', 'direccion': 'Av. Mariscal López 4567, Asunción', }, 'condicionOperacion': 'CONTADO', 'condicionPago': { 'tipo': 'CONTADO', 'tipoPago': 'TRANSFERENCIA', 'monedaPago': 'PYG', 'montoPago': 1100000, }, 'items': [{ 'codigo': 'PROD-001', 'descripcion': 'Resma de papel A4 75g', 'cantidad': 100, 'unidadMedida': 'UNI', 'precioUnitario': 11000, 'afectacionTributaria': 'GRAVADO', 'tasaIVA': 10, }], } ) data = response.json() # data['cdc'] → "01800123451001001000000122026042710000000006" # data['estado'] → "PENDIENTE" ``` ## Próximos pasos [#próximos-pasos] * [Receptor B2B y B2C](/docs/guias/receptor-b2b-b2c): cada caso de receptor con su ejemplo y los rechazos asociados. * [Consultar el estado del documento](/docs/referencia/documentos-electronicos/consultar-estado) * [Modelo Receptor](/docs/referencia/modelos/receptor): schema completo del bloque `receptor`. # Documentos Electrónicos (/docs/referencia/documentos-electronicos) ## Endpoint único y polimórfico [#endpoint-único-y-polimórfico] **Diseño importante:** Sifende usa **un solo endpoint** para todos los tipos de documento electrónico. El campo `tipoDocumento` en el body determina qué tipo emitís. No hay endpoints separados para facturas, notas de crédito, etc. ``` POST /api/v1/documento-electronico ``` | `tipoDocumento` | Tipo de documento | Estado | | ------------------------------ | ------------------------ | ------------ | | `FACTURA_ELECTRONICA` | Factura Electrónica (FE) | ✅ Disponible | | `NOTA_DE_CREDITO_ELECTRONICA` | Nota de Crédito (NCE) | ✅ Disponible | | `NOTA_DE_DEBITO_ELECTRONICA` | Nota de Débito (NDE) | ✅ Disponible | | `AUTOFACTURA_ELECTRONICA` | Autofactura (AFE) | ✅ Disponible | | `NOTA_DE_REMISION_ELECTRONICA` | Nota de Remisión (NRE) | ✅ Disponible | Cada tipo tiene su propio schema de la solicitud. Ver [Modelos de Datos](/docs/referencia/modelos). ## Autenticación [#autenticación] Todos los endpoints de esta sección requieren API key: ``` Authorization: Bearer {tu-api-key} ``` ## URL base [#url-base] ``` https://api.sifende.com.py/api/v1/documento-electronico ``` ## Endpoints [#endpoints] | Método | Path | Descripción | | ------ | ---------------- | ------------------------------------------------------------------------------------- | | `POST` | `/` | [Emitir un documento electrónico](/docs/referencia/documentos-electronicos/emitir) | | `GET` | `/status/:cdc` | [Consultar estado por CDC](/docs/referencia/documentos-electronicos/consultar-estado) | | `GET` | `/:cdc/kude` | [Descargar KuDE PDF](/docs/referencia/documentos-electronicos/descargar-kude) | | `POST` | `/:cdc/cancelar` | [Cancelar un documento](/docs/referencia/documentos-electronicos/cancelar) | | `POST` | `/:cdc/nominar` | [Nominar una factura innominada](/docs/referencia/documentos-electronicos/nominar) | | `POST` | `/inutilizar` | [Inutilizar numeración](/docs/referencia/documentos-electronicos/inutilizar) | ## ¿Tu documento fue rechazado? [#tu-documento-fue-rechazado] Si emitís un documento y queda en estado `RECHAZADO`, la mayoría de los rechazos durante el onboarding se deben a que un dato no coincide con lo que **SET** tiene registrado para tu RUC (timbrado, actividades económicas, CSC, establecimiento / punto). Mirá [Rechazos comunes de SIFEN](/docs/solucion-problemas/rechazos-comunes) para el diagnóstico paso a paso, o la [tabla completa de códigos](/docs/solucion-problemas/rechazos-sifen). # Inutilizar Numeración (/docs/referencia/documentos-electronicos/inutilizar) ## POST /api/v1/documento-electronico/inutilizar [#post-apiv1documento-electronicoinutilizar] Envía el evento de inutilización a SIFEN para un rango de números de documento no emitidos. Esta operación requiere DEV o PROD. En SANDBOX devuelve [`422 sandbox-operation-not-supported`](/docs/solucion-problemas/sandbox-operation-not-supported) sin crear ni enviar un evento. ### Autenticación [#autenticación] `Authorization: Bearer {api-key}` — requerido ### Idempotencia [#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](/docs/guias/idempotencia). ```http Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000 ``` En inutilización, `4066` deja el evento `INDETERMINADA` y devuelve `409 idempotency-outcome-unknown`. No reenvíes el rango ni uses otra clave. ### Cuerpo de la solicitud [#cuerpo-de-la-solicitud] ```json { "numeroTimbrado": 12557896, "establecimiento": "001", "puntoExpedicion": "001", "numeroInicio": "0000025", "numeroFin": "0000030", "tipoDocumento": 1, "motivo": "Números no utilizados por error de sistema" } ``` | Campo | Tipo | Req. | Descripción | | ----------------- | --------- | ---- | ------------------------------------------------- | | `numeroTimbrado` | `integer` | Sí | Número del timbrado | | `establecimiento` | `string` | Sí | Código de establecimiento de 3 caracteres | | `puntoExpedicion` | `string` | Sí | Código de punto de expedición de 3 caracteres | | `numeroInicio` | `string` | Sí | Primer número del rango, de 1 a 7 caracteres | | `numeroFin` | `string` | Sí | Último número del rango, de 1 a 7 caracteres | | `tipoDocumento` | `integer` | Sí | Código SIFEN del tipo de documento | | `motivo` | `string` | Sí | Motivo de la inutilización, de 5 a 500 caracteres | | `serie` | `string` | No | Serie de hasta 2 caracteres | `numeroFin` debe ser mayor que `numeroInicio`; la diferencia no puede superar 1.000. ### Respuesta exitosa [#respuesta-exitosa] **Status:** `200 OK` La respuesta contiene el evento. Revisá `estadoEvento`: `APROBADO` confirma la inutilización; `RECHAZADO` indica que SIFEN no la aceptó. Conservá también `codigoRespuesta` y `mensajeRespuesta`. ### Errores [#errores] | Status | Tipo | Descripción | | ------ | --------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | | 400 | `evento-inutilizacion-error` | Rango, timbrado o tipo de documento inválido | | 400 | `validation-error` | `Idempotency-Key` vacía, repetida o con formato inválido | | 409 | `evento-inutilizacion-error` | Ya existe una inutilización activa para el mismo rango | | 409 | `idempotency-in-progress` | La misma intención sigue en curso. Incluye `Retry-After: 2` | | 409 | `idempotency-outcome-unknown` | `4066` u otro resultado terminal indeterminado. No incluye `Retry-After` | | 409 | `idempotency-key-expired` | Venció el replay de 7 días; la clave permanece reservada | | 422 | [`sandbox-operation-not-supported`](/docs/solucion-problemas/sandbox-operation-not-supported) | La operación no está disponible en SANDBOX | | 422 | `idempotency-key-reused` | La clave ya corresponde a otro tipo de operación | | 503 | `idempotency-upstream-unknown` | SIFEN no confirmó el resultado. Incluye `Retry-After: 2`; reintentá con la misma clave | ### Ejemplos del ciclo idempotente [#ejemplos-del-ciclo-idempotente] #### Primera ejecución [#primera-ejecución] ```http POST /api/v1/documento-electronico/inutilizar HTTP/1.1 Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000 Content-Type: application/json { "numeroTimbrado": 12557896, "establecimiento": "001", "puntoExpedicion": "001", "numeroInicio": "0000025", "numeroFin": "0000030", "tipoDocumento": 1, "motivo": "Números no utilizados por error de sistema" } HTTP/1.1 200 OK { "eventoSifenId": 92, "tipoEvento": "INUTILIZACION", "estadoEvento": "APROBADO", "numeroInicio": "0000025", "numeroFin": "0000030", "protocoloAutorizacion": "987654321", "codigoRespuesta": "0600" } ``` #### Replay dentro de 7 días [#replay-dentro-de-7-días] La misma solicitud devuelve el `200` y body originales sin otro envío a SIFEN. ```http HTTP/1.1 200 OK { "eventoSifenId": 92, "tipoEvento": "INUTILIZACION", "estadoEvento": "APROBADO", "numeroInicio": "0000025", "numeroFin": "0000030", "protocoloAutorizacion": "987654321", "codigoRespuesta": "0600" } ``` #### Mismatch de payload u operación [#mismatch-de-payload-u-operación] ```http HTTP/1.1 422 Unprocessable Entity Content-Type: application/problem+json { "type": "https://sifende.com.py/docs/solucion-problemas/idempotency-key-reused", "title": "Clave de idempotencia reutilizada", "status": 422, "detail": "La clave de idempotencia ya fue usada para otro tipo de operación" } ``` #### Primera ejecución todavía en curso [#primera-ejecución-todavía-en-curso] ```http HTTP/1.1 409 Conflict Retry-After: 2 Content-Type: application/problem+json { "type": "https://sifende.com.py/docs/solucion-problemas/idempotency-in-progress", "title": "Solicitud idempotente en proceso", "status": 409, "detail": "Ya existe una solicitud con esta clave en proceso; reintentá después del intervalo indicado" } ``` #### Timeout reintentable [#timeout-reintentable] ```http HTTP/1.1 503 Service Unavailable Retry-After: 2 Content-Type: application/problem+json { "type": "https://sifende.com.py/docs/solucion-problemas/idempotency-upstream-unknown", "title": "Resultado SIFEN no confirmado", "status": 503, "detail": "No se pudo confirmar el resultado en SIFEN; reintentá con la misma Idempotency-Key después del intervalo indicado" } ``` #### `4066` indeterminado terminal [#4066-indeterminado-terminal] ```http HTTP/1.1 409 Conflict Content-Type: application/problem+json { "type": "https://sifende.com.py/docs/solucion-problemas/idempotency-outcome-unknown", "title": "Resultado idempotente indeterminado", "status": 409, "detail": "El resultado de la operación es indeterminado; no vuelvas a enviar la operación" } ``` El evento asociado queda con `estadoEvento: INDETERMINADA`, `codigoRespuesta: "4066"` y el mensaje original de SIFEN para auditoría. No existe replay exitoso ni reconciliación por consulta. #### Replay expirado [#replay-expirado] ```http HTTP/1.1 409 Conflict Content-Type: application/problem+json { "type": "https://sifende.com.py/docs/solucion-problemas/idempotency-key-expired", "title": "Clave de idempotencia expirada", "status": 409, "detail": "El resultado asociado a la clave de idempotencia expiró y ya no puede reproducirse; la clave no puede reutilizarse" } ``` # Nominar una factura (/docs/referencia/documentos-electronicos/nominar) ## POST /api/v1/documento-electronico/:cdc/nominar [#post-apiv1documento-electronicocdcnominar] Identifica al receptor de una FE originalmente innominada mediante un evento de nominación. Requiere una factura en estado `APROBADO` o `APROBADO_OBSERVACION`, con receptor original no contribuyente, `INNOMINADO` y número de documento `"0"`. La operación es síncrona y está disponible en DEV y PROD. SANDBOX devuelve [`422 sandbox-operation-not-supported`](/docs/solucion-problemas/sandbox-operation-not-supported), sin registrar ni enviar un evento. La nominación no modifica el CDC, XML firmado ni KuDE originales y no consume numeración ni cupo de emisión. ## Headers y CDC [#headers-y-cdc] | Dato | Requerido | Descripción | | ----------------- | --------- | ------------------------------------------------------------------------------------------------------------- | | `Authorization` | Sí | `Bearer {api-key}` del contribuyente y ambiente de la factura | | `Content-Type` | Sí | `application/json` | | `Idempotency-Key` | No | Clave estable para recuperar la respuesta de la misma intención; ver [idempotencia](/docs/guias/idempotencia) | | `cdc` (ruta) | Sí | CDC de la FE: 44 dígitos, comenzando con `01` | ## Cuerpo de la solicitud [#cuerpo-de-la-solicitud] | Campo | Tipo | Requerido | Descripción | | ---------- | -------- | --------- | ------------------------------------------------------- | | `motivo` | `string` | Sí | De 5 a 500 caracteres, no compuesto sólo por espacios | | `receptor` | `object` | Sí | Identificación del receptor según las reglas siguientes | ### Receptor de la nominación [#receptor-de-la-nominación] Este objeto tiene nombres distintos al receptor de emisión: usa `naturaleza`, `ruc`, `tipoContribuyente` y `codigoCiudad`. | Campo | Tipo | Requerido | Descripción | | -------------------------- | --------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | | `naturaleza` | `enum` | Sí | `CONTRIBUYENTE` o `NO_CONTRIBUYENTE` | | `tipoOperacion` | `enum` | Sí | `B2B`, `B2C` o `B2F`; no admite B2G | | `pais` | `enum` | Sí | Código del país; no tiene valor por defecto | | `nombreRazonSocial` | `string` | Sí | De 4 a 255 caracteres, no vacío | | `tipoContribuyente` | `enum` | Para B2B | `PERSONA_FISICA` o `PERSONA_JURIDICA` | | `ruc` | `string` | Para B2B | De 3 a 8 dígitos, sin DV | | `digitoVerificador` | `string` | Para B2B | Un dígito; debe corresponder al RUC | | `tipoDocumento` | `enum` | Para B2C/B2F | `CEDULA_PARAGUAYA`, `PASAPORTE`, `CEDULA_EXTRANJERA`, `CARNET_DE_RESIDENCIA`, `TARJETA_DIPLOMATICA` u `OTRO`; no admite `INNOMINADO` | | `numeroDocumento` | `string` | Para B2C/B2F | De 1 a 20 caracteres: letras ASCII, dígitos o guion | | `descripcionTipoDocumento` | `string` | Sólo para `OTRO` | Obligatoria con `OTRO`, de 9 a 41 caracteres después de quitar espacios de los extremos; se omite para otros tipos | | `direccion` | `string` | Para B2F | Hasta 255 caracteres; opcional para B2B/B2C | | `numeroCasa` | `integer` | Si hay dirección | De 0 a 999999; obligatorio para B2F | | `departamento` | `enum` | Si hay dirección paraguaya | Valor del catálogo `departamento`; no se admite en B2F | | `codigoDistrito` | `integer` | No | Código positivo del distrito, compatible con departamento y ciudad; no se admite en B2F | | `codigoCiudad` | `integer` | Si hay dirección paraguaya | Código positivo de ciudad del departamento y, si se informa, del distrito; no se admite en B2F | | `nombreFantasia` | `string` | No | De 4 a 255 caracteres | | `telefono` | `string` | No | De 6 a 15 caracteres | | `celular` | `string` | No | De 10 a 20 caracteres | | `email` | `string` | No | Dirección de correo válida | | `codigoCliente` | `string` | No | De 3 a 15 caracteres | * **B2B:** exige `naturaleza = CONTRIBUYENTE` y `pais = PRY`. Omití `tipoDocumento`, `numeroDocumento` y `descripcionTipoDocumento`. * **B2C:** exige `naturaleza = NO_CONTRIBUYENTE` y `pais = PRY`. * **B2F:** exige `naturaleza = NO_CONTRIBUYENTE`, país distinto de `PRY`, dirección y número de casa. Omití las divisiones territoriales paraguayas. * **B2C/B2F:** omití `tipoContribuyente`, `ruc` y `digitoVerificador`. Para B2B/B2C, si informás dirección, también son obligatorios número de casa, departamento y ciudad. Sin dirección, omití el número de casa y las divisiones territoriales. Consultá los [catálogos de enumeraciones](/docs/referencia/catalogos/enumeraciones) y [geografía](/docs/referencia/catalogos/geografia). ### Ejemplo B2C [#ejemplo-b2c] ```json { "motivo": "Identificación del cliente a su solicitud", "receptor": { "naturaleza": "NO_CONTRIBUYENTE", "tipoOperacion": "B2C", "pais": "PRY", "tipoDocumento": "CEDULA_PARAGUAYA", "numeroDocumento": "1234567", "nombreRazonSocial": "Juan Pérez" } } ``` ## Respuesta [#respuesta] **HTTP `200`** devuelve directamente el objeto del evento, sin envoltorio `data`. Revisá `estadoEvento`: `APROBADO` confirma la nominación; `RECHAZADO` indica que SIFEN rechazó el evento aunque el HTTP sea `200`. | Campo | Descripción | | ------------------------------------------------------------ | ----------------------------------------------------------- | | `eventoSifenId`, `documentoElectronicoId`, `contribuyenteId` | Identificadores del evento, documento y contribuyente | | `ambiente` | Ambiente de la operación | | `tipoEvento` | `NOMINACION` | | `estadoEvento` | `APROBADO` o `RECHAZADO` en una respuesta confirmada | | `cdc`, `motivo` | Documento y motivo de la nominación | | `protocoloAutorizacion` | Protocolo comunicado por SIFEN | | `codigoRespuesta` | Primer código de respuesta de SIFEN | | `mensajeRespuesta` | Mensajes con formato `[código] mensaje`, separados por `\|` | | `fechaCreacion`, `fechaProcesamiento` | Fechas del evento | Sólo una nominación `APROBADO` aporta el receptor efectivo para la precarga de NCE/NDE en el panel. ## Resultado incierto y reintentos [#resultado-incierto-y-reintentos] Si SIFEN no confirma el resultado, la API conserva el evento como `ENVIADO` y responde `503 evento-nominacion-error` con `Retry-After: 2`. No equivale a una aprobación ni a un rechazo. Esperá el intervalo y repetí la misma solicitud, con la misma `Idempotency-Key` si la enviaste. La confirmación y, si se comprueba que el evento no existe, como máximo un reenvío se realizan dentro de la petición. No hay recuperación automática en segundo plano. No cambies el receptor, motivo o clave mientras el resultado siga incierto. Una nominación aprobada no se reemplaza mediante una nueva solicitud; el replay con la clave original permite recuperar su respuesta. ## Errores [#errores] | HTTP | Tipo | Qué revisar | | ---- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------- | | 400 | `validation-error`, `invalid-enum-value`, `invalid-format` | Campos, formatos y valores del receptor o la clave | | 400 | `evento-nominacion-error` | Elegibilidad de la factura, geografía o datos indicados en `detail` | | 403 | `document-archived` | El período de acceso al documento finalizó. No aplica a una clave ya registrada | | 404 | `documento-electronico-not-found` | CDC no encontrado para la API key y su ambiente, o documento cuya conservación venció | | 409 | `evento-nominacion-error` | Conflicto con una nominación activa o aprobada | | 422 | `sandbox-operation-not-supported` | Usá el ambiente DEV o PROD correspondiente a la factura | | 503 | `evento-nominacion-error` | Resultado sin confirmar; respetá `Retry-After` | También se aplican los [errores de idempotencia](/docs/guias/idempotencia) cuando enviás la clave y los [errores generales de la API](/docs/referencia/errores). Consultá la [guía de nominación](/docs/guias/nominar-factura) para implementar el flujo. # Autofactura Electrónica (/docs/referencia/modelos/autofactura) **`tipoDocumento`:** `AUTOFACTURA_ELECTRONICA` ✅ Disponible La Autofactura Electrónica (AFE) documenta una compra a una persona no contribuyente. El contribuyente que la emite es el comprador; los datos de quien vende se envían en `vendedor`. La solicitud se envía a [`POST /api/v1/documento-electronico`](/docs/referencia/documentos-electronicos/emitir). ## Restricciones [#restricciones] * Admite vendedores locales con cédula paraguaya y constancia de no ser contribuyente. No admite microproductores ni vendedores del exterior. * La operación debe ser en guaraníes (`PYG`) y al contado (`CONTADO`). * No envíes `receptor`: se completa con los datos del contribuyente asociado a la API key. * Los ítems llevan el precio final por unidad, sin campos de IVA ni descuentos separados. * No admite cuotas ni campos de crédito. * No admite `PAGO_BANCARIO` como medio de pago. * No está disponible en la modalidad packs. Antes de emitir, Sifende consulta el padrón del vendedor. Admite personas sin RUC o con estado cancelado (`CAN`) o cancelado definitivo (`CDE`). Si la consulta no está disponible, devuelve `502 padron-no-disponible`: intentá nuevamente más tarde. Esto no sustituye la evaluación de si corresponde usar una autofactura para la compra. ## Campos de la solicitud [#campos-de-la-solicitud] | Campo | Tipo | Requerido | Descripción | | ------------------------------------------ | ---------- | --------- | ------------------------------------------------------------------------------------------------------------------------- | | `tipoDocumento` | `enum` | Sí | `AUTOFACTURA_ELECTRONICA` | | `fechaEmision` | `datetime` | No | Fecha y hora de Paraguay: `YYYY-MM-DDTHH:mm:ss`. Si se omite, se usa la fecha y hora en que Sifende recibe la solicitud | | `numeroEstablecimiento`, `puntoExpedicion` | `integer` | Sí | 1–999, habilitados para el contribuyente | | `tipoEmision` | `enum` | No | `NORMAL` por defecto | | `tipoTransaccion` | `enum` | Sí | Nombre exacto del [catálogo de enumeraciones](/docs/referencia/catalogos/enumeraciones) | | `monedaOperacion` | `enum` | No | `PYG` por defecto. No admite otra moneda ni `tipoCambio` de la operación | | `condicionOperacion` | `enum` | No | `CONTADO` por defecto | | `vendedor` | `object` | Sí | Identificación y domicilio del vendedor; ver campos debajo | | `lugarOperacion` | `object` | Sí | Dirección donde se realiza la compra; usa los mismos campos que `vendedor.domicilio` | | `constancia` | `object` | Sí | Enviá `tipo: CONSTANCIA_NO_CONTRIBUYENTE` | | `items` | `array` | Sí | Entre 1 y 999 ítems; ver campos debajo | | `condicionPago` | `object` | Sí | `tipo: CONTADO`, `tipoPago`, `monedaPago` y `montoPago`. Ver [Condición de Pago](/docs/referencia/modelos/condicion-pago) | | `emailEntrega` | `string` | No | Correo para recibir el documento, hasta 80 caracteres | | `infoEmisor` | `string` | No | Información adicional del emisor, de 1 a 3000 caracteres en una sola línea | | `obligacionesAfectadas` | `array` | No | Hasta 11 códigos de obligaciones tributarias del catálogo, enviados como strings | Enviá únicamente los campos admitidos para AFE. Los campos desconocidos se rechazan con `400 invalid-format`; no se descartan. Omití los campos incompatibles, como `descuentoGlobalPorcentaje`, `tipoCambio` en el documento, `receptor`, cuotas y datos de crédito. ### Vendedor [#vendedor] | Campo | Tipo | Requerido | Descripción | | ----------------- | --------- | --------- | -------------------------------------------------------------------------- | | `naturaleza` | `enum` | Sí | `NO_CONTRIBUYENTE` | | `tipoDocumento` | `enum` | Sí | `CEDULA_PARAGUAYA` | | `numeroDocumento` | `string` | Sí | Número de cédula: solo dígitos, de 5 a 12, conservando los ceros iniciales | | `nombre` | `string` | Sí | Nombre completo, de 4 a 60 caracteres | | `numeroCasa` | `integer` | Sí | 0–999999. Usá `0` si no tiene número | | `domicilio` | `object` | Sí | Dirección y códigos geográficos | ### Domicilio y lugar de la operación [#domicilio-y-lugar-de-la-operación] | Campo | Tipo | Requerido | Descripción | | ---------------- | --------- | --------- | ----------------------------------------- | | `direccion` | `string` | Sí | Hasta 255 caracteres | | `departamento` | `string` | Sí | Código SIFEN de 1 o 2 dígitos | | `codigoDistrito` | `integer` | No | Código SIFEN del distrito, entre 1 y 9999 | | `ciudad` | `string` | Sí | Código SIFEN de hasta 5 dígitos | Consultá el [catálogo de geografía](/docs/referencia/catalogos/geografia) y enviá los códigos SIFEN, no los nombres ni los IDs. Podés omitir el distrito si el departamento y la ciudad identifican la ubicación sin ambigüedad. Si la ciudad no pertenece al departamento o distrito indicado, la API devuelve `400`: corregí los códigos. Si el código de ciudad es ambiguo, informá `codigoDistrito` para identificar la ubicación. ### Ítems y pago [#ítems-y-pago] | Campo del ítem | Tipo | Requerido | Descripción | | ---------------- | -------- | --------- | ------------------------------------------------------------------------------- | | `codigo` | `string` | Sí | Hasta 50 caracteres | | `descripcion` | `string` | Sí | Hasta 2000 caracteres | | `cantidad` | `number` | Sí | Mayor que cero, hasta 10 dígitos enteros y 8 decimales | | `unidadMedida` | `enum` | Sí | Nombre del catálogo, por ejemplo `UNI` o `kg` | | `precioUnitario` | `number` | Sí | Precio final por unidad, mayor que cero, hasta 15 dígitos enteros y 8 decimales | Sifende calcula los totales y redondea el total general al múltiplo inferior de 50 guaraníes. Los totales de ítem y operación admiten hasta 15 dígitos enteros y 8 decimales. El pago debe coincidir con el total general. La API admite pagos en otra moneda con `tipoCambio` dentro de `condicionPago`; la operación sigue siendo en PYG. El resultado de `montoPago × tipoCambio`, redondeado a guaraníes enteros (la mitad hacia arriba), debe coincidir exactamente con el total general. Por ejemplo, para un total de 10.000 Gs., un pago de 2 USD con cotización de 5.000 Gs. cumple esa condición. Para cheques, informá `numeroCheque` de 8 dígitos y `bancoCheque` de 1 a 20 caracteres. ## Ejemplo [#ejemplo] ```json { "tipoDocumento": "AUTOFACTURA_ELECTRONICA", "fechaEmision": "2026-09-30T10:00:00", "numeroEstablecimiento": 1, "puntoExpedicion": 1, "tipoTransaccion": "COMPRA_PRODUCTOS", "vendedor": { "naturaleza": "NO_CONTRIBUYENTE", "tipoDocumento": "CEDULA_PARAGUAYA", "numeroDocumento": "1234567", "nombre": "Persona Vendedora", "numeroCasa": 0, "domicilio": { "direccion": "Calle principal", "departamento": "1", "ciudad": "1" } }, "lugarOperacion": { "direccion": "Calle principal", "departamento": "1", "ciudad": "1" }, "constancia": { "tipo": "CONSTANCIA_NO_CONTRIBUYENTE" }, "condicionPago": { "tipo": "CONTADO", "tipoPago": "EFECTIVO", "monedaPago": "PYG", "montoPago": 10000 }, "items": [ { "codigo": "BIEN-1", "descripcion": "Bien usado", "cantidad": 2, "unidadMedida": "UNI", "precioUnitario": 5000 } ], "tipoEmision": "NORMAL", "condicionOperacion": "CONTADO" } ``` ## Consultar el resultado [#consultar-el-resultado] La respuesta `202 Accepted` incluye el CDC y el estado `PENDIENTE`. Consultá el estado para confirmar la aprobación de SIFEN antes de usar el documento como comprobante. Usá `Idempotency-Key` para reintentar la misma solicitud sin duplicar la emisión. Una clave ya registrada devuelve la emisión original aunque cambie el contenido; generá una clave por documento. Ver [Idempotencia](/docs/guias/idempotencia). ## Próximos pasos [#próximos-pasos] * [Guía para emitir una autofactura](/docs/guias/autofactura) * [Consultar el estado de un documento](/docs/guias/consultar-estado) * [Descargar el KuDE](/docs/guias/descargar-kude) * [Manejar errores de la API](/docs/guias/manejar-errores) # Condición de Pago (/docs/referencia/modelos/condicion-pago) Una Factura Electrónica describe cómo paga el cliente con una de dos formas excluyentes: * **`condicionPago`**: un solo objeto para el caso simple, un medio de contado o un crédito con una entrega inicial opcional. * **`pagos` + `credito`**: la forma completa. Admite varios medios de pago, datos de tarjeta o cheque y medios `OTRO` con descripción propia. No combines ambas formas: una solicitud con `condicionPago` y `pagos` o `credito` recibe `400 validation-error`. ## Forma completa: `pagos` y `credito` [#forma-completa-pagos-y-credito] | Campo | Tipo | Requerido | Descripción | | --------- | -------- | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | | `pagos` | `array` | Sí en `CONTADO`; opcional en `CREDITO` | Medios de pago en orden, hasta 999. En `CONTADO` cubren el total; en `CREDITO` describen la entrega inicial | | `credito` | `object` | Sí en `CREDITO` sin `condicionPago` | Condiciones del crédito; no se informa en `CONTADO`. Si una operación a crédito no envía `condicionPago` ni `credito`, la respuesta es `400` en `credito` | ### Cada pago [#cada-pago] | Campo | Tipo | Requerido | Descripción | | --------------------- | -------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | `tipoPago` | `enum` | Sí | Medio de pago — ver [`tipoPago`](#valores-de-tipopago) | | `descripcionTipoPago` | `string` | Sí con `OTRO` | Descripción propia del medio, de 4 a 30 caracteres. Sólo con `tipoPago = OTRO` | | `montoPago` | `number` | Sí | Importe en la moneda del pago, mayor que cero, hasta 15 enteros y 4 decimales | | `monedaPago` | `enum` | Sí | Moneda del pago | | `tipoCambio` | `number` | Condicional | Obligatorio cuando `monedaPago` no es `PYG`; no se informa en `PYG` | | `tarjeta` | `object` | Sí con tarjeta | Obligatorio y exclusivo de `TARJETA_DE_CREDITO` y `TARJETA_DE_DEBITO` | | `cheque` | `object` | Sí con cheque | `{ numeroCheque, bancoCheque }`, obligatorio y exclusivo de `CHEQUE`. `numeroCheque` admite hasta 8 dígitos; `bancoCheque`, de 4 a 20 caracteres no vacíos | `PAGO_BANCARIO` sólo corresponde a una operación bancaria: informalo con `indicadorPresencia: "OPERACION_BANCARIA"`. ### `tarjeta` [#tarjeta] | Campo | Tipo | Requerido | Descripción | | ------------------------------ | -------- | ------------- | ---------------------------------------------------------------------------- | | `tipoTarjeta` | `enum` | Sí | Denominación — ver [`tipoTarjeta`](#tipotarjeta) | | `descripcionTipoTarjeta` | `string` | Sí con `OTRO` | De 4 a 20 caracteres. Sólo con `tipoTarjeta = OTRO` | | `formaProcesamientoPago` | `enum` | Sí | `POS`, `PAGO_ELECTRONICO` u `OTRO` | | `razonSocialProcesadora` | `string` | No | De 4 a 60 caracteres | | `rucProcesadora` | `string` | No | RUC sin DV; se informa junto con `digitoVerificadorProcesadora` | | `digitoVerificadorProcesadora` | `string` | No | Un dígito, que debe corresponder al RUC | | `codigoAutorizacion` | `string` | No | Entero positivo de 6 a 10 dígitos, sin ceros a la izquierda (desde `100000`) | | `nombreTitular` | `string` | No | De 4 a 30 caracteres | | `ultimosCuatroDigitos` | `string` | No | Cuatro dígitos distintos de `0000` | ### Contado con varios medios [#contado-con-varios-medios] La suma de los pagos debe ser igual al total a pagar de la factura: no se admite un saldo pendiente en una operación al contado. Un saldo a pagar después corresponde a crédito. En guaraníes el total a pagar se redondea hacia abajo a múltiplos de 50 (107.437 se paga 107.400). En otras monedas el total no se redondea: se paga el total general exacto (30,75 USD se paga 30,75). ```json { "condicionOperacion": "CONTADO", "pagos": [ { "tipoPago": "EFECTIVO", "monedaPago": "PYG", "montoPago": 60000 }, { "tipoPago": "TARJETA_DE_DEBITO", "monedaPago": "PYG", "montoPago": 50000, "tarjeta": { "tipoTarjeta": "VISA", "formaProcesamientoPago": "POS", "ultimosCuatroDigitos": "4321" } } ] } ``` Cuando todos los pagos están en la moneda de la operación, la suma se compara con el total general en esa moneda. Si algún pago está en otra moneda, la comparación se hace en guaraníes: cada pago se convierte con su `tipoCambio` y se compara con el total en guaraníes de la factura. ### `credito` [#credito] | Campo | Tipo | Requerido | Descripción | | --------------------- | --------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | `condicionCredito` | `enum` | Sí | `PLAZO` o `CUOTA` | | `plazoCredito` | `string` | Una alternativa para `PLAZO` | Texto libre de 2 a 15 caracteres | | `plazoEstructurado` | `object` | Una alternativa para `PLAZO` | `{ "cantidad": 30, "unidad": "DIAS" }` | | `cuotas` | `integer` | Sí para `CUOTA` | Cantidad de cuotas, de 1 a 999; igual a la cantidad de elementos de `detalleCuotas` | | `detalleCuotas` | `array` | Sí para `CUOTA` | `{ monto, fechaVencimiento?, moneda? }` por cuota. `moneda` es opcional y, si se informa, debe coincidir con `monedaOperacion` | | `montoEntregaInicial` | `number` | No | Si se informa, debe ser igual a la suma de `pagos` | ```json { "condicionOperacion": "CREDITO", "pagos": [ { "tipoPago": "CHEQUE", "monedaPago": "PYG", "montoPago": 20000, "cheque": { "numeroCheque": "1234567", "bancoCheque": "Banco Continental" } } ], "credito": { "condicionCredito": "CUOTA", "cuotas": 2, "detalleCuotas": [ { "monto": 45000, "fechaVencimiento": "2026-11-18" }, { "monto": 45000, "fechaVencimiento": "2026-12-18" } ] } } ``` ## Forma simple: `condicionPago` [#forma-simple-condicionpago] | Campo | Tipo | Requerido | Descripción | | ------------------------ | --------- | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | `tipo` | `enum` | Sí | `CONTADO` o `CREDITO`; debe coincidir con `condicionOperacion` | | `tipoPago` | `enum` | Para `CONTADO` y para crédito con entrega inicial | Medio de pago — ver tabla abajo | | `descripcionTipoPago` | `string` | Sí con `OTRO` | Descripción propia del medio, de 4 a 30 caracteres. Sólo con `tipoPago = OTRO` | | `monedaPago` | `enum` | Para `CONTADO` y para crédito con entrega inicial | Moneda del pago; en una entrega inicial debe coincidir con `monedaOperacion` | | `tipoCambio` | `number` | Condicional | Obligatorio cuando `monedaPago` no es `PYG`; no se informa para pagos en `PYG` | | `montoPago` | `number` | Sí para `CONTADO` | Monto pagado; si `monedaPago` coincide con `monedaOperacion`, debe ser igual al total de la operación. No se informa para `CREDITO` | | `numeroCheque` | `string` | Sí para `tipoPago = CHEQUE` | Número del cheque, hasta 8 dígitos. Sólo con `CHEQUE` | | `bancoCheque` | `string` | Sí para `tipoPago = CHEQUE` | Banco emisor del cheque, de 4 a 20 caracteres no vacíos. Sólo con `CHEQUE` | | `tipoTarjeta` | `enum` | No (sólo tarjetas) | Denominación de la tarjeta. Si no se informa, se asume `OTRO` | | `descripcionTipoTarjeta` | `string` | Sí con `tipoTarjeta = OTRO` | De 4 a 20 caracteres. Sólo con `tipoTarjeta = OTRO` o sin `tipoTarjeta` | | `formaProcesamientoPago` | `enum` | No (sólo tarjetas) | Forma de procesamiento. Si no se informa, se asume `OTRO` | | `condicionCredito` | `enum` | Sí para `CREDITO` | Modalidad: `PLAZO` o `CUOTA` | | `plazoCredito` | `string` | Una alternativa para `PLAZO` | Texto libre de 2 a 15 caracteres. No genera un vencimiento calculable. | | `plazoEstructurado` | `object` | Una alternativa para `PLAZO` | `{ "cantidad": 30, "unidad": "DIAS" }`; cantidad entera de 1 a 9999, unidad `DIAS` o `MESES`. | | `cuotas` | `integer` | Sí para `CUOTA` | Cantidad, entre 1 y 999; debe coincidir con `detalleCuotas.length` | | `detalleCuotas` | `array` | Sí para `CUOTA` | Un detalle por cuota; cada monto es positivo y la fecha es opcional | | `montoEntregaInicial` | `number` | No (sólo `CREDITO`) | Entrega inicial; `null` o `0` significa que no hay entrega | Los datos de tarjeta sólo se informan con `TARJETA_DE_CREDITO` o `TARJETA_DE_DEBITO`, y los de cheque sólo con `CHEQUE`; con otro `tipoPago` la respuesta es `400` en el campo enviado. Para informar los datos de la procesadora o más de un medio de pago, usá la [forma completa](#forma-completa-pagos-y-credito). ## Tipo de cambio del pago [#tipo-de-cambio-del-pago] `tipoCambio` describe la conversión de la moneda del pago y se valida independientemente del tipo de cambio GLOBAL o POR\_ITEM de la operación. Debe ser positivo, menor que `99999.9999` y admitir como máximo 4 decimales. ```json { "condicionPago": { "tipo": "CONTADO", "tipoPago": "TRANSFERENCIA", "monedaPago": "USD", "tipoCambio": 7130.5000, "montoPago": 30.75 } } ``` Una operación en USD pagada en PYG no lleva `tipoCambio` en el pago. Un pago en USD sí lo requiere, aunque ya hayas informado la cotización de la operación. Ver [Facturar en Moneda Extranjera](/docs/guias/moneda-extranjera). ## Modalidades de crédito [#modalidades-de-crédito] `PLAZO` y `CUOTA` son ramas excluyentes, en `condicionPago` y en `credito`. Para `PLAZO` enviá exactamente uno de `plazoCredito` o `plazoEstructurado`. No envíes `cuotas` ni `detalleCuotas` con `PLAZO`, ni ningún plazo con `CUOTA`. El plazo estructurado produce el texto (`30 días` o `2 meses`) y una fecha desde la fecha efectiva de emisión. Los meses se suman como meses calendario y se ajustan al último día del mes. ```json { "condicionPago": { "tipo": "CREDITO", "condicionCredito": "PLAZO", "plazoCredito": "30 días", "montoEntregaInicial": 0 } } ``` También se puede emitir con vencimiento calculable: ```json { "condicionPago": { "tipo": "CREDITO", "condicionCredito": "PLAZO", "plazoEstructurado": { "cantidad": 30, "unidad": "DIAS" } } } ``` `plazoCredito` se envía como texto libre y no se interpreta como una fecha. `cuotas` es la cantidad de cuotas y `detalleCuotas` el calendario completo: debe tener exactamente esa cantidad de elementos, y la suma de los montos debe ser igual al saldo financiado, es decir el total de la factura menos la entrega inicial. Las cuotas se expresan en la moneda de la operación. ```json { "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" } ] } } ``` Cada `monto` admite hasta 15 enteros y 4 decimales. `fechaVencimiento` usa `YYYY-MM-DD` y puede omitirse. `moneda` también puede omitirse; si se informa, debe ser la `monedaOperacion`. ### Entrega inicial [#entrega-inicial] Una entrega positiva agrega `tipoPago` y `monedaPago` al mismo bloque de `condicionPago`, o se informa como `pagos` en la forma completa: ```json { "condicionPago": { "tipo": "CREDITO", "condicionCredito": "PLAZO", "plazoCredito": "30 días", "tipoPago": "TRANSFERENCIA", "monedaPago": "PYG", "montoEntregaInicial": 20000 } } ``` La entrega se expresa en la moneda de la operación y debe ser menor que el total: sin saldo financiado, la operación es `CONTADO`. `CHEQUE` también exige `numeroCheque` y `bancoCheque`. El crédito admite cualquier moneda de operación. En moneda extranjera, la entrega y las cuotas se expresan en esa moneda, y un pago en moneda extranjera lleva su `tipoCambio`. ## Valores de `tipoPago` [#valores-de-tipopago] | Valor | Descripción | | ----------------------- | --------------------------------------------- | | `EFECTIVO` | Pago en efectivo | | `CHEQUE` | Cheque | | `TARJETA_DE_CREDITO` | Tarjeta de crédito | | `TARJETA_DE_DEBITO` | Tarjeta de débito | | `TRANSFERENCIA` | Transferencia bancaria | | `GIRO` | Giro u orden de pago | | `BILLETERA_ELECTRONICA` | Billetera electrónica | | `TARJETA_EMPRESARIAL` | Tarjeta empresarial | | `RETENCION` | Retención | | `PAGO_BANCARIO` | Pago bancario, sólo en una operación bancaria | | `PAGO_MOVIL` | Pago móvil | | `OTRO` | Otro medio, con `descripcionTipoPago` | Consultá [enumeraciones](/docs/referencia/enumeraciones#tipopago) para el listado completo y actualizado. ### tipoTarjeta [#tipotarjeta] | Valor | Descripción | | ------------------ | ---------------- | | `VISA` | Visa | | `MASTERCARD` | Mastercard | | `AMERICAN_EXPRESS` | American Express | | `MAESTRO` | Maestro | | `PANAL` | Panal | | `CABAL` | Cabal | | `OTRO` | Otro | `tipoTarjeta` y `formaProcesamientoPago` también se publican en `/api/v1/public/enums`. ## Próximos pasos [#próximos-pasos] * [Modelo Factura Electrónica](/docs/referencia/modelos/factura-electronica) * [Enumeraciones SIFEN](/docs/referencia/enumeraciones) # Documento Asociado (/docs/referencia/modelos/documento-asociado) El objeto `documentoAsociado` referencia un documento previo desde una Nota de Crédito o de Débito, que debe apuntar a la FE original que modifica. Las Facturas Electrónicas usan la lista [`documentosAsociados`](/docs/referencia/modelos/factura-electronica#documentos-asociados-y-anticipos), también para un solo documento. ## Schema [#schema] | Campo | Tipo | Requerido | Descripción | | --------------- | -------- | --------------------- | ---------------------------------------------------------------------------------------------- | | `tipoDocumento` | `enum` | Sí | `ELECTRONICO`, `IMPRESO` o `CONSTANCIA_ELECTRONICA` | | `rucFusionado` | `string` | No | En NCE/NDE, RUC fusionado del emisor del documento asociado, sin DV ni guion; ver reglas abajo | | `cdc` | `string` | Sí para `ELECTRONICO` | CDC de 44 caracteres del documento referenciado | ## Tipos admitidos según el documento [#tipos-admitidos-según-el-documento] | Documento | Campo de asociación | Tipos admitidos | | --------- | --------------------- | ---------------------------------------------------------------------------------------------------------- | | NCE y NDE | `documentoAsociado` | `ELECTRONICO`; otro valor recibe `400 validation-error` | | FE | `documentosAsociados` | `ELECTRONICO` o `IMPRESO`, notas de remisión y facturas de anticipo. `CONSTANCIA_ELECTRONICA` no se admite | | NRE | `documentosAsociados` | `ELECTRONICO` o `IMPRESO`, sólo facturas | Las NRE usan una lista con campos específicos. Consultá [Documentos asociados de NRE](/docs/referencia/modelos/nota-remision#documentos-asociados-documentosasociados). ## Reglas [#reglas] * El CDC debe pertenecer a un documento aprobado por SIFEN (estado `APROBADO` o `APROBADO_OBSERVACION`). No podés referenciar un documento pendiente o rechazado. * El receptor del documento original y el de la NCE/NDE deben coincidir (mismo RUC, CI, etc.). * Para NCE: el documento original debe ser una FE (no se permite NCE sobre NCE). ### RUC fusionado en NCE y NDE [#ruc-fusionado-en-nce-y-nde] `documentoAsociado.rucFusionado` admite de 3 a 8 caracteres: empieza con un dígito distinto de cero, continúa con dígitos y puede terminar en `A`, `B`, `C` o `D`. Debe corresponder al RUC emisor contenido en el CDC asociado, comparándolo con ceros a la izquierda hasta 8 caracteres. No se admite en FE. Por ejemplo, para el CDC del ejemplo siguiente, el RUC base es `80012345`. ## Ejemplo — Referencia electrónica [#ejemplo--referencia-electrónica] ```json { "documentoAsociado": { "tipoDocumento": "ELECTRONICO", "cdc": "01800123451001001000000122026042710000000006" } } ``` El CDC tiene exactamente **44 dígitos** y codifica RUC del emisor, tipo de documento, establecimiento, punto de expedición, número, fecha de emisión y un código de seguridad. Ver el [concepto CDC](/docs/conceptos/cdc) para el desglose completo. ## Uso típico — Nota de Crédito [#uso-típico--nota-de-crédito] ```json { "tipoDocumento": "NOTA_DE_CREDITO_ELECTRONICA", "motivoEmision": "DEVOLUCION", "documentoAsociado": { "tipoDocumento": "ELECTRONICO", "cdc": "01800123451001001000000122026042710000000006" } } ``` ## Próximos pasos [#próximos-pasos] * [Modelo Nota de Crédito](/docs/referencia/modelos/nota-credito) * [Modelo Nota de Débito](/docs/referencia/modelos/nota-debito) * [Concepto: CDC](/docs/conceptos/cdc) # Factura Electrónica (/docs/referencia/modelos/factura-electronica) **`tipoDocumento`:** `FACTURA_ELECTRONICA` ✅ Disponible La solicitud de FE contiene todos los campos obligatorios para emitir una Factura Electrónica conforme a SIFEN. Se envía al endpoint polimórfico [`POST /api/v1/documento-electronico`](/docs/referencia/documentos-electronicos/emitir). ## Campos comunes (base) [#campos-comunes-base] | Campo | Tipo | Requerido | Descripción | | --------------------------- | ---------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `tipoDocumento` | `enum` | Sí | Debe ser `FACTURA_ELECTRONICA` | | `fechaEmision` | `datetime` | No | ISO 8601 sin zona — `YYYY-MM-DDTHH:mm:ss`, hora de Paraguay. Si se omite, se usa la fecha y hora en que Sifende recibe la solicitud. Admite hasta 720 horas antes y 120 horas después de la hora actual de Paraguay; fuera de ese rango recibe `400` en `errores.fechaEmision` | | `tipoEmision` | `enum` | No | Sólo `NORMAL`, valor por defecto. SIFEN todavía no habilita la emisión en contingencia | | `numeroEstablecimiento` | `integer` | Sí | 1–999; obligatorio, sin valor por defecto | | `puntoExpedicion` | `integer` | Sí | 1–999; obligatorio, sin valor por defecto | | `monedaOperacion` | `enum` | No | Por defecto `PYG`. Acepta `USD`, `EUR`, etc. | | `tipoCambio` | `number` | Condicional | Tipo de cambio global. Obligatorio para moneda extranjera en modalidad GLOBAL; no se informa en PYG ni en POR\_ITEM | | `descuentoGlobalPorcentaje` | `number` | No | Porcentaje global mayor que 0 y menor o igual a 100, aplicado al precio unitario de cada ítem | | `obligacionesAfectadas` | `string[]` | No | Hasta 11 códigos de obligaciones tributarias, sin valores nulos ni repetidos; ver abajo | | `infoEmisor` | `string` | No | Texto libre adicional del emisor, de 1 a 3000 caracteres en una sola línea | | `receptor` | `object` | Sí | Ver [Receptor](/docs/referencia/modelos/receptor) | | `items` | `array` | Sí | Al menos 1 ítem — ver [Ítem](/docs/referencia/modelos/item) | ### Obligaciones afectadas [#obligaciones-afectadas] `obligacionesAfectadas` admite los códigos `"113"`, `"143"`, `"211"`, `"311"`, `"321"`, `"700"`, `"701"`, `"702"`, `"703"`, `"715"` y `"716"`, como strings. Por ejemplo: `"obligacionesAfectadas": ["211", "700"]`. Se admite en FE, NCE y NDE. En NRE debe omitirse: incluso una lista vacía recibe `400 validation-error`. ## Campos específicos de FE [#campos-específicos-de-fe] | Campo | Tipo | Requerido | Descripción | | -------------------------- | -------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `tipoTransaccion` | `enum` | Sí | `VENTA_MERCADERIA`, `PRESTACION_SERVICIOS`, `MIXTO`, `VENTA_ACTIVO_FIJO`, `VENTA_DIVISAS`, `ANTICIPO`, `VENTA_CREDITO_FISCAL` — ver [tipoTransaccion](/docs/referencia/enumeraciones#tipotransaccion) para la lista completa | | `condicionOperacion` | `enum` | Sí | `CONTADO` o `CREDITO` | | `condicionPago` | `object` | Una de dos formas | Forma simple: un medio de contado o un crédito. Ver [Condición de Pago](/docs/referencia/modelos/condicion-pago) | | `pagos` | `array` | Una de dos formas | Forma completa: medios de pago de contado o entrega inicial de un crédito | | `credito` | `object` | En `CREDITO` sin `condicionPago` | Condiciones del crédito en la forma completa | | `tipoImpuesto` | `enum` | No | Impuesto afectado: `IVA` (por defecto), `RENTA`, `NINGUNO` o `IVA_RENTA`. Con `RENTA` o `NINGUNO` los ítems no pueden ser `GRAVADO` ni `GRAVADO_PARCIAL` (`400` en `items[i].afectacionTributaria`) | | `indicadorPresencia` | `enum` | No | Presencia del comprador; por defecto `OPERACION_PRESENCIAL` | | `descripcionPresencia` | `string` | Con `OTRO` | De 10 a 30 caracteres; obligatoria y exclusiva de `indicadorPresencia = OTRO` | | `fechaFuturaRemision` | `date` | No | `YYYY-MM-DD`, cuando la mercadería se traslada después con una nota de remisión | | `documentosAsociados` | `array` | No | Hasta 99 notas de remisión o facturas de anticipo. Ver [Documentos asociados](#documentos-asociados-y-anticipos) | | `condicionAnticipo` | `enum` | Con anticipo | `ANTICIPO_GLOBAL` o `ANTICIPO_POR_ITEM` | | `anticipoGlobalPorcentaje` | `number` | Con `ANTICIPO_GLOBAL` | Porcentaje del precio unitario de cada ítem que se cubre con el anticipo | | `comision` | `number` | No | Comisión de la operación con IVA 10% incluido, mayor que 0. Se suma al total general y su IVA al total de IVA. En moneda extranjera requiere `tipoCambio` global | | `informacionFiscal` | `string` | No | Información de interés del Fisco, de 1 a 3000 caracteres en una sola línea | | `informacionAdicional` | `string` | No | Texto para el receptor, de 1 a 5000 caracteres. Se imprime en el KuDE y no se envía a SIFEN | | `datosComerciales` | `object` | No | Órdenes, asiento, ciclo, vencimientos, contrato y saldo anterior. Ver [Datos comerciales](#datos-comerciales) | | `energia` | `array` | No | Hasta 9 mediciones de energía eléctrica | | `seguro` | `object` | No | Aseguradora y pólizas | | `supermercado` | `object` | No | Cajero, efectivo, vuelto y donación | | `transporte` | `object` | No | Traslado de la mercadería. Ver [Transporte y carga](#transporte-y-carga) | | `carga` | `object` | No | Volumen, peso y característica de la carga | `condicionPago` y `pagos`/`credito` son formas excluyentes. Las facturas a crédito admiten dos modalidades: `PLAZO`, con un texto libre o `{ cantidad, unidad }`, y `CUOTA`, con el calendario completo de cuotas, que debe sumar el saldo financiado. El crédito admite cualquier moneda de operación. Para una operación en moneda extranjera al contado, elegí una sola modalidad: `tipoCambio` en la factura (GLOBAL) o `tipoCambio` en todos los ítems (POR\_ITEM). Consultá [Facturar en Moneda Extranjera](/docs/guias/moneda-extranjera) para ver solicitudes completas. Para descuentos, informá solamente las decisiones comerciales: `descuentoParticular` como importe por unidad dentro del ítem y `descuentoGlobalPorcentaje` una vez en el documento. Sifende deriva los porcentajes e importes técnicos del XML, los subtotales, el IVA y el total neto. En PYG los importes globales derivados se redondean a entero con `half-up`; en otras monedas conservan hasta 8 decimales. Si la operación lleva una comisión aparte de los ítems, informala en `comision` con el IVA incluido. Sifende la suma al total general, calcula su IVA al 10% y lo agrega al total de IVA. Los pagos de contado deben cubrir el total general con la comisión incluida. Se admite en FE, NCE y NDE. No se admite un total aparte de operación más comisión: el total general ya la incluye. ## Compras públicas [#compras-públicas] Los datos de contratación DNCP son opcionales en cualquier tipo de operación: B2B, B2C, B2G o B2F. Cuando el receptor es un organismo público, además debe cumplir las [reglas B2G](/docs/referencia/modelos/receptor#reglas-clave). | Campo | Tipo | Descripción | | ------------------------ | -------- | ------------------------------------------------------------------------------------------ | | `comprasPublicas` | `object` | Datos de contratación; si se informa, todos sus campos son obligatorios | | `codigoContratacionDncp` | `string` | Código de contratación DNCP, de 1 a 30 caracteres, no vacío ni compuesto sólo por espacios | ### Campos de `comprasPublicas` [#campos-de-compraspublicas] | Campo | Tipo | Regla | | -------------------- | -------- | -------------------------------------------------------------------- | | `modalidad` | `string` | Exactamente 2 caracteres sin espacios | | `entidad` | `string` | Exactamente 5 dígitos; valor mayor que cero | | `anho` | `string` | Exactamente 2 dígitos; valor mayor que cero | | `secuencia` | `string` | Exactamente 7 dígitos; valor mayor que cero | | `fechaEmisionCodigo` | `string` | Fecha `YYYY-MM-DD`, anterior a la fecha efectiva de emisión de la FE | Enviá los códigos como strings con sus ceros iniciales. La API no acepta números JSON ni completa los ceros. Ejemplo del bloque, para una FE cuya fecha efectiva sea posterior al 10 de enero de 2026: ```json { "comprasPublicas": { "modalidad": "CD", "entidad": "00123", "anho": "26", "secuencia": "0000456", "fechaEmisionCodigo": "2026-01-10" } } ``` Los ítems pueden incluir `codigoDncpGeneral` (string de 8 dígitos) y `codigoDncpEspecifico` (string de 3 a 4 dígitos), también en cualquier operación. Ver [Ítem](/docs/referencia/modelos/item). Un formato de campo inválido recibe `400`. Si `fechaEmisionCodigo` no es anterior a la fecha de emisión de la factura, la respuesta es `422 public-procurement-data-invalid`. ## Documentos asociados y anticipos [#documentos-asociados-y-anticipos] `documentosAsociados` lista, en orden, los documentos que respaldan la factura. Una factura sólo se asocia a una nota de remisión o a una factura de anticipo, electrónica o impresa. El campo singular `documentoAsociado` es de las notas de crédito y débito: en una factura recibe `400 validation-error`, también si hay un solo documento. | Campo | Tipo | Requerido | Descripción | | ------------------------------- | -------- | ------------------------- | -------------------------------------------------------------------------------------------- | | `tipoDocumento` | `enum` | Sí | `ELECTRONICO` o `IMPRESO` | | `cdc` | `string` | Sí en `ELECTRONICO` | CDC de 44 dígitos de la nota de remisión o la factura de anticipo | | `numeroTimbrado` | `string` | Sí en `IMPRESO` | 8 dígitos | | `establecimiento` | `string` | Sí en `IMPRESO` | 3 dígitos | | `puntoExpedicion` | `string` | Sí en `IMPRESO` | 3 dígitos | | `numeroDocumento` | `string` | Sí en `IMPRESO` | 7 dígitos | | `tipoDocumentoImpreso` | `enum` | Sí en `IMPRESO` | `FACTURA` o `NOTA_DE_REMISION` | | `fechaEmision` | `date` | Sí en `IMPRESO` | Fecha del documento impreso | | `numeroComprobanteRetencion` | `string` | No | 15 caracteres; sólo con un pago `RETENCION` | | `numeroResolucionCreditoFiscal` | `string` | En `VENTA_CREDITO_FISCAL` | 15 caracteres; obligatorio en cada documento asociado de esa transacción y exclusivo de ella | Una venta de crédito fiscal (`tipoTransaccion: "VENTA_CREDITO_FISCAL"`) informa al menos un documento asociado, y cada uno lleva su `numeroResolucionCreditoFiscal`. `numeroComprobanteRetencion` es opcional aunque haya un pago `RETENCION`. El Manual Técnico lo marca opcional en la tabla del campo y obligatorio en la regla 2412; SIFEN hoy no aplica esa regla. El comprobante viaja dentro de un documento asociado admitido (nota de remisión o factura de anticipo): no se informa sin una asociación. Un documento electrónico asociado emitido con Sifende se valida antes de firmar la factura. La respuesta es `400 validation-error`, con el error en `errores["documentosAsociados[i]"]`, cuando: | Situación | Mensaje | | ----------------------------------------- | --------------------------------------------------------------------------------- | | Es de otro emisor | `El documento asociado debe ser del mismo emisor (H004g)` | | Está pendiente o fue rechazado | `El documento asociado todavía no está aprobado` | | Está cancelado | `El documento asociado está cancelado (H004b)` | | Es una factura que no es de anticipo | `Una factura asociada debe ser una factura de anticipo (H004e)` | | Es una factura de anticipo en otra moneda | `La factura de anticipo debe tener la misma moneda de la operación (H004f)` | | Tiene otro receptor | `El documento asociado debe tener el mismo receptor que la factura (H004h/H004i)` | Sólo se admiten documentos `APROBADO` o `APROBADO_OBSERVACION`: si todavía está pendiente, esperá su aprobación antes de emitir la factura. Para aplicar un anticipo ya facturado, asociá la factura de anticipo y declará cuánto se aplica en esta factura: * **`ANTICIPO_GLOBAL`**: `anticipoGlobalPorcentaje` se aplica al precio unitario de todos los ítems. * **`ANTICIPO_POR_ITEM`**: cada ítem que aplica anticipo informa `anticipoParticular`, el importe por unidad. Con una sola factura de anticipo electrónica asociada, todos los ítems la referencian en el XML sin que informes `cdcAnticipo`, también los que no aplican anticipo. Con varias, cada ítem indica la suya con `cdcAnticipo`, aplique o no anticipo; un ítem sin `cdcAnticipo` recibe `400` en `items[i].cdcAnticipo`. Una factura de anticipo asociada debe aplicarse en al menos un ítem: asociarla sin `condicionAnticipo` ni importe de anticipo recibe `400` en `condicionAnticipo`. El anticipo reduce el total de cada ítem. El emisor controla cuánto de cada anticipo queda por aplicar. ```json { "documentosAsociados": [ { "tipoDocumento": "ELECTRONICO", "cdc": "01800123451001001000000122026042710000000006" } ], "condicionAnticipo": "ANTICIPO_GLOBAL", "anticipoGlobalPorcentaje": 30 } ``` ## Datos comerciales [#datos-comerciales] | Campo | Tipo | Descripción | | ------------------ | -------- | ------------------------------------------------------------------------------ | | `ordenCompra` | `string` | Hasta 15 caracteres | | `ordenVenta` | `string` | Hasta 15 caracteres | | `asientoContable` | `string` | Hasta 10 caracteres | | `ciclo` | `string` | Hasta 15 caracteres; se informa junto con `fechaInicioCiclo` y `fechaFinCiclo` | | `fechaInicioCiclo` | `date` | Inicio del ciclo facturado | | `fechaFinCiclo` | `date` | Fin del ciclo; no puede ser anterior al inicio | | `vencimientosPago` | `date[]` | Hasta 3 fechas de vencimiento, no anteriores a la emisión | | `numeroContrato` | `string` | Hasta 30 caracteres | | `saldoAnterior` | `number` | Saldo anterior, mayor o igual a cero | ## Datos sectoriales [#datos-sectoriales] * **`energia`**: cada medición informa `numeroMedidor`, `codigoActividad`, `codigoCategoria`, `lecturaAnterior`, `lecturaActual` y `consumo`. La lectura actual no puede ser menor que la anterior, y el consumo es la diferencia entre ambas. * **`seguro`**: `codigoEmpresa` y `polizas`. Cada póliza informa `codigo`, `numero`, `vigencia` y `unidadVigencia`, y opcionalmente `fechaInicioVigencia` y `fechaFinVigencia` (`YYYY-MM-DDTHH:mm:ss`, por ejemplo `2026-01-01T00:00:00`; el fin no puede ser anterior al inicio) y `codigoItem`, que debe ser el código de un ítem de la factura. * **`supermercado`**: `nombreCajero`, `efectivo`, `vuelto`, `donacion` y `descripcionDonacion`. El vuelto y la donación no pueden superar el efectivo recibido. ## Transporte y carga [#transporte-y-carga] `transporte` es opcional en una factura y usa los mismos campos que el [transporte de la nota de remisión](/docs/referencia/modelos/nota-remision#transporte-transporte): `modalidad` y `responsableFlete` son obligatorios; `tipoTransporte`, fechas del traslado, `incoterm`, `numeroManifiesto`, `numeroDespachoImportacion`, `paisDestino`, `salida`, `entregas`, `vehiculos` y `transportista` se informan cuando corresponden. Si informás el transportista, su domicilio fiscal y la dirección del conductor son obligatorios. `carga` informa `volumenTotal` y `pesoTotal` como enteros positivos en string, con sus unidades, y una `caracteristica`. Con `caracteristica: "OTRO"` se describe la carga en `descripcionCaracteristica`. ## Ejemplo completo — FE B2C contado [#ejemplo-completo--fe-b2c-contado] ```json { "tipoDocumento": "FACTURA_ELECTRONICA", "fechaEmision": "2026-04-15T10:30:00", "tipoEmision": "NORMAL", "numeroEstablecimiento": 1, "puntoExpedicion": 1, "monedaOperacion": "PYG", "tipoTransaccion": "VENTA_MERCADERIA", "condicionOperacion": "CONTADO", "receptor": { "tipoContribuyente": "NO_CONTRIBUYENTE", "tipoOperacion": "B2C", "tipoDocumento": "CEDULA_PARAGUAYA", "numeroDocumento": "1234567", "nombreRazonSocial": "Juan Pérez" }, "condicionPago": { "tipo": "CONTADO", "tipoPago": "EFECTIVO", "monedaPago": "PYG", "montoPago": 110000 }, "items": [ { "codigo": "PROD-001", "descripcion": "Resma de papel A4 75g", "cantidad": 10, "unidadMedida": "UNI", "precioUnitario": 11000, "afectacionTributaria": "GRAVADO", "tasaIVA": 10 } ] } ``` ## Ejemplos completos — FE a crédito [#ejemplos-completos--fe-a-crédito] ```json { "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": "0", "nombreRazonSocial": "Comercial San Roque S.A." }, "condicionOperacion": "CREDITO", "condicionPago": { "tipo": "CREDITO", "condicionCredito": "PLAZO", "plazoCredito": "30 días", "montoEntregaInicial": 0 }, "items": [ { "codigo": "PROD-001", "descripcion": "Resma de papel A4 75g", "cantidad": 10, "unidadMedida": "UNI", "precioUnitario": 12000, "afectacionTributaria": "GRAVADO", "tasaIVA": 10 } ] } ``` ```json { "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": "0", "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 agregar una entrega inicial positiva, incluí `tipoPago`, `monedaPago` y `montoEntregaInicial` dentro de `condicionPago`, o informala en `pagos`. Se expresa en la moneda de la operación y debe ser menor que el total. Los errores del contrato de crédito devuelven `400 validation-error` antes de reservar el número del documento. Una solicitud rechazada por estas validaciones no consume secuencia ni crea el documento electrónico. ## Respuesta [#respuesta] `202 Accepted` con los datos del documento creado en estado `PENDIENTE`: ```json { "id": "550e8400-e29b-41d4-a716-446655440000", "cdc": "01800123451001001000000122026042710000000006", "estado": "PENDIENTE", "ambiente": "DEV", "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" } ``` Ver el detalle completo de la respuesta en [Emitir Documento Electrónico](/docs/referencia/documentos-electronicos/emitir#respuesta-exitosa). ## Próximos pasos [#próximos-pasos] * [Consultar el estado del documento](/docs/referencia/documentos-electronicos/consultar-estado) * [Descargar el KuDE en PDF](/docs/referencia/documentos-electronicos/descargar-kude) * [Receptor B2B vs B2C](/docs/guias/receptor-b2b-b2c) # Modelos de Datos (/docs/referencia/modelos) Cada tipo de documento electrónico tiene su propio schema de la solicitud. Todos se envían al mismo endpoint [`POST /api/v1/documento-electronico`](/docs/referencia/documentos-electronicos/emitir) con el campo `tipoDocumento` correspondiente. ## Documentos [#documentos] | Modelo | tipoDocumento | Estado | | ------------------------------------------------------------------- | ------------------------------ | ------------ | | [Factura Electrónica](/docs/referencia/modelos/factura-electronica) | `FACTURA_ELECTRONICA` | ✅ Disponible | | [Nota de Crédito](/docs/referencia/modelos/nota-credito) | `NOTA_DE_CREDITO_ELECTRONICA` | ✅ Disponible | | [Nota de Débito](/docs/referencia/modelos/nota-debito) | `NOTA_DE_DEBITO_ELECTRONICA` | ✅ Disponible | | [Autofactura](/docs/referencia/modelos/autofactura) | `AUTOFACTURA_ELECTRONICA` | ✅ Disponible | | [Nota de Remisión](/docs/referencia/modelos/nota-remision) | `NOTA_DE_REMISION_ELECTRONICA` | ✅ Disponible | ## Entidades compartidas [#entidades-compartidas] | Modelo | Descripción | | ----------------------------------------------------------------- | -------------------------------------------- | | [Receptor](/docs/referencia/modelos/receptor) | Datos del receptor (B2B y B2C) | | [Ítem](/docs/referencia/modelos/item) | Línea de producto o servicio | | [Condición de Pago](/docs/referencia/modelos/condicion-pago) | Contado y crédito | | [Documento Asociado](/docs/referencia/modelos/documento-asociado) | Referencia a documento previo (para NCE/NDE) | # Ítem (/docs/referencia/modelos/item) Cada documento electrónico contiene un arreglo `items` con al menos un elemento. Cada ítem representa un producto o servicio facturado, con su precio, cantidad e información tributaria. Sifende calcula automáticamente todos los totales (subtotales, IVA discriminado, total general). No los mandes en la solicitud: se computan a partir de `cantidad`, `precioUnitario`, `afectacionTributaria` y `tasaIVA`. ## Schema [#schema] | Campo | Tipo | Requerido | Descripción | | ---------------------- | --------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `codigo` | `string` | Sí | Código interno del producto en tu sistema, hasta 50 caracteres | | `descripcion` | `string` | Sí | Descripción del producto o servicio, hasta 2000 caracteres | | `cantidad` | `number` | Sí | Cantidad entre `0.00000001` y `9999999999.99999999`, con hasta 10 enteros y 8 decimales | | `unidadMedida` | `enum` | Sí | `UNI`, `kg`, `LT`, `MT`, etc. — ver [enumeraciones](/docs/referencia/enumeraciones) | | `precioUnitario` | `number` | Sí | Precio unitario **con IVA incluido**, mayor o igual a `0` | | `tipoCambio` | `number` | Condicional | Obligatorio en cada ítem cuando una operación extranjera usa POR\_ITEM; no se informa en GLOBAL ni en PYG | | `afectacionTributaria` | `enum` | Sí | `GRAVADO`, `EXENTO`, `EXONERADO`, `GRAVADO_PARCIAL` | | `tasaIVA` | `integer` | Condicional | `5` o `10` — obligatorio con `GRAVADO` y `GRAVADO_PARCIAL`. Con `EXENTO` o `EXONERADO` se omite o se envía `0`; otra tasa recibe `400` en `items[i].tasaIVA` | | `propIVA` | `number` | Condicional | Porcentaje gravado, mayor a `0` y menor a `100` — obligatorio cuando `afectacionTributaria = GRAVADO_PARCIAL`. En el resto de las afectaciones se ignora | | `descuentoParticular` | `number` | No | Importe de descuento por unidad, en la moneda de la operación. Admite hasta 15 enteros y 8 decimales | ## Códigos de compras públicas [#códigos-de-compras-públicas] | Campo | Tipo | Requerido | Descripción | | ---------------------- | -------- | --------- | ------------------------------------------------------ | | `codigoDncpGeneral` | `string` | No | Exactamente 8 dígitos; opcional en cualquier operación | | `codigoDncpEspecifico` | `string` | No | De 3 a 4 dígitos; opcional en cualquier operación | Conservá los ceros iniciales, por ejemplo `"00123456"` y `"0123"`. No envíes estos códigos como números JSON. Ver [Compras públicas](/docs/referencia/modelos/factura-electronica#compras-públicas). ## Identificación y trazabilidad [#identificación-y-trazabilidad] Estos campos opcionales se incorporan al documento emitido en FE, NCE y NDE: | Campo | Tipo | Regla | | -------------------------------- | -------- | ------------------------------------------------------ | | `partidaArancelaria` | `string` | 4 dígitos | | `ncm` | `string` | De 6 a 8 dígitos | | `gtin` | `string` | GTIN de 8, 12, 13 o 14 dígitos | | `gtinPaquete` | `string` | GTIN del paquete, mismo formato | | `paisOrigen` | `enum` | País de origen de la mercadería | | `observacion` | `string` | Información de interés del emisor sobre el ítem | | `lote` | `string` | De 1 a 80 caracteres | | `vencimiento` | `date` | `YYYY-MM-DD` | | `numeroSerie` | `string` | De 1 a 10 caracteres | | `numeroPedido` | `string` | De 1 a 20 caracteres | | `numeroSeguimiento` | `string` | De 1 a 20 caracteres | | `numeroRegistroProducto` | `string` | Registro sanitario, de 1 a 20 caracteres | | `numeroRegistroEntidadComercial` | `string` | Registro de la entidad comercial, de 1 a 20 caracteres | | `nombreProducto` | `string` | De 1 a 30 caracteres | Las tolerancias de quiebra o merma (`tolerancia`, `toleranciaCantidad`, `toleranciaPorcentaje`) sólo existen en la [nota de remisión](/docs/referencia/modelos/nota-remision#mercaderías-items). `codigoProductoCPBS` no forma parte del documento: usá los códigos DNCP. Informarlos en una FE, NCE o NDE recibe `400 validation-error`. ## Descuentos y anticipos del ítem [#descuentos-y-anticipos-del-ítem] | Campo | Tipo | Descripción | | ------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `descuentoParticular` | `number` | Descuento por unidad, en importe | | `descuentoParticularPorcentaje` | `number` | Alternativa: porcentaje sobre el precio unitario, mayor que 0 y hasta 100. Se informa uno u otro | | `anticipoParticular` | `number` | Sólo en FE con `condicionAnticipo: "ANTICIPO_POR_ITEM"`: anticipo aplicado por unidad | | `cdcAnticipo` | `string` | CDC de la factura de anticipo del ítem. Obligatorio en cada ítem cuando la factura asocia más de una factura de anticipo electrónica; con una sola se completa solo | El descuento y el anticipo, sumados, no pueden superar el precio unitario. Ver [Documentos asociados y anticipos](/docs/referencia/modelos/factura-electronica#documentos-asociados-y-anticipos). ## Vehículos nuevos [#vehículos-nuevos] `vehiculoNuevo` describe un vehículo nuevo vendido en el ítem: `tipoOperacion`, `chasis` (17 caracteres alfanuméricos), `color`, `potencia`, `capacidadMotor`, `pesoNeto`, `pesoBruto`, `tipoCombustible`, `numeroMotor`, `capacidadTraccion`, `anioFabricacion`, `tipoVehiculo` y `capacidadPasajeros`. Con `tipoCombustible: "OTRO"` se informa `descripcionCombustible`, de 3 a 20 caracteres. La cilindrada no se admite. ## Cálculo de IVA [#cálculo-de-iva] Para ítems `GRAVADO`, Sifende calcula el IVA a partir del precio total: * **IVA 10%:** `iva = total / 11` * **IVA 5%:** `iva = total / 21` * **IVA 0% / EXENTO / EXONERADO:** sin IVA discriminado * **GRAVADO\_PARCIAL:** `propIVA` es la proporción gravada de la base. Con `t` la tasa y `p` la proporción, la base gravada es `100 × total × p / (10000 + t × p)`, el IVA es `base × t / 100` y la parte exenta es `100 × total × (100 − p) / (10000 + t × p)` El precio unitario que enviás es IVA incluido. Esa es la convención SIFEN estándar. `descuentoParticular` también es unitario: Sifende lo multiplica por `cantidad` para obtener el descuento particular total. El descuento global no se informa por ítem; usá `descuentoGlobalPorcentaje` en el nivel del documento y Sifende derivará el importe correspondiente para cada ítem. En moneda extranjera, `tipoCambio` admite hasta 5 enteros y 4 decimales, debe ser positivo y menor que `99999.9999`. Si la factura no tiene un tipo de cambio global, todos los ítems deben informarlo; no se permiten modalidades mezcladas ni ítems sin cotización. Ver [Facturar en Moneda Extranjera](/docs/guias/moneda-extranjera). ## Valores comunes de `unidadMedida` [#valores-comunes-de-unidadmedida] | Valor | Significado | | ----- | ---------------- | | `UNI` | Unidad | | `kg` | Kilogramo | | `LT` | Litro | | `MT` | Metro | | `M2` | Metro cuadrado | | `M3` | Metro cúbico | | `Hs` | Hora (servicios) | | `Di` | Día | Ver el listado completo en [enumeraciones](/docs/referencia/enumeraciones#unidadmedida). ## Ejemplo — Producto gravado IVA 10% [#ejemplo--producto-gravado-iva-10] ```json { "codigo": "PROD-001", "descripcion": "Resma de papel A4 75g", "cantidad": 10, "unidadMedida": "UNI", "precioUnitario": 11000, "afectacionTributaria": "GRAVADO", "tasaIVA": 10 } ``` Total del ítem: `10 × 11.000 = 110.000 PYG` (incluye IVA 10% = `10.000 PYG`). ## Ejemplo — Servicio exento [#ejemplo--servicio-exento] ```json { "codigo": "SRV-EDU-01", "descripcion": "Curso de capacitación — 8 horas", "cantidad": 8, "unidadMedida": "Hs", "precioUnitario": 50000, "afectacionTributaria": "EXENTO" } ``` ## Ejemplo — Ítem gravado parcialmente [#ejemplo--ítem-gravado-parcialmente] ```json { "codigo": "PAQ-001", "descripcion": "Paquete turístico — traslado y entradas", "cantidad": 1, "unidadMedida": "UNI", "precioUnitario": 500000, "afectacionTributaria": "GRAVADO_PARCIAL", "tasaIVA": 10, "propIVA": 30 } ``` El 30% del ítem se grava al 10% y el 70% restante va como exento. ## Próximos pasos [#próximos-pasos] * [Modelo Factura Electrónica](/docs/referencia/modelos/factura-electronica) * [Concepto: Ítems e IVA](/docs/conceptos/items-iva) * [Enumeraciones SIFEN](/docs/referencia/enumeraciones) # Nota de Crédito Electrónica (/docs/referencia/modelos/nota-credito) **`tipoDocumento`:** `NOTA_DE_CREDITO_ELECTRONICA` ✅ Disponible La Nota de Crédito Electrónica (NCE) reduce o anula el monto de una Factura Electrónica previamente aprobada por SIFEN. Siempre debe referenciar al documento original mediante `documentoAsociado`. ## Restricciones [#restricciones] La NCE no admite receptor `INNOMINADO`. El receptor debe estar identificado con CI, RUC u otro documento válido. El campo `tipoTransaccion` no se envía: se hereda de la Factura Electrónica original referenciada. ## Campos específicos de NCE [#campos-específicos-de-nce] | Campo | Tipo | Requerido | Descripción | | ------------------- | -------- | --------- | ------------------------------------------------------------------------------------------------------------------- | | `motivoEmision` | `enum` | Sí | Motivo de emisión; ver los valores admitidos debajo | | `documentoAsociado` | `object` | Sí | Referencia obligatoria al documento original. Ver [Documento Asociado](/docs/referencia/modelos/documento-asociado) | Incluye además todos los [campos comunes de la base](/docs/referencia/modelos/factura-electronica#campos-comunes-base): `fechaEmision`, `tipoEmision`, `numeroEstablecimiento`, `puntoExpedicion`, `monedaOperacion`, `receptor`, `items`, y la `comision` opcional de la operación. ## Valores de `motivoEmision` [#valores-de-motivoemision] | Valor | Cuándo usarlo | | --------------------------------- | ------------------------------------------------- | | `DEVOLUCION` | Devolución total o parcial de mercadería | | `DESCUENTO` | Descuento aplicado posteriormente a la emisión | | `BONIFICACION` | Bonificación comercial otorgada al cliente | | `DEVOLUCION_Y_AJUSTES_DE_PRECIOS` | Devolución combinada con ajuste de precios | | `CREDITO_INCOBRABLE` | Crédito declarado incobrable | | `RECUPERO_DE_COSTO` | Recupero de costos | | `RECUPERO_DE_GASTO` | Recupero de gastos | | `AJUSTE_DE_PRECIO` | Ajuste por error de precio en la factura original | ## Ejemplo [#ejemplo] ```json { "tipoDocumento": "NOTA_DE_CREDITO_ELECTRONICA", "fechaEmision": "2026-04-20T14:00:00", "tipoEmision": "NORMAL", "numeroEstablecimiento": 1, "puntoExpedicion": 1, "monedaOperacion": "PYG", "motivoEmision": "DEVOLUCION", "documentoAsociado": { "tipoDocumento": "ELECTRONICO", "cdc": "01800123451001001000000122026042710000000006" }, "receptor": { "tipoContribuyente": "CONTRIBUYENTE", "tipoOperacion": "B2B", "tipoContribuyenteReceptor": "PERSONA_JURIDICA", "numeroDocumento": "80054321", "digitoVerificador": "1", "nombreRazonSocial": "Distribuidora Asunción S.R.L." }, "items": [ { "codigo": "PROD-001", "descripcion": "Resma de papel A4 75g (devolución)", "cantidad": 2, "unidadMedida": "UNI", "precioUnitario": 10000, "afectacionTributaria": "GRAVADO", "tasaIVA": 10 } ] } ``` ## Próximos pasos [#próximos-pasos] * [Cómo emitir una NCE — guía paso a paso](/docs/guias/nota-credito) * [Modelo Documento Asociado](/docs/referencia/modelos/documento-asociado) # Nota de Débito Electrónica (/docs/referencia/modelos/nota-debito) **`tipoDocumento`:** `NOTA_DE_DEBITO_ELECTRONICA` ✅ Disponible La Nota de Débito Electrónica (NDE) aumenta el monto facturado de una Factura Electrónica previamente aprobada por SIFEN. Se usa para cargar intereses, gastos adicionales o ajustes al alza. Siempre referencia al documento original mediante `documentoAsociado`. ## Restricciones [#restricciones] El campo `tipoTransaccion` no se envía: se hereda de la Factura Electrónica original referenciada. ## Campos específicos de NDE [#campos-específicos-de-nde] | Campo | Tipo | Requerido | Descripción | | ------------------- | -------- | --------- | ------------------------------------------------------------------------------------------------------------------- | | `motivoEmision` | `enum` | Sí | Motivo de emisión; ver los valores admitidos debajo | | `documentoAsociado` | `object` | Sí | Referencia obligatoria al documento original. Ver [Documento Asociado](/docs/referencia/modelos/documento-asociado) | Incluye además todos los [campos comunes de la base](/docs/referencia/modelos/factura-electronica#campos-comunes-base): `fechaEmision`, `tipoEmision`, `numeroEstablecimiento`, `puntoExpedicion`, `monedaOperacion`, `receptor`, `items`, y la `comision` opcional de la operación. ## Valores de `motivoEmision` [#valores-de-motivoemision] | Valor | Cuándo usarlo | | --------------------------------- | ------------------------------------------ | | `DEVOLUCION_Y_AJUSTES_DE_PRECIOS` | Devolución combinada con ajuste de precios | | `DEVOLUCION` | Devolución | | `DESCUENTO` | Descuento | | `BONIFICACION` | Bonificación | | `CREDITO_INCOBRABLE` | Crédito declarado incobrable | | `RECUPERO_DE_COSTO` | Recupero de costos | | `RECUPERO_DE_GASTO` | Recupero de gastos | | `AJUSTE_DE_PRECIO` | Ajuste de precio | ## Ejemplo [#ejemplo] ```json { "tipoDocumento": "NOTA_DE_DEBITO_ELECTRONICA", "fechaEmision": "2026-04-22T09:15:00", "tipoEmision": "NORMAL", "numeroEstablecimiento": 1, "puntoExpedicion": 1, "monedaOperacion": "PYG", "motivoEmision": "AJUSTE_DE_PRECIO", "documentoAsociado": { "tipoDocumento": "ELECTRONICO", "cdc": "01800123451001001000000122026042710000000006" }, "receptor": { "tipoContribuyente": "CONTRIBUYENTE", "tipoOperacion": "B2B", "tipoContribuyenteReceptor": "PERSONA_JURIDICA", "numeroDocumento": "80054321", "digitoVerificador": "1", "nombreRazonSocial": "Distribuidora Asunción S.R.L." }, "items": [ { "codigo": "AJ-PRECIO", "descripcion": "Ajuste de precio sobre la factura original", "cantidad": 1, "unidadMedida": "UNI", "precioUnitario": 25000, "afectacionTributaria": "EXENTO" } ] } ``` ## Próximos pasos [#próximos-pasos] * [Cómo emitir una NDE — guía paso a paso](/docs/guias/nota-debito) * [Modelo Documento Asociado](/docs/referencia/modelos/documento-asociado) # Nota de Remisión Electrónica (/docs/referencia/modelos/nota-remision) **`tipoDocumento`:** `NOTA_DE_REMISION_ELECTRONICA` ✅ Disponible La Nota de Remisión Electrónica (NRE) documenta el traslado de mercaderías. Se envía a [`POST /api/v1/documento-electronico`](/docs/referencia/documentos-electronicos/emitir). ## Antes de iniciar el traslado [#antes-de-iniciar-el-traslado] * Esperá a que la nota esté en estado `APROBADO` o `APROBADO_OBSERVACION` y llevá el KuDE con la mercadería. * Los ítems describen las mercaderías, sin precios ni IVA. No se informan condiciones de pago ni descuentos. * El receptor siempre debe estar identificado. No se admite `INNOMINADO`. * En importación y exportación, la NRE cubre el tramo paraguayo. No reemplaza la documentación aduanera. Para un traslado real, emití en PROD. Una nota de DEV o SANDBOX es una prueba sin validez fiscal, aunque figure como `APROBADO`. ## Campos raíz [#campos-raíz] | Campo | Tipo | Requerido | Descripción | | --------------------------- | ---------- | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | `tipoDocumento` | `enum` | Sí | `NOTA_DE_REMISION_ELECTRONICA` | | `fechaEmision` | `datetime` | No | Fecha y hora local de Paraguay, sin zona: `YYYY-MM-DDTHH:mm:ss`. Si se omite, se usa la fecha y hora en que Sifende recibe la solicitud | | `tipoEmision` | `enum` | No | Sólo `NORMAL`, valor por defecto | | `numeroEstablecimiento` | `integer` | Sí | 1–999 | | `puntoExpedicion` | `integer` | Sí | 1–999 | | `receptor` | `object` | Sí | Persona o entidad identificada que recibe la mercadería | | `motivoTraslado` | `enum` | Sí | Motivo del catálogo, por ejemplo `TRASLADO_POR_VENTAS`, `TRASLADO_POR_CONSIGNACION`, `TRASLADO_ENTRE_LOCALES`, `IMPORTACION`, `EXPORTACION` u `OTRO` | | `descripcionMotivoTraslado` | `string` | Para `OTRO` | 5–60 caracteres; se omite para los demás motivos | | `responsableEmision` | `enum` | Sí | Responsable de emitir la nota; independiente del transportista y del responsable del flete | | `kilometrosRecorrido` | `integer` | Sí | 1–99999 | | `costoFlete` | `number` | No | Importe no negativo, hasta 15 enteros y 8 decimales; no representa una venta ni una base de IVA | | `fechaFacturaFutura` | `date` | En ventas sin documentos asociados | `YYYY-MM-DD`; el mes y año no pueden ser posteriores a los de la emisión | | `informacionFiscal` | `string` | No | 1–3000 caracteres en una sola línea con la información fiscal que corresponda al traslado | | `infoEmisor` | `string` | No | 1–3000 caracteres en una sola línea de información adicional del emisor | | `carga` | `object` | No | Volumen, peso y características de la carga | | `items` | `array` | Sí | 1–999 mercaderías | | `transporte` | `object` | Sí | Recorrido, vehículos, transportista y conductor | | `documentosAsociados` | `array` | No | Hasta 99 facturas electrónicas o impresas | | `monedaOperacion` | `enum` | No | Se puede omitir o enviar `PYG` (valor predeterminado al omitir el campo; no acepta `null`); la nota no lleva importes comerciales | Consultá los valores de las enumeraciones en [`GET /api/v1/public/enums`](/docs/referencia/catalogos/enumeraciones). Los campos opcionales pueden omitirse; los textos informados no pueden quedar en blanco. Conservá los ceros iniciales de los campos que se envían como texto. ## Receptor [#receptor] Se aplican las reglas del [receptor](/docs/referencia/modelos/receptor), con dirección e identificación obligatorias: | Campo | Tipo | Regla | | --------------------------- | --------- | ------------------------------------------------------------------------------------------ | | `tipoContribuyente` | `enum` | `CONTRIBUYENTE` o `NO_CONTRIBUYENTE` | | `tipoOperacion` | `enum` | Tipo de operación del receptor | | `numeroDocumento` | `string` | RUC de 3–8 dígitos sin DV para contribuyentes; documento de 1–20 caracteres para los demás | | `digitoVerificador` | `string` | Un dígito, obligatorio y válido para contribuyentes | | `tipoContribuyenteReceptor` | `enum` | Obligatorio para contribuyentes: `PERSONA_FISICA` o `PERSONA_JURIDICA` | | `tipoDocumento` | `enum` | Obligatorio para no contribuyentes; debe identificar al receptor | | `nombreRazonSocial` | `string` | Obligatorio, 4–255 caracteres | | `pais` | `enum` | Código de tres letras; `PRY` por defecto y requerido para operaciones distintas de `B2F` | | `direccion` | `string` | Obligatoria, 1–255 caracteres | | `numeroCasa` | `integer` | Obligatorio, 0–999999; usá `0` si no tiene número | | `departamento`, `ciudad` | `string` | Obligatorios para un receptor nacional; deben corresponder al catálogo geográfico | | `codigoDistrito` | `integer` | Opcional; permite precisar una ciudad con nombre repetido | | `telefono`, `celular` | `string` | Opcionales, 6–15 y 10–20 caracteres respectivamente | | `email` | `string` | Opcional, email válido de hasta 80 caracteres | En `TRASLADO_ENTRE_LOCALES`, el receptor debe ser contribuyente y su RUC debe coincidir con el del emisor. En `B2F`, usá la dirección y el país reales del receptor extranjero. ## Mercaderías: `items[]` [#mercaderías-items] | Campo | Tipo | Regla | | ---------------------------------------------------------- | -------- | -------------------------------------------------------------------------- | | `codigo` | `string` | Obligatorio, 1–50 caracteres | | `descripcion` | `string` | Obligatoria, 1–2000 caracteres | | `cantidad` | `number` | Obligatoria, mayor que cero; hasta 10 enteros y 8 decimales | | `unidadMedida` | `enum` | Obligatoria; nombre exacto del catálogo | | `partidaArancelaria`, `ncm` | `string` | Opcionales, 4 y 6–8 dígitos respectivamente; no pueden contener sólo ceros | | `codigoDncpGeneral`, `codigoDncpEspecifico` | `string` | Opcionales, 8 y 3–4 dígitos respectivamente | | `gtin`, `gtinPaquete` | `string` | Opcionales, 8, 12, 13 o 14 dígitos; no pueden contener sólo ceros | | `paisOrigen` | `enum` | Opcional, país de origen de tres letras | | `observacion` | `string` | Opcional, 1–500 caracteres | | `tolerancia` | `enum` | Si se informa, exige `toleranciaCantidad` y `toleranciaPorcentaje` | | `toleranciaCantidad` | `number` | No negativa, hasta 10 enteros y 4 decimales | | `toleranciaPorcentaje` | `number` | 0–100, hasta 8 decimales | | `lote` | `string` | Identificación de la partida de mercadería, 1–80 caracteres | | `vencimiento` | `date` | Fecha de vencimiento de la mercadería, `YYYY-MM-DD` | | `numeroSerie` | `string` | 1–10 caracteres | | `numeroPedido`, `numeroSeguimiento` | `string` | 1–20 caracteres cada uno | | `numeroRegistroProducto`, `numeroRegistroEntidadComercial` | `string` | 1–20 caracteres cada uno | | `nombreProducto` | `string` | 1–30 caracteres | La tolerancia no reduce la cantidad trasladada ni funciona como un descuento. No envíes `precioUnitario`, `tasaIVA` ni otros importes comerciales. ## Carga: `carga` [#carga-carga] | Campo | Tipo | Regla | | ----------------------------------------- | -------- | ----------------------------------------------------------------------------------- | | `unidadMedidaVolumen`, `unidadMedidaPeso` | `enum` | Opcionales, nombres del catálogo `unidadMedida` | | `volumenTotal`, `pesoTotal` | `string` | Opcionales, enteros positivos de hasta 20 dígitos, sin ceros iniciales ni decimales | | `caracteristica` | `enum` | `MERCADERIA_CON_CADENA_DE_FRIO`, `CARGA_PELIGROSA` u `OTRO` | | `descripcionCaracteristica` | `string` | Obligatoria sólo para `OTRO`: 1–50 caracteres, sin saltos de línea | Enviá peso y volumen como texto, por ejemplo `"1200"`. Los datos de carga no reemplazan las instrucciones que deban incluirse en `informacionFiscal`. ## Transporte: `transporte` [#transporte-transporte] | Campo | Tipo | Regla | | ----------------------------------------- | -------- | --------------------------------------------------------------------------------------------- | | `tipoTransporte` | `enum` | Obligatorio: `PROPIO` o `TERCERO` | | `modalidad` | `enum` | Obligatoria: `TERRESTRE`, `FLUVIAL`, `AEREO` o `MULTIMODAL` | | `responsableFlete` | `enum` | Obligatorio, valor del catálogo | | `fechaInicioTraslado`, `fechaFinTraslado` | `date` | Obligatorias; el fin no puede preceder al inicio y el inicio debe ser posterior al 22/11/2018 | | `salida` | `object` | Local de salida obligatorio | | `entregas` | `array` | De 1 a 99 locales de entrega | | `vehiculos` | `array` | De 1 a 4 vehículos | | `transportista` | `object` | Obligatorio, incluye los datos del conductor | | `incoterm` | `enum` | Opcional, condición de negociación del catálogo | | `numeroManifiesto` | `string` | Opcional, 1–15 caracteres | | `paisDestino` | `enum` | Opcional, país de tres letras | | `numeroDespachoImportacion` | `string` | Obligatorio para `IMPORTACION`, exactamente 16 caracteres | ### Locales: `salida` y `entregas[]` [#locales-salida-y-entregas] | Campo | Tipo | Regla | | ------------------------------------------------ | --------- | ---------------------------------------------------------- | | `direccion` | `string` | Obligatoria, 1–255 caracteres | | `numeroCasa` | `integer` | Obligatorio, 0–999999; `0` si no tiene número | | `departamento`, `ciudad` | `string` | Obligatorios; ubicaciones paraguayas relacionadas entre sí | | `codigoDistrito` | `integer` | Opcional; debe pertenecer al departamento | | `complementoDireccion1`, `complementoDireccion2` | `string` | Opcionales, 1–255 caracteres cada uno | | `telefono` | `string` | Opcional, 6–15 caracteres | Elegí las ubicaciones del [catálogo geográfico](/docs/referencia/catalogos/geografia). Si una ciudad es ambigua, informá `codigoDistrito`. ### Vehículos: `vehiculos[]` [#vehículos-vehiculos] | Campo | Tipo | Regla | | ---------------------- | --------- | -------------------------------------------------------------------- | | `tipoVehiculo` | `string` | Obligatorio, 4–10 caracteres | | `marca` | `string` | Obligatoria, 1–10 caracteres | | `tipoIdentificacion` | `integer` | Obligatorio: `1` exige número de identificación; `2` exige matrícula | | `numeroIdentificacion` | `string` | 1–20 caracteres | | `matricula` | `string` | 6–7 caracteres | | `datosAdicionales` | `string` | Opcional, 1–20 caracteres | | `numeroVuelo` | `string` | Obligatorio sólo en modalidad `AEREO`, exactamente 6 caracteres | ### Transportista y conductor: `transportista` [#transportista-y-conductor-transportista] | Campo | Tipo | Regla | | -------------------------------------- | ---------------- | ----------------------------------------------------------------------------- | | `naturaleza` | `enum` | Obligatoria: `CONTRIBUYENTE` o `NO_CONTRIBUYENTE` | | `nombreRazonSocial` | `string` | Obligatorio, 4–60 caracteres | | `ruc`, `digitoVerificador` | `string` | Obligatorios para contribuyentes: RUC de 3–8 dígitos y DV válido de un dígito | | `tipoDocumento`, `numeroDocumento` | `enum`, `string` | Obligatorios para no contribuyentes; número de 1–20 caracteres | | `nacionalidad` | `enum` | Opcional, país de tres letras | | `domicilioFiscal` | `string` | Obligatorio, 1–150 caracteres | | `numeroDocumentoConductor` | `string` | Obligatorio, 1–20 caracteres | | `nombreConductor` | `string` | Obligatorio, 4–60 caracteres | | `direccionConductor` | `string` | Obligatoria, 1–255 caracteres | | `nombreAgente` | `string` | 4–60 caracteres | | `rucAgente`, `digitoVerificadorAgente` | `string` | RUC de 3–8 dígitos y DV válido de un dígito | | `direccionAgente` | `string` | 1–255 caracteres | Un transportista contribuyente se identifica con RUC y DV; un no contribuyente, con documento personal. Los cuatro datos del agente deben enviarse juntos si informás alguno o si `responsableFlete` es `AGENTE_INTERMEDIARIO`. El transportista y el conductor son obligatorios también en transporte propio. ## Documentos asociados: `documentosAsociados[]` [#documentos-asociados-documentosasociados] Sólo se asocian facturas. Usá los campos correspondientes a una de estas dos opciones: | Campo | Tipo | Electrónico | Impreso | | ------------------------------------ | -------- | ---------------------------------------------------------- | -------------------------------- | | `tipoDocumento` | `enum` | `ELECTRONICO` | `IMPRESO` | | `cdc` | `string` | Obligatorio, 44 dígitos, con DV válido y prefijo `01` | Se omite | | `rucFusionado` | `string` | Opcional, 3–8 dígitos, debe corresponder al emisor del CDC | Se omite | | `numeroTimbrado` | `string` | Se omite | Obligatorio, 8 dígitos | | `establecimiento`, `puntoExpedicion` | `string` | Se omiten | Obligatorios, 3 dígitos cada uno | | `numeroDocumento` | `string` | Se omite | Obligatorio, 7 dígitos | | `tipoDocumentoImpreso` | `enum` | Se omite | Obligatorio: `FACTURA` | | `fechaEmision` | `date` | Se omite | Obligatoria, `YYYY-MM-DD` | Conservá los ceros iniciales. En `TRASLADO_POR_VENTAS`, si no hay facturas asociadas, informá `fechaFacturaFutura`. ## Ejemplo nacional completo [#ejemplo-nacional-completo] Traslado por consignación dentro de San Lorenzo. Reemplazá las identidades, las fechas y las direcciones por las de la operación real. ```json { "tipoDocumento": "NOTA_DE_REMISION_ELECTRONICA", "fechaEmision": "2026-10-02T08:00:00", "tipoEmision": "NORMAL", "numeroEstablecimiento": 1, "puntoExpedicion": 1, "receptor": { "tipoContribuyente": "NO_CONTRIBUYENTE", "tipoOperacion": "B2C", "tipoDocumento": "CEDULA_PARAGUAYA", "numeroDocumento": "4567890", "nombreRazonSocial": "Ana González", "pais": "PRY", "direccion": "Avenida Mariscal López", "numeroCasa": 450, "departamento": "CENTRAL", "ciudad": "SAN LORENZO" }, "motivoTraslado": "TRASLADO_POR_CONSIGNACION", "responsableEmision": "EMISOR_FACTURA", "kilometrosRecorrido": 8, "items": [ { "codigo": "PAP-A4-75", "descripcion": "Resma de papel A4 de 75 gramos", "cantidad": 100, "unidadMedida": "UNI" } ], "transporte": { "tipoTransporte": "PROPIO", "modalidad": "TERRESTRE", "responsableFlete": "TRANSPORTE_PROPIO", "fechaInicioTraslado": "2026-10-02", "fechaFinTraslado": "2026-10-02", "salida": { "direccion": "Calle Teniente Benítez", "numeroCasa": 120, "departamento": "CENTRAL", "ciudad": "SAN LORENZO" }, "entregas": [ { "direccion": "Avenida Mariscal López", "numeroCasa": 450, "departamento": "CENTRAL", "ciudad": "SAN LORENZO" } ], "vehiculos": [ { "tipoVehiculo": "CAMION", "marca": "ISUZU", "tipoIdentificacion": 2, "matricula": "ABC1234" } ], "transportista": { "naturaleza": "NO_CONTRIBUYENTE", "nombreRazonSocial": "Carlos Benítez", "tipoDocumento": "CEDULA_PARAGUAYA", "numeroDocumento": "3456789", "domicilioFiscal": "Calle Teniente Benítez 120, San Lorenzo", "numeroDocumentoConductor": "3456789", "nombreConductor": "Carlos Benítez", "direccionConductor": "Calle Teniente Benítez 120, San Lorenzo" } } } ``` ## Ejemplo de importación: tramo local [#ejemplo-de-importación-tramo-local] Estos ejemplos describen el tramo paraguayo del traslado. Reemplazá las fechas, las identidades y los datos aduaneros por los de tu operación. El país del receptor y `paisDestino` son datos distintos; las direcciones de salida y entrega siguen siendo paraguayas. ```json { "tipoDocumento": "NOTA_DE_REMISION_ELECTRONICA", "fechaEmision": "2026-10-03T10:00:00", "numeroEstablecimiento": 1, "puntoExpedicion": 1, "tipoEmision": "NORMAL", "receptor": { "tipoContribuyente": "NO_CONTRIBUYENTE", "tipoOperacion": "B2F", "tipoDocumento": "PASAPORTE", "numeroDocumento": "AAB123456", "nombreRazonSocial": "Martín Fernández", "pais": "ARG", "direccion": "Avenida Corrientes", "numeroCasa": 1234 }, "responsableEmision": "EMISOR_FACTURA", "kilometrosRecorrido": 320, "transporte": { "transportista": { "naturaleza": "NO_CONTRIBUYENTE", "nombreRazonSocial": "João Pereira", "tipoDocumento": "PASAPORTE", "numeroDocumento": "FZ123456", "domicilioFiscal": "Rua das Flores 250, Foz do Iguaçu", "numeroDocumentoConductor": "FZ123456", "nombreConductor": "João Pereira", "direccionConductor": "Rua das Flores 250, Foz do Iguaçu" }, "tipoTransporte": "PROPIO", "modalidad": "TERRESTRE", "responsableFlete": "TRANSPORTE_PROPIO", "fechaInicioTraslado": "2026-10-03", "fechaFinTraslado": "2026-10-03", "salida": { "direccion": "Avenida San Blas", "numeroCasa": 150, "departamento": "ALTO PARANA", "ciudad": "CIUDAD DEL ESTE" }, "entregas": [ { "direccion": "Avenida Fernando de la Mora", "numeroCasa": 2300, "departamento": "CENTRAL", "ciudad": "LUQUE" } ], "vehiculos": [ { "tipoVehiculo": "CAMION", "marca": "SCANIA", "tipoIdentificacion": 2, "matricula": "ABCD123" } ], "incoterm": "FOB", "paisDestino": "BRA", "numeroManifiesto": "MAN-2026-004512", "numeroDespachoImportacion": "26005IC04001234K" }, "items": [ { "codigo": "REP-1042", "descripcion": "Repuestos para maquinaria agrícola", "cantidad": 40, "unidadMedida": "UNI" } ], "motivoTraslado": "IMPORTACION" } ``` ## Ejemplo de exportación: tramo local [#ejemplo-de-exportación-tramo-local] ```json { "tipoDocumento": "NOTA_DE_REMISION_ELECTRONICA", "fechaEmision": "2026-10-03T10:00:00", "numeroEstablecimiento": 1, "puntoExpedicion": 1, "tipoEmision": "NORMAL", "receptor": { "tipoContribuyente": "NO_CONTRIBUYENTE", "tipoOperacion": "B2F", "tipoDocumento": "PASAPORTE", "numeroDocumento": "AAB123456", "nombreRazonSocial": "Martín Fernández", "pais": "ARG", "direccion": "Avenida Corrientes", "numeroCasa": 1234 }, "responsableEmision": "EMISOR_FACTURA", "kilometrosRecorrido": 320, "transporte": { "transportista": { "naturaleza": "NO_CONTRIBUYENTE", "nombreRazonSocial": "João Pereira", "tipoDocumento": "PASAPORTE", "numeroDocumento": "FZ123456", "domicilioFiscal": "Rua das Flores 250, Foz do Iguaçu", "numeroDocumentoConductor": "FZ123456", "nombreConductor": "João Pereira", "direccionConductor": "Rua das Flores 250, Foz do Iguaçu" }, "tipoTransporte": "PROPIO", "modalidad": "TERRESTRE", "responsableFlete": "TRANSPORTE_PROPIO", "fechaInicioTraslado": "2026-10-03", "fechaFinTraslado": "2026-10-03", "salida": { "direccion": "Avenida San Blas", "numeroCasa": 150, "departamento": "ALTO PARANA", "ciudad": "CIUDAD DEL ESTE" }, "entregas": [ { "direccion": "Avenida Fernando de la Mora", "numeroCasa": 2300, "departamento": "CENTRAL", "ciudad": "LUQUE" } ], "vehiculos": [ { "tipoVehiculo": "CAMION", "marca": "SCANIA", "tipoIdentificacion": 2, "matricula": "ABCD123" } ], "incoterm": "FOB", "paisDestino": "BRA", "numeroManifiesto": "MAN-2026-004512" }, "items": [ { "codigo": "REP-1042", "descripcion": "Repuestos para maquinaria agrícola", "cantidad": 40, "unidadMedida": "UNI" } ], "motivoTraslado": "EXPORTACION" } ``` ## Consultar el resultado [#consultar-el-resultado] La emisión devuelve `202 Accepted`, el CDC y las URLs de seguimiento. Guardá esos datos y [consultá el estado](/docs/guias/consultar-estado). En la respuesta de estado, `iTiDe` vale `7`. Si la nota está `APROBADO` o `APROBADO_OBSERVACION`, [descargá el KuDE](/docs/guias/descargar-kude) para acompañar la mercadería. Si está `RECHAZADO`, corregí el motivo antes de emitir otra. Un timeout o un estado `ERROR` requiere revisar el documento existente; no emitas otra nota para forzar el resultado. # Receptor (/docs/referencia/modelos/receptor) El objeto `receptor` identifica al destinatario del documento electrónico. Su estructura cambia según el tipo de operación: B2C (consumidor final), B2B (otro contribuyente con RUC), B2G (organismo público) o B2F (cliente del exterior). ## Schema [#schema] | Campo | Tipo | Requerido | Descripción | | --------------------------- | --------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `tipoContribuyente` | `enum` | Sí | `CONTRIBUYENTE` o `NO_CONTRIBUYENTE`. Únicos dos valores. Siempre obligatorio, en toda operación | | `tipoOperacion` | `enum` | Sí | `B2B`, `B2C`, `B2G`, `B2F`. Un receptor `NO_CONTRIBUYENTE` sólo admite `B2C` o `B2F` | | `tipoContribuyenteReceptor` | `enum` | Condicional | `PERSONA_FISICA` o `PERSONA_JURIDICA` — **obligatorio cuando `tipoContribuyente = CONTRIBUYENTE`**; no se envía cuando es `NO_CONTRIBUYENTE` (SIFEN lo rechaza con el código 1303) | | `tipoDocumento` | `enum` | Condicional | `CEDULA_PARAGUAYA`, `PASAPORTE`, `CEDULA_EXTRANJERA`, `CARNET_DE_RESIDENCIA`, `INNOMINADO`, `TARJETA_DIPLOMATICA`, `OTRO` — requerido cuando `tipoContribuyente = NO_CONTRIBUYENTE`; no se envía cuando es `CONTRIBUYENTE` | | `numeroDocumento` | `string` | Sí, salvo en B2F | RUC base (sin DV), número de CI, pasaporte, etc. El RUC lleva de 3 a 8 caracteres, sin guion ni cero inicial (por ejemplo `80012345`). Para el caso innominado se envía el literal `"0"`. En B2F es opcional; si se envía, no puede estar vacío | | `nombreRazonSocial` | `string` | Sí | Nombre completo o razón social, de 4 a 255 caracteres. Para el caso innominado se envía el literal `"Sin Nombre"` | | `digitoVerificador` | `string` | Condicional | DV del RUC, un solo dígito — **obligatorio cuando `tipoContribuyente = CONTRIBUYENTE`**. Debe corresponder al RUC informado (módulo 11) | | `descripcionTipoDocumento` | `string` | Con `OTRO` | De 9 a 41 caracteres; obligatoria y exclusiva de `tipoDocumento = OTRO` | | `nombreFantasia` | `string` | No | Nombre de fantasía, de 4 a 255 caracteres; se informa además de `nombreRazonSocial` | | `direccion` | `string` | Condicional | Hasta 255 caracteres. Opcional para B2B / B2C / B2G. Obligatoria solo para Nota de Remisión Electrónica (NRE) y operaciones B2F (cliente del exterior con `tipoOperacion = B2F`). | | `numeroCasa` | `integer` | Condicional | Número de casa, `0` si no tiene; obligatorio para B2F y en una FE que informa `direccion` | | `departamento` | `string` | No | Departamento del catálogo de [geografía](/docs/referencia/catalogos/geografia); en una FE se informa junto con `ciudad` | | `codigoDistrito` | `integer` | No | Código del distrito (catálogo geográfico SIFEN) | | `ciudad` | `string` | No | Ciudad; en una FE se informa junto con `departamento`, y la combinación debe existir en el catálogo | | `telefono` | `string` | No | Teléfono fijo, de 6 a 15 caracteres | | `celular` | `string` | No | Teléfono móvil, de 10 a 20 caracteres | | `email` | `string` | No | Email, de 3 a 80 caracteres — Sifende lo usa para enviar el KuDE automáticamente si está configurado | | `codigoCliente` | `string` | No | Código libre del emisor para identificar al cliente, de 3 a 15 caracteres. SIFEN no aplica validaciones de negocio y no lo muestra en el KuDE | | `pais` | `enum` | No | Por defecto `PRY`. B2B, B2C y B2G exigen `PRY`; B2F exige el código ISO de un país distinto de `PRY` | Las reglas condicionales de esta tabla están expresadas como `if`/`then` en el [spec OpenAPI](/docs/referencia/openapi), así que se pueden validar localmente antes de mandar la solicitud. ## Reglas clave [#reglas-clave] * **B2B:** No envíes `tipoDocumento`. El receptor se identifica por `tipoOperacion: "B2B"` + `tipoContribuyente: "CONTRIBUYENTE"` + `tipoContribuyenteReceptor` + `numeroDocumento` (RUC) + `digitoVerificador`. Los tres últimos son obligatorios: sin `tipoContribuyenteReceptor` o sin `digitoVerificador` la API responde `400 validation-error`. La `direccion` es opcional. * **B2C:** `tipoContribuyente = NO_CONTRIBUYENTE` y generalmente `tipoDocumento = CEDULA_PARAGUAYA`. Para el receptor innominado (sin identificación) se usa `tipoDocumento = INNOMINADO` con `numeroDocumento: "0"` y `nombreRazonSocial: "Sin Nombre"` — ambos siguen siendo obligatorios. Sólo se permite en Factura Electrónica, no en Nota de Crédito ni de Débito. La `direccion` es opcional. * **B2G (gobierno):** `tipoOperacion = B2G`, `tipoContribuyente = CONTRIBUYENTE` y `pais = PRY`. Exige `numeroDocumento` con el RUC de 3 a 8 caracteres sin cero inicial, con una letra final A-D opcional, `digitoVerificador` de un dígito y `tipoContribuyenteReceptor`. No envíes `tipoDocumento`. La `direccion` es opcional. Ver [Compras públicas](/docs/referencia/modelos/factura-electronica#compras-públicas). * **B2F (exterior):** Usar `tipoContribuyente = NO_CONTRIBUYENTE`, `tipoDocumento = PASAPORTE` (o `CEDULA_EXTRANJERA`, `CARNET_DE_RESIDENCIA`, `TARJETA_DIPLOMATICA`, `OTRO`) y `pais` con el código ISO correspondiente. El país debe ser distinto de `PRY`; `direccion` y `numeroCasa` son obligatorios. `numeroDocumento` es opcional: si el cliente no tiene un número para informar, omití el campo. Omití `departamento`, `ciudad`, `codigoDistrito`, `digitoVerificador` y `tipoContribuyenteReceptor`. En una FE, B2F sólo admite `tipoTransaccion = PRESTACION_SERVICIOS`; `VENTA_MERCADERIA` recibe `400 validation-error`. * **Nota de Remisión Electrónica (NRE):** la `direccion` del receptor es obligatoria porque la NRE documenta un traslado físico de mercadería. ## Departamento y ciudad [#departamento-y-ciudad] `departamento`, `codigoDistrito` y `ciudad` se resuelven contra el catálogo de [geografía](/docs/referencia/catalogos/geografia): * `departamento` acepta el `name` de la categoría `departamento` de [`/public/enums`](/docs/referencia/catalogos/enumeraciones) (`PTE_HAYES`), el nombre del catálogo (`PTE. HAYES`) o el código como texto (`"15"`). * `ciudad` acepta el `nombre` o el `codigo` (como texto) de una ciudad del catálogo. Si el nombre del catálogo termina en un calificador entre paréntesis, podés omitirlo: `"Asunción"` resuelve `ASUNCION (DISTRITO)`. * En los nombres no importan mayúsculas, tildes, puntos ni guiones bajos. * Si el nombre coincide con más de una ciudad del departamento, la API responde `400 validation-error`. En `errores["receptor.ciudad"]` lista las opciones con su `codigoDistrito` y su código. Enviá `codigoDistrito` o el código de la ciudad. * SIFEN admite hasta 30 caracteres en la descripción de la ciudad. Si el nombre del catálogo es más largo, el documento lo lleva recortado. ## Ejemplos [#ejemplos] ```json { "receptor": { "tipoContribuyente": "NO_CONTRIBUYENTE", "tipoOperacion": "B2C", "tipoDocumento": "CEDULA_PARAGUAYA", "numeroDocumento": "1234567", "nombreRazonSocial": "Juan Pérez", "email": "juan.perez@example.com.py" } } ``` ```json { "receptor": { "tipoContribuyente": "NO_CONTRIBUYENTE", "tipoOperacion": "B2C", "tipoDocumento": "INNOMINADO", "numeroDocumento": "0", "nombreRazonSocial": "Sin Nombre" } } ``` Los literales `"0"` y `"Sin Nombre"` los define el Manual Técnico de SIFEN para el caso innominado: no son valores de relleno, tienen que ir exactamente así. ```json { "receptor": { "tipoContribuyente": "CONTRIBUYENTE", "tipoOperacion": "B2B", "tipoContribuyenteReceptor": "PERSONA_JURIDICA", "numeroDocumento": "80054321", "digitoVerificador": "1", "nombreRazonSocial": "Distribuidora Asunción S.R.L.", "codigoCliente": "CLI-001", "direccion": "Av. Mariscal López", "numeroCasa": 1234, "departamento": "CAPITAL", "ciudad": "Asunción", "email": "facturacion@distribuidora-asuncion.com.py" } } ``` ```json { "receptor": { "tipoContribuyente": "NO_CONTRIBUYENTE", "tipoOperacion": "B2F", "tipoDocumento": "PASAPORTE", "numeroDocumento": "AB1234567", "nombreRazonSocial": "John Smith", "direccion": "1234 Main Street, Miami, FL 33101", "numeroCasa": 1234, "pais": "USA" } } ``` ## Próximos pasos [#próximos-pasos] * [Guía: Receptor B2B vs B2C](/docs/guias/receptor-b2b-b2c) * [Concepto: Receptor](/docs/conceptos/receptor) # Detalle de Evento (/docs/referencia/eventos/detalle) ## GET /eventos/:eventoId [#get-eventoseventoid] Devuelve el detalle completo de un evento SIFEN, incluyendo el protocolo de autorización si SIFEN lo confirmó. ### Autenticación y ruta [#autenticación-y-ruta] ```text GET /api/v1/documento-electronico/eventos/{eventoId} ``` `Authorization: Bearer {api-key}`. La clave determina el contribuyente y el ambiente. ### Path parameters [#path-parameters] | Parámetro | Tipo | Descripción | | ---------- | --------- | -------------------------- | | `eventoId` | `integer` | `eventoSifenId` del evento | ### Respuesta exitosa [#respuesta-exitosa] **Status:** `200 OK` Devuelve el objeto del evento (mismos campos que [Listar Eventos](/docs/referencia/eventos/listar)). #### Ejemplo — evento de CANCELACION confirmado [#ejemplo--evento-de-cancelacion-confirmado] ```json { "eventoSifenId": 1024, "documentoElectronicoId": 8821, "contribuyenteId": 42, "tipoEvento": "CANCELACION", "estadoEvento": "APROBADO", "cdc": "01800123451001001000000122026042710000000006", "motivo": "Error en datos del cliente", "protocoloAutorizacion": "20260427143218000", "codigoRespuesta": "0600", "mensajeRespuesta": "Evento de cancelación registrado exitosamente", "fechaCreacion": "2026-04-27T14:32:18", "fechaProcesamiento": "2026-04-27T14:32:45", "ambiente": "DEV" } ``` #### Ejemplo — evento de INUTILIZACION pendiente [#ejemplo--evento-de-inutilizacion-pendiente] ```json { "eventoSifenId": 1025, "documentoElectronicoId": null, "contribuyenteId": 42, "tipoEvento": "INUTILIZACION", "estadoEvento": "PENDIENTE", "cdc": null, "motivo": "Numeración no utilizada por error de sistema", "protocoloAutorizacion": null, "codigoRespuesta": null, "mensajeRespuesta": null, "fechaCreacion": "2026-04-27T15:01:09", "fechaProcesamiento": null, "numeroTimbrado": 12557896, "establecimiento": "001", "puntoExpedicion": "001", "numeroInicio": "0000025", "numeroFin": "0000030", "tipoDocumento": 1, "serieNumero": null, "ambiente": "DEV" } ``` ### Cuándo aparece `protocoloAutorizacion` [#cuándo-aparece-protocoloautorizacion] El campo se completa **solo cuando SIFEN confirma el evento** con un protocolo. El código `0600` indica que el evento quedó registrado. Un resultado `APROBADO` también puede corresponder a una cancelación ya registrada (`4003`); en ese caso el protocolo puede ser `null`. Si el evento todavía está `PENDIENTE`, `protocoloAutorizacion`, `codigoRespuesta` y `mensajeRespuesta` serán `null`. ### Errores [#errores] | Status | Tipo | Descripción | | ------ | ------------------ | ------------------------------------------------------- | | 401 | — | API key inválida | | 404 | `evento-not-found` | El `eventoId` no existe o no pertenece al contribuyente | ### Ejemplo [#ejemplo] ```bash curl https://api.sifende.com.py/api/v1/documento-electronico/eventos/1024 \ -H "Authorization: Bearer $API_KEY" ``` # Eventos SIFEN (/docs/referencia/eventos) Los eventos SIFEN permiten enviar una **cancelación** de documento, una **inutilización** de numeración o una **nominación** de factura innominada. ## Endpoints [#endpoints] | Método | Path | Descripción | | ------ | -------------------------------------------- | ------------------------------------------------------------ | | `GET` | `/api/v1/documento-electronico/eventos` | [Listar eventos](/docs/referencia/eventos/listar) | | `GET` | `/api/v1/documento-electronico/eventos/{id}` | [Ver detalle de un evento](/docs/referencia/eventos/detalle) | Para **enviar** eventos, ver [Cancelar Documento](/docs/referencia/documentos-electronicos/cancelar), [Inutilizar Numeración](/docs/referencia/documentos-electronicos/inutilizar) y [Nominar una factura](/docs/referencia/documentos-electronicos/nominar). # Listar Eventos (/docs/referencia/eventos/listar) ## GET /eventos [#get-eventos] Lista los eventos SIFEN —cancelaciones, inutilizaciones y nominaciones— enviados desde la API. Soporta paginación y filtrado por tipo. ### Autenticación y ruta [#autenticación-y-ruta] ```text GET /api/v1/documento-electronico/eventos ``` `Authorization: Bearer {api-key}`. La clave determina el contribuyente y el ambiente. ### Query parameters [#query-parameters] | Parámetro | Tipo | Default | Descripción | | ------------ | --------- | ------- | -------------------------------------------------------------- | | `page` | `integer` | `0` | Página solicitada (base 0) | | `size` | `integer` | `10` | Cantidad de elementos por página | | `tipoEvento` | `string` | — | Filtra por tipo: `CANCELACION`, `INUTILIZACION` o `NOMINACION` | ### Respuesta exitosa [#respuesta-exitosa] **Status:** `200 OK` La respuesta contiene directamente `content`, `page`, `size`, `totalElements` y `totalPages`. ```json { "content": [ { "eventoSifenId": 1024, "documentoElectronicoId": 8821, "contribuyenteId": 42, "tipoEvento": "CANCELACION", "estadoEvento": "APROBADO", "cdc": "01800123451001001000000122026042710000000006", "motivo": "Error en datos del cliente", "protocoloAutorizacion": "20260427143218000", "codigoRespuesta": "0600", "mensajeRespuesta": "Evento de cancelación registrado exitosamente", "fechaCreacion": "2026-04-27T14:32:18", "fechaProcesamiento": "2026-04-27T14:32:45", "ambiente": "DEV" } ], "totalElements": 87, "totalPages": 9, "size": 10, "page": 0 } ``` ### Campos del evento [#campos-del-evento] | Campo | Tipo | Descripción | | ------------------------ | ---------------- | ------------------------------------------------------------------------- | | `eventoSifenId` | `integer` | Identificador del evento | | `documentoElectronicoId` | `integer\|null` | DE asociado (null en inutilizaciones) | | `contribuyenteId` | `integer` | Contribuyente emisor del evento | | `ambiente` | `string` | Ambiente de la operación: `DEV` o `PROD` | | `tipoEvento` | `enum` | `CANCELACION`, `INUTILIZACION` o `NOMINACION` | | `estadoEvento` | `enum` | `PENDIENTE`, `ENVIADO`, `APROBADO`, `RECHAZADO`, `ERROR`, `INDETERMINADA` | | `cdc` | `string\|null` | CDC del documento (cancelación o nominación) | | `motivo` | `string` | Motivo declarado al enviar el evento | | `protocoloAutorizacion` | `string\|null` | Número de protocolo SIFEN cuando se confirma | | `codigoRespuesta` | `string\|null` | Código de respuesta SIFEN | | `mensajeRespuesta` | `string\|null` | Mensaje SIFEN | | `fechaCreacion` | `datetime` | Fecha de envío del evento | | `fechaProcesamiento` | `datetime\|null` | Fecha de respuesta de SIFEN | #### Solo en `tipoEvento = INUTILIZACION` [#solo-en-tipoevento--inutilizacion] | Campo | Tipo | Descripción | | ----------------- | -------------- | ---------------------------------------------------- | | `numeroTimbrado` | `integer` | Timbrado del rango inutilizado | | `establecimiento` | `string` | Establecimiento (3 dígitos) | | `puntoExpedicion` | `string` | Punto de expedición (3 dígitos) | | `numeroInicio` | `string` | Primer número del rango | | `numeroFin` | `string` | Último número del rango | | `tipoDocumento` | `integer` | Código numérico del tipo de documento (ej. `1` = FE) | | `serieNumero` | `string\|null` | Serie utilizada (si aplica) | ### Errores [#errores] | Status | Tipo | Descripción | | ------ | ---- | ---------------- | | 401 | — | API key inválida | ### Ejemplo [#ejemplo] ```bash curl "https://api.sifende.com.py/api/v1/documento-electronico/eventos?page=0&size=20&tipoEvento=CANCELACION" \ -H "Authorization: Bearer $API_KEY" ``` # Webhooks (/docs/referencia/webhooks) Los webhooks notifican cambios de documentos y lotes. Se configuran por contribuyente y ambiente desde **Webhooks** en el panel. Mantené las consultas de estado como respaldo operativo: la entrega es *at-least-once* y un receptor debe tolerar duplicados. ## Eventos [#eventos] | Tipo | Cuándo se emite | | ----------------------------------------- | ------------------------------------------------------------ | | `documento.aprobado` | SIFEN aprueba un documento. | | `documento.rechazado` | SIFEN rechaza un documento. | | `documento.cancelado` | SIFEN acepta la cancelación de un documento. | | [`lote.procesado`](/docs/conceptos/lotes) | Todos los documentos de un lote alcanzan un resultado final. | Cada endpoint elige uno o más eventos y un ambiente inmutable (`DEV`, `PROD` o `SANDBOX`). Un contribuyente puede tener hasta cinco endpoints activos por ambiente. La URL debe usar HTTPS; no se siguen redirects. Los eventos nuevos se entregan únicamente a endpoints de su ambiente (`DEV`, `PROD` o `SANDBOX`). Ese ambiente queda fijo: para escuchar otro, [creá otro endpoint](/docs/panel/webhooks). Podés registrar la misma URL en ambientes distintos; cada endpoint tiene su propio secreto. En SANDBOX también se entrega `documento.aprobado`, con un protocolo `SBX-` seguido del CDC, a los endpoints de SANDBOX suscritos a ese evento. No representa una aprobación de SIFEN. ## Sobre del evento [#sobre-del-evento] Todos los payloads usan la versión `1`: ```json { "id": "d44f9f47-380f-4f51-b5c9-4fa335711e18", "tipo": "documento.aprobado", "version": "1", "ocurridoEn": "2026-08-13T15:00:00Z", "contribuyenteId": 42, "ambiente": "PROD", "data": { "documentoId": "41de310e-1374-4593-bce4-7c27638ee99a", "cdc": "01800123451001001000000122026042710000000006", "estado": "APROBADO", "loteId": 815, "protocoloAutorizacion": "123456789", "resultados": [] } } ``` `ambiente` identifica el ambiente del documento o lote: `DEV`, `PROD` o `SANDBOX`. Las notificaciones nuevas incluyen este campo en la raíz. Las entregas creadas antes de su incorporación conservan su payload y destinatario originales, incluso en un reintento. Pueden no incluir `ambiente` y corresponder a un ambiente distinto del que muestra hoy el endpoint. `documento.aprobado` y `documento.rechazado` incluyen `documentoId`, `cdc`, `estado`, `loteId`, `protocoloAutorizacion` y `resultados`. `documento.cancelado` incluye `documentoId`, `cdc`, `estado`, `eventoSifenId`, `motivo`, `codigoRespuesta`, `mensajeRespuesta` y `protocoloAutorizacion`. El objeto `data` de `lote.procesado` contiene: | Campo | Contenido | | ------------------------- | ---------------------------------------------------------------------------------------------- | | `loteId`, `numeroLote` | Identificadores del envío | | `estado` | `"PROCESADO"` | | `aprobados` | Cantidad de documentos aprobados | | `aprobadosConObservacion` | Cantidad de documentos aprobados con observaciones | | `rechazados` | Cantidad de documentos rechazados | | `documentos` | Lista con `documentoId`, `cdc`, `estado`, `protocoloAutorizacion` y `resultados` por documento | ## Headers [#headers] | Header | Contenido | | ----------------------- | ----------------------------------------------- | | `X-Sifende-Event-Id` | UUID estable del evento; usalo para deduplicar. | | `X-Sifende-Event-Type` | Tipo del evento. | | `X-Sifende-Delivery-Id` | UUID de la entrega a un endpoint. | | `X-Sifende-Timestamp` | Unix timestamp en segundos usado en la firma. | | `X-Sifende-Signature` | `v1=` seguido del HMAC-SHA256 en Base64. | ## Verificar la firma [#verificar-la-firma] El secreto `whsec_…` se muestra sólo al crear o rotar el endpoint. Guardalo en un gestor de secretos. La firma se calcula sobre bytes, no sobre un JSON parseado o reserializado: ```text mensaje = eventId + "." + deliveryId + "." + timestamp + "." + rawBody firma = "v1=" + Base64(HMAC-SHA256(secret, mensaje)) ``` Ejemplo en Node.js: ```js import { createHmac, timingSafeEqual } from 'node:crypto'; export function verificarWebhook({ rawBody, headers, secret }) { const eventId = headers['x-sifende-event-id']; const deliveryId = headers['x-sifende-delivery-id']; const timestamp = headers['x-sifende-timestamp']; const recibida = headers['x-sifende-signature']; const prefijo = Buffer.from(`${eventId}.${deliveryId}.${timestamp}.`); const mensaje = Buffer.concat([prefijo, rawBody]); const esperada = `v1=${createHmac('sha256', secret).update(mensaje).digest('base64')}`; return recibida.length === esperada.length && timingSafeEqual(Buffer.from(recibida), Buffer.from(esperada)); } ``` Validá también que `X-Sifende-Timestamp` esté dentro de una ventana razonable y rechazá firmas fuera de esa ventana. Capturá el cuerpo crudo antes de cualquier middleware JSON. ## Respuestas y reintentos [#respuestas-y-reintentos] Respondé rápido con cualquier estado `2xx`. Sifende clasifica los resultados así: | Resultado | Comportamiento | | -------------------------------- | ------------------------------------------------- | | `200–299` | Entrega completada. | | Error de red, DNS, TLS o timeout | Se reintenta. | | `408`, `425`, `429`, `500–599` | Se reintenta con backoff. | | `300–399` | Falla permanente; los redirects están bloqueados. | | Otros `400–499` | Falla permanente. | Los reintentos pueden durar hasta 24 horas, con backoff entre 10 segundos y una hora. Una entrega puede repetirse; deduplicá por `X-Sifende-Event-Id`. ## Ciclo de vida e historial [#ciclo-de-vida-e-historial] Editar la URL, las suscripciones o el secreto afecta también a las entregas pendientes. Desactivar o eliminar un endpoint cancela sus entregas no terminales. El historial muestra estado, HTTP, error e intentos durante 90 días. Para crear, editar o desactivar endpoints, seguí la [guía de webhooks del panel](/docs/panel/webhooks). # Emitir un documento electrónico (/docs/referencia/api/emitir-documento) # Nominar el receptor de una factura innominada (/docs/referencia/api/nominarByCdc) # Cancelar un documento (/docs/referencia/api/cancelar-documento) # Inutilizar un rango de numeración (/docs/referencia/api/inutilizar-numeracion) # Listar todas las enumeraciones de SIFEN (/docs/referencia/api/listar-enumeraciones) # Consultar un RUC o cédula en el padrón (/docs/referencia/api/consultar-padron) # Listar ciudades de un distrito (/docs/referencia/api/listar-ciudades) # Listar departamentos (/docs/referencia/api/listar-departamentos) # Listar distritos de un departamento (/docs/referencia/api/listar-distritos) # Listar ciudades de un departamento (/docs/referencia/api/listar-ciudades-departamento) # Descargar el KuDE en PDF (/docs/referencia/api/descargar-kude) # Consultar el estado de un documento (/docs/referencia/api/consultar-estado) # Consultar plan y consumo (ruta deprecada) (/docs/referencia/api/consultar-plan-consumo-deprecado) # Listar eventos del contribuyente (/docs/referencia/api/listar-eventos) # Consultar un evento por su id (/docs/referencia/api/consultar-evento) # Consultar el contribuyente emisor (/docs/referencia/api/consultar-contribuyente) # Consultar plan y consumo (/docs/referencia/api/consultar-plan-consumo) # Especificación OpenAPI (https://www.sifende.com.py/openapi/v1.json) Contrato de la API generado desde el código. Es la fuente de verdad: si algo de la documentación de arriba lo contradice, vale lo que dice este documento. Los requisitos condicionales están expresados en el schema como `if`/`then`, así que se pueden validar antes de mandar el request. El caso más frecuente es `ReceptorDTO`: `tipoContribuyenteReceptor` y `digitoVerificador` son obligatorios cuando `tipoContribuyente = CONTRIBUYENTE`, y `tipoDocumento` lo es cuando es `NO_CONTRIBUYENTE`. Cada modelo también está publicado como JSON Schema suelto en `https://www.sifende.com.py/schemas/v1/{Modelo}.json` (por ejemplo `FacturaElectronicaRequest.json`), con las dependencias inlineadas en `$defs`. ```json { "openapi": "3.1.0", "info": { "title": "Sifende API", "description": "API de facturación electrónica para Paraguay (SIFEN).\n\nEste documento se genera desde el código de la API, así que describe lo que la API\nrealmente acepta y devuelve. Ante una contradicción con la documentación escrita, vale\nlo que dice acá.\n\n**Emisión asíncrona.** `POST /api/v1/documento-electronico` responde `202 Accepted` con\nel CDC ya calculado y `estado: PENDIENTE`. El envío a SIFEN ocurre en segundo plano;\nel estado final se consulta con `GET /api/v1/documento-electronico/status/{cdc}`.\n\n**Ambientes.** La URL base es la misma para DEV, PROD y SANDBOX. Cada API key conserva\nun ambiente inmutable persistido. Las claves nuevas usan `sk_test_`, `sk_live_` y\n`sk_sandbox_`, respectivamente; las claves legacy conservan su valor y nunca se rutean\ninfiriendo el ambiente desde el prefijo. SANDBOX no llama a SIFEN y autoaprueba localmente.\n\n**Errores.** Todas las respuestas de error son `application/problem+json`\n([RFC 9457](https://www.rfc-editor.org/rfc/rfc9457)), con `type` apuntando a la página de\nla documentación que explica ese error concreto.\n\n**Alcance.** Sólo la API de integración y los catálogos públicos. Los endpoints del\npanel web, que se autentican con Keycloak, no son parte de este contrato.\n", "contact": { "name": "Soporte Sifende", "url": "https://sifende.com.py/docs", "email": "soporte@sifende.com.py" }, "version": "v1" }, "externalDocs": { "description": "Documentación de Sifende", "url": "https://sifende.com.py/docs" }, "servers": [ { "url": "https://api.sifende.com.py", "description": "DEV, PROD y SANDBOX — el ambiente está persistido en la API key" } ], "security": [ { "apiKey": [] } ], "tags": [ { "name": "Catálogos", "description": "Datos de referencia de SIFEN. No requieren autenticación." }, { "name": "Padrón", "description": "Consulta de contribuyentes y ciudadanos por RUC o cédula." }, { "name": "Contribuyente", "description": "Datos y plan del contribuyente identificado por la API key." }, { "name": "Documentos electrónicos", "description": "API de integración: emisión, consulta de estado, KuDE y eventos. Se autentica con API key, que además identifica al contribuyente emisor." } ], "paths": { "/api/v1/documento-electronico": { "post": { "tags": [ "Documentos electrónicos" ], "summary": "Emitir un documento electrónico", "description": "Registra el documento y lo encola para SIFEN. La respuesta es inmediata y el CDC ya\nviene calculado, pero el envío ocurre en segundo plano: `estado` es siempre\n`PENDIENTE` acá. El estado final se consulta con el `statusUrl` de la respuesta.\n\nEl emisor no se envía en el body: sale de la API key. El timbrado y el correlativo\nlos asigna Sifende.\n", "operationId": "emitir-documento", "parameters": [ { "name": "Idempotency-Key", "in": "header", "description": "Clave opcional para identificar una intención idempotente en operaciones compatibles.\nAcepta un solo valor de 1 a 255 caracteres ASCII visibles, sin espacios al inicio ni al final.\nEl alcance es por contribuyente y ambiente, compartido entre los tipos de operación.\nUna clave existente resuelve la operación original sin comparar el body ni el CDC posterior.\nOtro tipo de operación devuelve 422. El cliente debe persistir la clave y la solicitud original\ny generar una clave nueva para cada intención nueva. El replay dura 7 días desde la finalización;\ndespués la clave sigue reservada hasta que termina la conservación del documento.\nLa solicitud debe poder deserializarse; los campos del body se validan sólo para operaciones nuevas.\n", "required": false, "schema": { "type": "string", "maxLength": 255, "minLength": 1, "pattern": "^[!-~](?:[ -~]{0,253}[!-~])?$" }, "example": "550e8400-e29b-41d4-a716-446655440000" } ], "requestBody": { "content": { "application/json": { "schema": { "oneOf": [ { "$ref": "#/components/schemas/FacturaElectronicaRequest" }, { "$ref": "#/components/schemas/NotaCreditoElectronicaRequest" }, { "$ref": "#/components/schemas/NotaDebitoElectronicaRequest" }, { "$ref": "#/components/schemas/NotaRemisionElectronicaRequest" }, { "$ref": "#/components/schemas/AutofacturaElectronicaRequest" } ] } } }, "required": true }, "responses": { "202": { "description": "Documento registrado y encolado. `Location` apunta al `statusUrl`", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DocumentoElectronicoEmisionResponseDTO" }, "example": { "id": "550e8400-e29b-41d4-a716-446655440000", "deId": 4821, "cdc": "01800123451001001000000122026042710000000006", "estado": "PENDIENTE", "tipoDocumento": "FACTURA_ELECTRONICA", "iTiDe": 1, "numeroDocumento": 122, "numeroFormateado": "001-001-0000122", "fechaCreacion": "2026-04-27T10:30:00", "qrUrl": "https://ekuatia.set.gov.py/consultas-test/qr?nVersion=150&Id=018001234510010010000001220260427100000000006", "statusUrl": "https://api.sifende.com.py/api/v1/documento-electronico/status/01800123451001001000000122026042710000000006", "kudeUrl": "https://api.sifende.com.py/api/v1/documento-electronico/01800123451001001000000122026042710000000006/kude" } } } }, "400": { "$ref": "#/components/responses/IdempotencyBadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/DocumentQuotaExceeded" }, "404": { "$ref": "#/components/responses/NotFound" }, "409": { "$ref": "#/components/responses/IdempotencyConflict" }, "422": { "$ref": "#/components/responses/EmissionUnprocessableEntity" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/IdempotencyUnavailable" } } } }, "/api/v1/documento-electronico/{cdc}/nominar": { "post": { "tags": [ "evento-controller" ], "summary": "Nominar el receptor de una factura innominada", "description": "Nominación síncrona B2B/B2C/B2F. La consulta de confirmación y, si se confirma\nausencia, como máximo un reenvío ocurren dentro de esta petición.\nUn resultado incierto conserva ENVIADO y responde 503 con Retry-After;\nno equivale a aprobación ni rechazo y no inicia recuperación en segundo plano.\nSólo APROBADO aporta el receptor efectivo para la precarga de NCE/NDE en el panel.\n El XML firmado, CDC y KuDE originales no se modifican.\n Idempotency-Key es opcional, con alcance por contribuyente y ambiente compartido entre operaciones.\n Una clave existente recupera el documento, motivo y receptor originales, sin comparar\n el body ni el CDC posterior, incluso si el documento quedó archivado.\n Otro tipo de operación devuelve 422. Persistí la clave y la solicitud original;\n usá una clave nueva para cada intención nueva. El replay dura 7 días desde la finalización.\n La clave sigue reservada después, hasta que termina la conservación del documento.\n El body debe poder deserializarse; sus campos se validan sólo para operaciones nuevas.\n SANDBOX responde 422 sin registrar ni enviar un evento.\n", "operationId": "nominarByCdc", "parameters": [ { "name": "cdc", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "Idempotency-Key", "in": "header", "required": false, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EventoNominacionRequest" } } }, "required": true }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { "$ref": "#/components/schemas/EventoSifenDTO" } } } } } } }, "/api/v1/documento-electronico/{cdc}/cancelar": { "post": { "tags": [ "Documentos electrónicos" ], "summary": "Cancelar un documento", "description": " Envía a SIFEN el evento de cancelación. Sólo se puede cancelar un documento aprobado\n y dentro del plazo que fija SIFEN. Una respuesta `4003` se trata como éxito equivalente\n porque SIFEN ya tiene registrada una cancelación para el CDC. SANDBOX responde `422`.\n", "operationId": "cancelar-documento", "parameters": [ { "name": "cdc", "in": "path", "description": "CDC del documento a cancelar, 44 dígitos", "required": true, "schema": { "type": "string" }, "example": "01800123451001001000000122026042710000000006" }, { "name": "Idempotency-Key", "in": "header", "description": "Clave opcional para identificar una intención idempotente en operaciones compatibles.\nAcepta un solo valor de 1 a 255 caracteres ASCII visibles, sin espacios al inicio ni al final.\nEl alcance es por contribuyente y ambiente, compartido entre los tipos de operación.\nUna clave existente resuelve la operación original sin comparar el body ni el CDC posterior.\nOtro tipo de operación devuelve 422. El cliente debe persistir la clave y la solicitud original\ny generar una clave nueva para cada intención nueva. El replay dura 7 días desde la finalización;\ndespués la clave sigue reservada hasta que termina la conservación del documento.\nLa solicitud debe poder deserializarse; los campos del body se validan sólo para operaciones nuevas.\n", "required": false, "schema": { "type": "string", "maxLength": 255, "minLength": 1, "pattern": "^[!-~](?:[ -~]{0,253}[!-~])?$" }, "example": "550e8400-e29b-41d4-a716-446655440000" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CancelacionRequest" } } }, "required": true }, "responses": { "200": { "description": "Evento de cancelación registrado", "content": { "*/*": { "schema": { "$ref": "#/components/schemas/EventoSifenDTO" } } } }, "400": { "$ref": "#/components/responses/IdempotencyBadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/DocumentArchived" }, "404": { "$ref": "#/components/responses/NotFound" }, "409": { "$ref": "#/components/responses/IdempotencyConflict" }, "422": { "$ref": "#/components/responses/IdempotencyKeyReused" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/IdempotencyUnavailable" } } } }, "/api/v1/documento-electronico/inutilizar": { "post": { "tags": [ "Documentos electrónicos" ], "summary": "Inutilizar un rango de numeración", "description": " Informa a SIFEN que un rango de números de un timbrado no se va a usar. Una respuesta\n `4066` deja el resultado terminal `INDETERMINADA` y bloquea nuevos envíos para proteger\n el rango. SANDBOX responde `422` sin registrar ni enviar un evento.\n", "operationId": "inutilizar-numeracion", "parameters": [ { "name": "Idempotency-Key", "in": "header", "description": "Clave opcional para identificar una intención idempotente en operaciones compatibles.\nAcepta un solo valor de 1 a 255 caracteres ASCII visibles, sin espacios al inicio ni al final.\nEl alcance es por contribuyente y ambiente, compartido entre los tipos de operación.\nUna clave existente resuelve la operación original sin comparar el body ni el CDC posterior.\nOtro tipo de operación devuelve 422. El cliente debe persistir la clave y la solicitud original\ny generar una clave nueva para cada intención nueva. El replay dura 7 días desde la finalización;\ndespués la clave sigue reservada hasta que termina la conservación del documento.\nLa solicitud debe poder deserializarse; los campos del body se validan sólo para operaciones nuevas.\n", "required": false, "schema": { "type": "string", "maxLength": 255, "minLength": 1, "pattern": "^[!-~](?:[ -~]{0,253}[!-~])?$" }, "example": "550e8400-e29b-41d4-a716-446655440000" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EventoInutilizacionRequest" } } }, "required": true }, "responses": { "200": { "description": "Evento de inutilización registrado", "content": { "*/*": { "schema": { "$ref": "#/components/schemas/EventoSifenDTO" } } } }, "400": { "$ref": "#/components/responses/IdempotencyBadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "404": { "$ref": "#/components/responses/NotFound" }, "409": { "$ref": "#/components/responses/IdempotencyConflict" }, "422": { "$ref": "#/components/responses/IdempotencyKeyReused" }, "500": { "$ref": "#/components/responses/InternalError" }, "503": { "$ref": "#/components/responses/IdempotencyUnavailable" } } } }, "/api/v1/public/enums": { "get": { "tags": [ "Catálogos" ], "summary": "Listar todas las enumeraciones de SIFEN", "description": "Catálogo completo de valores válidos, con su código SIFEN y su descripción. Es la fuente para poblar selects en tu UI.", "operationId": "listar-enumeraciones", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { "type": "object", "additionalProperties": { "type": "array", "items": { "$ref": "#/components/schemas/EnumValueDTO" } } } } } } }, "security": [] } }, "/api/v1/padron/{documento}": { "get": { "tags": [ "Padrón" ], "summary": "Consultar un RUC o cédula en el padrón", "description": "Devuelve razón social, estado, tipo de contribuyente y domicilio fiscal con los códigos\ngeográficos de SIFEN, listos para completar el receptor de un documento electrónico.\n\nAcepta el documento con o sin puntos y con o sin dígito verificador (`80002201`,\n`80002201-7`, `80.002.201-7`). Una cédula que no es RUC responde con\n`tipoDocumento: CEDULA` y `esContribuyente: false`.\n\nLímite: 60 consultas por minuto por API key.\n", "operationId": "consultar-padron", "parameters": [ { "name": "documento", "in": "path", "description": "RUC o cédula, con o sin puntos y DV.", "required": true, "schema": { "type": "string" }, "example": "80002201-7" } ], "responses": { "200": { "description": "Documento encontrado", "content": { "*/*": { "schema": { "$ref": "#/components/schemas/Padron" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "404": { "$ref": "#/components/responses/NotFound" }, "429": { "description": "Límite de consultas superado; `Retry-After` indica los segundos a esperar.", "content": { "*/*": { "schema": { "$ref": "#/components/schemas/ApiResponsePadron" } } } }, "500": { "$ref": "#/components/responses/InternalError" }, "502": { "description": "El padrón no respondió; reintentá en unos minutos.", "content": { "*/*": { "schema": { "$ref": "#/components/schemas/ApiResponsePadron" } } } } }, "security": [ { "apiKey": [] } ] } }, "/api/v1/geografia/distritos/{distritoId}/ciudades": { "get": { "tags": [ "Catálogos" ], "summary": "Listar ciudades de un distrito", "operationId": "listar-ciudades", "parameters": [ { "name": "distritoId", "in": "path", "required": true, "schema": { "type": "integer", "format": "int32" } } ], "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { "$ref": "#/components/schemas/ApiResponseListCiudadDTO" } } } } }, "security": [] } }, "/api/v1/geografia/departamentos": { "get": { "tags": [ "Catálogos" ], "summary": "Listar departamentos", "operationId": "listar-departamentos", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { "$ref": "#/components/schemas/ApiResponseListDepartamentoDTO" } } } } }, "security": [] } }, "/api/v1/geografia/departamentos/{departamentoId}/distritos": { "get": { "tags": [ "Catálogos" ], "summary": "Listar distritos de un departamento", "operationId": "listar-distritos", "parameters": [ { "name": "departamentoId", "in": "path", "required": true, "schema": { "type": "integer", "format": "int32" } } ], "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { "$ref": "#/components/schemas/ApiResponseListDistritoDTO" } } } } }, "security": [] } }, "/api/v1/geografia/departamentos/{departamentoId}/ciudades": { "get": { "tags": [ "Catálogos" ], "summary": "Listar ciudades de un departamento", "operationId": "listar-ciudades-departamento", "parameters": [ { "name": "departamentoId", "in": "path", "required": true, "schema": { "type": "integer", "format": "int32" } } ], "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { "$ref": "#/components/schemas/ApiResponseListCiudadDTO" } } } } }, "security": [] } }, "/api/v1/documento-electronico/{cdc}/kude": { "get": { "tags": [ "Documentos electrónicos" ], "summary": "Descargar el KuDE en PDF", "description": "Devuelve un PDF conservado o solicita preparación sin correo si falta. Un 202 es JSON, no un PDF: seguir Location con soloConsulta=true, cada 5 segundos. Solo consulta no vuelve a pedir la preparación: si sigue pendiente después de 2 minutos, repetir una vez la descarga sin soloConsulta. Se verifican titularidad y retención antes de consultar archivos o solicitar preparación. Las notas de remisión requieren APROBADO o APROBADO_OBSERVACION; de lo contrario, 403. Los fallos técnicos antes informados como 422 ahora usan 500/503 según la causa.", "operationId": "descargar-kude", "parameters": [ { "name": "cdc", "in": "path", "description": "CDC del documento, 44 dígitos", "required": true, "schema": { "type": "string" }, "example": "01800123451001001000000122026042710000000006" }, { "name": "soloConsulta", "in": "query", "description": "Sólo consultar el estado: no vuelve a pedir la preparación del PDF", "required": false, "schema": { "type": "boolean", "default": false } } ], "responses": { "200": { "description": "PDF del KuDE", "headers": { "Content-Disposition": { "description": "inline; filename=\"{cdc}.pdf\"", "style": "simple", "schema": { "type": "string" } }, "Content-Length": { "style": "simple", "schema": { "type": "integer", "format": "int64" } } }, "content": { "application/pdf": { "schema": { "type": "string", "format": "binary" } } } }, "202": { "$ref": "#/components/responses/KuDePending" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/DocumentArchived" }, "404": { "$ref": "#/components/responses/NotFound" }, "500": { "$ref": "#/components/responses/KuDeGenerationError" }, "501": { "$ref": "#/components/responses/KuDeNotSupported" }, "503": { "$ref": "#/components/responses/KuDeUnavailable" } } } }, "/api/v1/documento-electronico/status/{cdc}": { "get": { "tags": [ "Documentos electrónicos" ], "summary": "Consultar el estado de un documento", "description": "Estados terminales: `APROBADO`, `APROBADO_OBSERVACION`, `RECHAZADO` y `ERROR`. `APROBADO_OBSERVACION` es un resultado exitoso.", "operationId": "consultar-estado", "parameters": [ { "name": "cdc", "in": "path", "description": "CDC del documento, 44 dígitos", "required": true, "schema": { "type": "string" }, "example": "01800123451001001000000122026042710000000006" } ], "responses": { "200": { "description": "Estado actual del documento", "content": { "*/*": { "schema": { "$ref": "#/components/schemas/DocumentoElectronicoStatusDTO" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/DocumentArchived" }, "404": { "$ref": "#/components/responses/NotFound" }, "500": { "$ref": "#/components/responses/InternalError" } } } }, "/api/v1/documento-electronico/plan-consumo": { "get": { "tags": [ "Documentos electrónicos" ], "summary": "Consultar plan y consumo (ruta deprecada)", "description": "Ruta anterior de `GET /api/v1/contribuyente/plan-consumo`, con la misma respuesta.\nDeja de existir en la fecha del header `Sunset`.\n", "operationId": "consultar-plan-consumo-deprecado", "responses": { "200": { "description": "Plan y consumo actuales", "headers": { "Sunset": { "description": "Fecha de remoción de la ruta (RFC 8594)", "style": "simple", "schema": { "type": "string", "example": "Fri, 15 Jan 2027 00:00:00 GMT" } }, "Deprecation": { "description": "Fecha de deprecación como `@` y segundos Unix (RFC 9745)", "style": "simple", "schema": { "type": "string", "example": "@1791590400" } }, "Link": { "description": "Ruta que la reemplaza, con `rel=\"successor-version\"`", "style": "simple", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PlanConsumoDTO" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "500": { "$ref": "#/components/responses/InternalError" } }, "deprecated": true } }, "/api/v1/documento-electronico/eventos": { "get": { "tags": [ "Documentos electrónicos" ], "summary": "Listar eventos del contribuyente", "operationId": "listar-eventos", "parameters": [ { "name": "page", "in": "query", "description": "Página, base 0", "required": false, "schema": { "type": "integer", "format": "int32", "default": 0 } }, { "name": "size", "in": "query", "description": "Tamaño de página", "required": false, "schema": { "type": "integer", "format": "int32", "default": 10 } }, { "name": "tipoEvento", "in": "query", "description": "Filtro por tipo de evento", "required": false, "schema": { "type": "string" }, "example": "CANCELACION" } ], "responses": { "200": { "description": "Página de eventos", "content": { "*/*": { "schema": { "$ref": "#/components/schemas/PageDTOEventoSifenDTO" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "500": { "$ref": "#/components/responses/InternalError" } } } }, "/api/v1/documento-electronico/eventos/{eventoId}": { "get": { "tags": [ "Documentos electrónicos" ], "summary": "Consultar un evento por su id", "operationId": "consultar-evento", "parameters": [ { "name": "eventoId", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "Evento", "content": { "*/*": { "schema": { "$ref": "#/components/schemas/EventoSifenDTO" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "404": { "$ref": "#/components/responses/NotFound" }, "500": { "$ref": "#/components/responses/InternalError" } } } }, "/api/v1/contribuyente": { "get": { "tags": [ "Contribuyente" ], "summary": "Consultar el contribuyente emisor", "description": "Devuelve los datos del contribuyente identificado por la API key, tal como se usan\nal emitir en el ambiente de la clave: datos fiscales, dirección, timbrado,\nestablecimientos y el estado de la configuración necesaria para emitir.\n\n`estadoConfiguracion.listoParaEmitir` reproduce los controles que la emisión\nhace antes de asignar número. No contempla el cupo del plan, que se consulta en\n`GET /api/v1/contribuyente/plan-consumo`. En SANDBOX el timbrado y el\nCSC de prueba se generan en la primera emisión y la vigencia del certificado no\nse exige.\n", "operationId": "consultar-contribuyente", "responses": { "200": { "description": "Datos del contribuyente emisor", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ContribuyenteIntegracionDTO" }, "examples": { "personaJuridica": { "description": "personaJuridica", "value": { "ruc": "80012345", "digitoVerificador": "1", "razonSocial": "Ejemplo S.A.", "nombreFantasia": "Ejemplo", "tipoContribuyente": "PERSONA_JURIDICA", "ambiente": "PROD", "actividadesEconomicas": [ { "codigo": "56101", "descripcion": "Restaurantes" } ], "direccion": "Av. Mcal. López", "numeroCasa": 1234, "departamento": { "codigo": 1, "descripcion": "CAPITAL" }, "distrito": { "codigo": 1, "descripcion": "ASUNCION (DISTRITO)" }, "ciudad": { "codigo": 1, "descripcion": "ASUNCION (DISTRITO)" }, "telefono": "021123456", "email": "facturacion@ejemplo.com.py", "timbrado": { "numero": 12345678, "fechaInicioVigencia": "2026-01-15" }, "establecimientos": [ { "numeroEstablecimiento": 1, "nombreSucursal": "Casa central", "activo": true, "puntosExpedicion": [ { "puntoExpedicion": 1, "activo": true } ] } ], "logoUrl": "https://storage.googleapis.com/sifende-assets/logos/112/3f0c8f5e-6b2a-4d7e-9a51-2c4e8b7d9f10.png", "estadoConfiguracion": { "certificadoConfigurado": true, "certificadoVence": "2027-03-01", "certificadoVigente": true, "cscConfigurado": true, "timbradoVigente": true, "direccionConfigurada": true, "actividadEconomicaConfigurada": true, "listoParaEmitir": true } } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "500": { "$ref": "#/components/responses/InternalError" } } } }, "/api/v1/contribuyente/plan-consumo": { "get": { "tags": [ "Contribuyente" ], "summary": "Consultar plan y consumo", "description": "Devuelve el ciclo y consumo del contribuyente identificado por la API key.", "operationId": "consultar-plan-consumo", "responses": { "200": { "description": "Plan y consumo actuales", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PlanConsumoDTO" }, "examples": { "plan500": { "description": "plan500", "value": { "codigoPlan": "PLAN_500", "nombrePlan": "Plan 500", "inicioPeriodo": "2026-03-01T03:00:00Z", "finPeriodo": "2026-04-01T03:00:00Z", "documentosIncluidos": 500, "consumoConfirmado": 512, "reservasActivas": 3, "documentosDisponibles": 0, "permiteAdicionales": true, "precioDocumentoAdicionalPyg": 250, "adicionalesFacturables": 12, "costoEstimadoPyg": 3000 } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "500": { "$ref": "#/components/responses/InternalError" } } } } }, "components": { "schemas": { "AsociacionFacturaDTO": { "type": "object", "description": "Documento referenciado por la factura (H001): una nota de remisión o una factura de anticipo,\nelectrónica (`cdc`) o impresa (timbrado, establecimiento, punto, número, tipo y fecha).\n", "properties": { "tipoDocumento": { "type": "string", "description": "`ELECTRONICO` o `IMPRESO` (H002)", "enum": [ "ELECTRONICO", "IMPRESO", "CONSTANCIA_ELECTRONICA" ], "example": "ELECTRONICO" }, "cdc": { "type": "string", "description": "ELECTRONICO: CDC de una NRE (07…) o de una FE de anticipo (01…) del mismo emisor (H004)", "pattern": "[0-9]{44}" }, "numeroTimbrado": { "type": "string", "description": "IMPRESO: timbrado del documento impreso (H005)", "example": "12345678", "pattern": "[0-9]{8}" }, "establecimiento": { "type": "string", "description": "IMPRESO: establecimiento (H006)", "example": "001", "pattern": "[0-9]{3}" }, "puntoExpedicion": { "type": "string", "description": "IMPRESO: punto de expedición (H007)", "example": "001", "pattern": "[0-9]{3}" }, "numeroDocumento": { "type": "string", "description": "IMPRESO: número del documento (H008)", "example": "0000123", "pattern": "[0-9]{7}" }, "tipoDocumentoImpreso": { "type": "string", "description": "IMPRESO: `FACTURA` (anticipo) o `NOTA_DE_REMISION` (H009)", "enum": [ "FACTURA", "NOTA_DE_CREDITO", "NOTA_DE_DEBITO", "NOTA_DE_REMISION", "COMPROBANTE_DE_RETENCION" ], "example": "NOTA_DE_REMISION" }, "fechaEmision": { "type": "string", "format": "date", "description": "IMPRESO: fecha de emisión (H011)", "example": "2026-03-10" }, "numeroComprobanteRetencion": { "type": "string", "description": "Comprobante de retención (H012). Opcional y sólo con un pago `RETENCION`", "pattern": "\\S{15}" }, "numeroResolucionCreditoFiscal": { "type": "string", "description": "Resolución de crédito fiscal (H013). Obligatoria y exclusiva de `VENTA_CREDITO_FISCAL`", "pattern": "\\S{15}" } }, "required": [ "tipoDocumento" ] }, "AutofacturaElectronicaRequest": { "allOf": [ { "$ref": "#/components/schemas/DocumentoElectronicoRequest" }, { "type": "object", "properties": { "condicionOperacion": { "type": "string", "default": "CONTADO", "description": "Sólo CONTADO", "enum": [ "CONTADO" ] }, "vendedor": { "$ref": "#/components/schemas/VendedorAutofacturaDTO" }, "lugarOperacion": { "$ref": "#/components/schemas/DomicilioAutofacturaDTO" }, "constancia": { "$ref": "#/components/schemas/ConstanciaAutofacturaDTO" }, "condicionPago": { "$ref": "#/components/schemas/CondicionPagoDTO" }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/ItemAutofacturaDTO" }, "maxItems": 999, "minItems": 0 }, "emailEntrega": { "type": "string", "format": "email", "maxLength": 80, "minLength": 0, "pattern": "(?s).*\\S.*" } } }, { "properties": { "monedaOperacion": { "const": "PYG" }, "condicionOperacion": { "const": "CONTADO" }, "tipoCambio": { "type": "null" }, "descuentoGlobalPorcentaje": { "type": "null" } } }, { "required": [ "tipoTransaccion" ] }, { "properties": { "condicionPago": { "not": { "anyOf": [ { "required": [ "condicionCredito" ] }, { "required": [ "plazoCredito" ] }, { "required": [ "plazoEstructurado" ] }, { "required": [ "cuotas" ] }, { "required": [ "detalleCuotas" ] }, { "required": [ "montoEntregaInicial" ] } ] }, "properties": { "tipo": { "const": "CONTADO" } }, "required": [ "monedaPago", "montoPago", "tipo", "tipoPago" ] } } }, { "properties": { "tipoDocumento": { "const": "AUTOFACTURA_ELECTRONICA" } } } ], "description": "Autofactura electrónica. El comprador se deriva del contribuyente autenticado; no se envía receptor.", "required": [ "condicionPago", "constancia", "items", "lugarOperacion", "numeroEstablecimiento", "puntoExpedicion", "tipoDocumento", "tipoEmision", "vendedor" ], "unevaluatedProperties": false }, "CargaRemisionDTO": { "type": "object", "properties": { "unidadMedidaVolumen": { "type": "string", "enum": [ "kWh", "AA", "BG", "_4A", "AB", "BX", "CM", "CM2", "CM3", "BK", "CPM", "Ci", "DET", "Di", "DOC", "DPC", "BL", "GLL", "g", "GRO", "ha", "Hs", "SET", "E4", "kg", "kg_m2", "Km", "KT", "LT", "U_JGO", "ME", "ml", "m", "MT", "M2", "M3", "M5", "MCU", "MG", "ML", "MIL", "MM", "MM2", "Mi", "PK", "PAR", "BW", "FOT", "FTK", "PCE", "pm", "JR", "PUL", "KLT", "racion", "RM", "RO", "Se", "DR", "TN", "UNI", "UI", "GL", "Ya" ] }, "volumenTotal": { "type": "string", "example": "99999999999999999999", "pattern": "[1-9][0-9]{0,19}" }, "unidadMedidaPeso": { "type": "string", "enum": [ "kWh", "AA", "BG", "_4A", "AB", "BX", "CM", "CM2", "CM3", "BK", "CPM", "Ci", "DET", "Di", "DOC", "DPC", "BL", "GLL", "g", "GRO", "ha", "Hs", "SET", "E4", "kg", "kg_m2", "Km", "KT", "LT", "U_JGO", "ME", "ml", "m", "MT", "M2", "M3", "M5", "MCU", "MG", "ML", "MIL", "MM", "MM2", "Mi", "PK", "PAR", "BW", "FOT", "FTK", "PCE", "pm", "JR", "PUL", "KLT", "racion", "RM", "RO", "Se", "DR", "TN", "UNI", "UI", "GL", "Ya" ] }, "pesoTotal": { "type": "string", "example": "99999999999999999999", "pattern": "[1-9][0-9]{0,19}" }, "caracteristica": { "type": "string", "enum": [ "MERCADERIA_CON_CADENA_DE_FRIO", "CARGA_PELIGROSA", "OTRO" ] }, "descripcionCaracteristica": { "type": "string", "description": "Sólo OTRO: descripción requerida. En los otros tipos se deriva la descripción oficial", "maxLength": 50, "minLength": 1, "pattern": ".*\\S.*" } } }, "ChequePagoDTO": { "type": "object", "description": "Pago con cheque (E630)", "properties": { "numeroCheque": { "type": "string", "description": "Número del cheque (E631). Se completa con ceros a la izquierda hasta 8", "example": "1234", "pattern": "[0-9]{1,8}" }, "bancoCheque": { "type": "string", "description": "Banco emisor (E632)", "example": "Banco Continental", "maxLength": 20, "minLength": 4, "pattern": "(?s).*\\S.*" } }, "required": [ "bancoCheque", "numeroCheque" ] }, "ComprasPublicasDTO": { "type": "object", "description": "Datos opcionales de contratación pública, en cualquier operación. Los códigos deben enviarse como strings canónicos; la API no agrega ceros ni acepta números.", "properties": { "modalidad": { "type": "string", "description": "Modalidad de contratación (E021), exactamente 2 caracteres no blancos", "example": "CD", "maxLength": 2, "minLength": 2, "pattern": "\\S{2}" }, "entidad": { "type": "string", "description": "Entidad contratante (E022), 5 dígitos y valor mayor que cero", "example": "00123", "maxLength": 5, "minLength": 5, "pattern": "(?=.*[1-9])\\d{5}" }, "anho": { "type": "string", "description": "Año de contratación (E023), 2 dígitos y valor mayor que cero", "example": "26", "maxLength": 2, "minLength": 2, "pattern": "(?=.*[1-9])\\d{2}" }, "secuencia": { "type": "string", "description": "Secuencia de contratación (E024), 7 dígitos y valor mayor que cero", "example": "0000456", "maxLength": 7, "minLength": 7, "pattern": "(?=.*[1-9])\\d{7}" }, "fechaEmisionCodigo": { "type": "string", "format": "date", "description": "Fecha de emisión del código (E025), anterior a la fecha efectiva de la FE", "example": "2026-01-10" } }, "required": [ "anho", "entidad", "fechaEmisionCodigo", "modalidad", "secuencia" ] }, "CondicionPagoDTO": { "type": "object", "allOf": [ { "allOf": [ { "if": { "properties": { "monedaPago": { "const": "PYG" } }, "required": [ "monedaPago" ] }, "then": { "not": { "required": [ "tipoCambio" ] } } }, { "if": { "properties": { "monedaPago": { "not": { "const": "PYG" } } }, "required": [ "monedaPago" ] }, "then": { "required": [ "tipoCambio" ] } } ] } ], "description": "Medio de pago de la operación. Qué campos se informan depende de `tipo` y de `tipoPago`.\n`montoPago` tiene que cuadrar con el total de los ítems.\n", "properties": { "tipo": { "type": "string", "description": "`CONTADO` o `CREDITO`. Coincide con el `condicionOperacion` del documento", "enum": [ "CONTADO", "CREDITO" ], "example": "CONTADO" }, "tipoPago": { "type": "string", "description": "Medio de pago", "enum": [ "EFECTIVO", "CHEQUE", "TARJETA_DE_CREDITO", "TARJETA_DE_DEBITO", "TRANSFERENCIA", "GIRO", "BILLETERA_ELECTRONICA", "TARJETA_EMPRESARIAL", "VALE", "RETENCION", "PAGO_POR_ANTICIPO", "VALOR_FISCAL", "VALOR_COMERCIAL", "COMPENSACION", "PERMUTA", "PAGO_BANCARIO", "PAGO_MOVIL", "DONACION", "PROMOCION", "CONSUMO_INTERNO", "PAGO_ELECTRONICO", "OTRO" ], "example": "EFECTIVO" }, "descripcionTipoPago": { "type": "string", "description": "Descripción propia del medio (E607). Obligatoria y exclusiva de `tipoPago = OTRO`", "maxLength": 30, "minLength": 4, "pattern": "(?s).*\\S.*" }, "monedaPago": { "type": "string", "description": "Moneda del pago", "enum": [ "AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", "AUD", "AWG", "AZM", "BAM", "BBD", "BYN", "BDT", "BGN", "BHD", "BIF", "BMD", "BND", "BOB", "BOV", "BRL", "BSD", "BTN", "BWP", "BYR", "BZD", "CAD", "CDF", "CHF", "CHE", "CHW", "CLP", "CLF", "CNY", "COP", "COU", "CRC", "CUP", "CUC", "CVE", "CYP", "CZK", "DJF", "DKK", "DOP", "DZD", "EEK", "EGP", "ERN", "ETB", "EUR", "FJD", "FKP", "GBP", "GEL", "GHS", "GHC", "GIP", "GMD", "GNF", "GTQ", "GYD", "HKD", "HNL", "HRK", "HTG", "HUF", "IDR", "ILS", "INR", "IQD", "IRR", "ISK", "JMD", "JOD", "JPY", "KES", "KGS", "KHR", "KMF", "KPW", "KRW", "KWD", "KYD", "KZT", "LAK", "LBP", "LKR", "LRD", "LSL", "LTL", "LVL", "LYD", "MAD", "MZN", "MDL", "MGF", "MKD", "MGA", "MMK", "MNT", "MOP", "MRO", "MTL", "MUR", "XUA", "MVR", "MRU", "MWK", "MXN", "MXV", "MYR", "MZM", "NAD", "NGN", "NIO", "NOK", "NPR", "NZD", "OMR", "PAB", "PEN", "PGK", "PHP", "PKR", "PLN", "PYG", "QAR", "RON", "ROL", "RUB", "RWF", "SAR", "RSD", "SBD", "SCR", "SDD", "SDG", "SRD", "SEK", "SGD", "SHP", "SIT", "SKK", "SLL", "SOS", "SRG", "SSP", "STD", "SVC", "SYP", "SZL", "THB", "TJS", "TMM", "TND", "TRY", "TMT", "TOP", "TRL", "TTD", "TWD", "TZS", "UAH", "UGX", "USD", "USN", "UYU", "UYI", "UYW", "UZS", "VEB", "VND", "VUV", "VES", "WST", "STN", "XAF", "XAG", "XAU", "XCD", "XDR", "XOF", "XPD", "XPF", "XPT", "XSU", "XBA", "XBB", "XBC", "XTS", "XXX", "YER", "YUM", "ZMW", "ZWL", "ZAR", "ZMK", "ZWD" ], "example": "PYG" }, "montoPago": { "type": "number", "description": "Monto pagado en `monedaPago`. Obligatorio para `tipo = CONTADO`", "example": 110000, "minimum": 0 }, "tipoCambio": { "type": "number", "description": "Tipo de cambio de la moneda del pago (E611)", "example": 7135.1256, "maximum": 99999.9999, "minimum": 0 }, "tipoTarjeta": { "type": "string", "description": "Denominación de la tarjeta (E621). Se asume `OTRO` si no se informa", "enum": [ "VISA", "MASTERCARD", "AMERICAN_EXPRESS", "MAESTRO", "PANAL", "CABAL", "OTRO" ], "example": "VISA" }, "descripcionTipoTarjeta": { "type": "string", "description": "Descripción propia de la tarjeta (E622). Obligatoria y exclusiva de `tipoTarjeta = OTRO`", "maxLength": 20, "minLength": 4, "pattern": "(?s).*\\S.*" }, "formaProcesamientoPago": { "type": "string", "description": "Forma de procesamiento del pago con tarjeta (E626). Se asume `OTRO` si no se informa", "enum": [ "POS", "PAGO_ELECTRONICO", "OTRO" ], "example": "POS" }, "numeroCheque": { "type": "string", "description": "Número del cheque (E631). Obligatorio para `tipoPago = CHEQUE`", "example": "0001234", "pattern": "[0-9]{1,8}" }, "bancoCheque": { "type": "string", "description": "Banco emisor del cheque (E632). Obligatorio para `tipoPago = CHEQUE`", "example": "Banco Continental", "maxLength": 20, "minLength": 4, "pattern": "(?s).*\\S.*" }, "condicionCredito": { "type": "string", "description": "Modalidad del crédito (E641). `PLAZO` o `CUOTA`", "enum": [ "PLAZO", "CUOTA" ], "example": "PLAZO" }, "plazoCredito": { "type": "string", "description": "Plazo del crédito. Para `tipo = CREDITO`", "example": "30 días" }, "plazoEstructurado": { "$ref": "#/components/schemas/PlazoEstructuradoDTO", "description": "Alternativa al plazo libre: cantidad de 1 a 9999 y unidad DIAS o MESES" }, "cuotas": { "type": "integer", "format": "int32", "description": "Cantidad de cuotas (E644), entre 1 y 999. En runtime debe coincidir con la cantidad\nde elementos de `detalleCuotas`; JSON Schema no puede validar esa igualdad.\n", "example": 3 }, "detalleCuotas": { "type": "array", "description": "Detalle de las cuotas (E650). Para `condicionCredito = CUOTA`", "items": { "$ref": "#/components/schemas/CuotaCreditoDTO" } }, "montoEntregaInicial": { "type": "number", "description": "Entrega inicial del crédito (E645). Cero equivale a ausencia. En runtime debe ser menor que el\ntotal de la operación y expresarse en `monedaOperacion`; JSON Schema no valida ese cálculo.\n", "example": 50000 } } }, "ConstanciaAutofacturaDTO": { "type": "object", "additionalProperties": false, "allOf": [ { "properties": { "tipo": { "const": "CONSTANCIA_NO_CONTRIBUYENTE" } } } ], "description": "Constancia electrónica asociada a la autofactura (grupo H)", "properties": { "tipo": { "type": "string", "description": "Tipo de constancia (H014)", "enum": [ "CONSTANCIA_NO_CONTRIBUYENTE", "CONSTANCIA_MICROPRODUCTORES" ], "example": "CONSTANCIA_NO_CONTRIBUYENTE" } }, "required": [ "tipo" ] }, "CreditoFacturaDTO": { "type": "object", "description": "Condiciones del crédito (E640). Los medios de la entrega inicial van en `pagos`; el saldo\nfinanciado es el total menos esa entrega.\n", "properties": { "condicionCredito": { "type": "string", "description": "`PLAZO` o `CUOTA` (E641)", "enum": [ "PLAZO", "CUOTA" ], "example": "CUOTA" }, "plazoCredito": { "type": "string", "description": "PLAZO: texto libre de 2 a 15 caracteres (E643)", "example": "30 días" }, "plazoEstructurado": { "$ref": "#/components/schemas/PlazoEstructuradoDTO", "description": "PLAZO: alternativa estructurada a `plazoCredito`" }, "cuotas": { "type": "integer", "format": "int32", "description": "CUOTA: cantidad de 1 a 999 (E644); coincide con `detalleCuotas`", "example": 3 }, "detalleCuotas": { "type": "array", "description": "CUOTA: calendario completo (E650). La suma cubre el saldo financiado", "items": { "$ref": "#/components/schemas/CuotaCreditoDTO" }, "maxItems": 999, "minItems": 0 }, "montoEntregaInicial": { "type": "number", "description": "Opcional; si se informa coincide con la suma de `pagos` (E645)", "example": 20000, "minimum": 0 } }, "required": [ "condicionCredito" ] }, "CuotaCreditoDTO": { "type": "object", "description": "Detalle de una cuota del crédito (E650)", "properties": { "monto": { "type": "number", "description": "Monto de la cuota (E651)", "example": 40000, "exclusiveMaximum": 1000000000000000, "exclusiveMinimum": 0, "minimum": 0, "multipleOf": 0.0001 }, "fechaVencimiento": { "type": "string", "format": "date", "description": "Fecha de vencimiento opcional (E652)", "example": "2026-09-18" }, "moneda": { "type": "string", "description": "Moneda de la cuota (E653). Si se omite, `monedaOperacion`", "enum": [ "AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", "AUD", "AWG", "AZM", "BAM", "BBD", "BYN", "BDT", "BGN", "BHD", "BIF", "BMD", "BND", "BOB", "BOV", "BRL", "BSD", "BTN", "BWP", "BYR", "BZD", "CAD", "CDF", "CHF", "CHE", "CHW", "CLP", "CLF", "CNY", "COP", "COU", "CRC", "CUP", "CUC", "CVE", "CYP", "CZK", "DJF", "DKK", "DOP", "DZD", "EEK", "EGP", "ERN", "ETB", "EUR", "FJD", "FKP", "GBP", "GEL", "GHS", "GHC", "GIP", "GMD", "GNF", "GTQ", "GYD", "HKD", "HNL", "HRK", "HTG", "HUF", "IDR", "ILS", "INR", "IQD", "IRR", "ISK", "JMD", "JOD", "JPY", "KES", "KGS", "KHR", "KMF", "KPW", "KRW", "KWD", "KYD", "KZT", "LAK", "LBP", "LKR", "LRD", "LSL", "LTL", "LVL", "LYD", "MAD", "MZN", "MDL", "MGF", "MKD", "MGA", "MMK", "MNT", "MOP", "MRO", "MTL", "MUR", "XUA", "MVR", "MRU", "MWK", "MXN", "MXV", "MYR", "MZM", "NAD", "NGN", "NIO", "NOK", "NPR", "NZD", "OMR", "PAB", "PEN", "PGK", "PHP", "PKR", "PLN", "PYG", "QAR", "RON", "ROL", "RUB", "RWF", "SAR", "RSD", "SBD", "SCR", "SDD", "SDG", "SRD", "SEK", "SGD", "SHP", "SIT", "SKK", "SLL", "SOS", "SRG", "SSP", "STD", "SVC", "SYP", "SZL", "THB", "TJS", "TMM", "TND", "TRY", "TMT", "TOP", "TRL", "TTD", "TWD", "TZS", "UAH", "UGX", "USD", "USN", "UYU", "UYI", "UYW", "UZS", "VEB", "VND", "VUV", "VES", "WST", "STN", "XAF", "XAG", "XAU", "XCD", "XDR", "XOF", "XPD", "XPF", "XPT", "XSU", "XBA", "XBB", "XBC", "XTS", "XXX", "YER", "YUM", "ZMW", "ZWL", "ZAR", "ZMK", "ZWD" ], "example": "PYG" } }, "required": [ "monto" ] }, "DatosComercialesDTO": { "type": "object", "description": "Referencias comerciales (G002-G004) y datos adicionales de uso comercial (E821-E826)", "properties": { "ordenCompra": { "type": "string", "description": "Número de orden de compra (G002)", "example": "OC-2026-001", "maxLength": 15, "minLength": 1, "pattern": "(?s).*\\S.*" }, "ordenVenta": { "type": "string", "description": "Número de orden de venta (G003)", "maxLength": 15, "minLength": 1, "pattern": "(?s).*\\S.*" }, "asientoContable": { "type": "string", "description": "Número de asiento contable (G004)", "maxLength": 10, "minLength": 1, "pattern": "(?s).*\\S.*" }, "ciclo": { "type": "string", "description": "Ciclo facturado (E821). Exige fechas de inicio y fin", "example": "Octubre 2026", "maxLength": 15, "minLength": 1, "pattern": "(?s).*\\S.*" }, "fechaInicioCiclo": { "type": "string", "format": "date", "description": "Inicio del ciclo (E822). Obligatorio y exclusivo con `ciclo`" }, "fechaFinCiclo": { "type": "string", "format": "date", "description": "Fin del ciclo (E823), no anterior al inicio" }, "vencimientosPago": { "type": "array", "description": "Fechas de vencimiento para el pago (E824), hasta 3 y no anteriores a la emisión", "items": { "type": "string", "format": "date" }, "maxItems": 3, "minItems": 0 }, "numeroContrato": { "type": "string", "description": "Número de contrato (E825)", "maxLength": 30, "minLength": 1, "pattern": "(?s).*\\S.*" }, "saldoAnterior": { "type": "number", "description": "Saldo anterior (E826). Informativo: no se suma al total de la factura", "minimum": 0 } } }, "DocumentoAsociadoDTO": { "type": "object", "description": "Documento que origina el ajuste. Hoy sólo se admite `tipoDocumento = ELECTRONICO`, es decir\nreferenciar otro documento por su CDC: cualquier otro valor devuelve `400 validation-error`.\nLos campos de documento impreso están reservados para cuando se habilite ese caso.\n", "properties": { "tipoDocumento": { "type": "string", "description": "Único valor admitido hoy: `ELECTRONICO`", "enum": [ "ELECTRONICO", "IMPRESO", "CONSTANCIA_ELECTRONICA" ], "example": "ELECTRONICO" }, "cdc": { "type": "string", "description": "CDC del documento referenciado, 44 dígitos", "example": "01800123451001001000000122026042710000000006", "pattern": "\\d{44}" }, "numeroTimbrado": { "type": "string" }, "establecimiento": { "type": "string" }, "puntoExpedicion": { "type": "string" }, "numeroDocumento": { "type": "string" }, "tipoDocumentoImpreso": { "type": "string", "enum": [ "FACTURA", "NOTA_DE_CREDITO", "NOTA_DE_DEBITO", "NOTA_DE_REMISION", "COMPROBANTE_DE_RETENCION" ] }, "fechaEmision": { "type": "string" }, "rucFusionado": { "type": "string", "description": "RUC fusionado del emisor del documento asociado, sin DV ni guion (H018)", "example": "80012345", "maxLength": 8, "minLength": 3, "pattern": "[1-9][0-9]*[0-9A-D]?" } }, "required": [ "cdc", "tipoDocumento" ] }, "DocumentoAsociadoRemisionDTO": { "type": "object", "properties": { "tipoDocumento": { "type": "string", "enum": [ "ELECTRONICO", "IMPRESO", "CONSTANCIA_ELECTRONICA" ] }, "cdc": { "type": "string", "pattern": "[0-9]{44}" }, "numeroTimbrado": { "type": "string", "pattern": "[0-9]{8}" }, "establecimiento": { "type": "string", "pattern": "[0-9]{3}" }, "puntoExpedicion": { "type": "string", "pattern": "[0-9]{3}" }, "numeroDocumento": { "type": "string", "pattern": "[0-9]{7}" }, "tipoDocumentoImpreso": { "type": "string", "enum": [ "FACTURA", "NOTA_DE_CREDITO", "NOTA_DE_DEBITO", "NOTA_DE_REMISION", "COMPROBANTE_DE_RETENCION" ] }, "fechaEmision": { "type": "string", "format": "date" }, "rucFusionado": { "type": "string", "pattern": "[0-9]{3,8}" } }, "required": [ "tipoDocumento" ] }, "DocumentoElectronicoRequest": { "type": "object", "description": "Campos comunes a todo documento electrónico. `tipoDocumento` decide el schema\ncompleto del request: cada valor agrega los campos propios de ese tipo, que están\nen el schema correspondiente (`FacturaElectronicaRequest`,\n`NotaCreditoElectronicaRequest`, …).\n\nEl emisor no se envía: sale de la API key. El timbrado y el correlativo tampoco,\nlos asigna Sifende.\n", "discriminator": { "propertyName": "tipoDocumento", "mapping": { "FACTURA_ELECTRONICA": "#/components/schemas/FacturaElectronicaRequest", "NOTA_DE_CREDITO_ELECTRONICA": "#/components/schemas/NotaCreditoElectronicaRequest", "NOTA_DE_DEBITO_ELECTRONICA": "#/components/schemas/NotaDebitoElectronicaRequest", "NOTA_DE_REMISION_ELECTRONICA": "#/components/schemas/NotaRemisionElectronicaRequest", "AUTOFACTURA_ELECTRONICA": "#/components/schemas/AutofacturaElectronicaRequest" } }, "properties": { "tipoDocumento": { "type": "string", "description": "Tipo de documento a emitir. Determina qué campos adicionales acepta el request", "enum": [ "FACTURA_ELECTRONICA", "NOTA_DE_CREDITO_ELECTRONICA", "NOTA_DE_DEBITO_ELECTRONICA", "NOTA_DE_REMISION_ELECTRONICA", "AUTOFACTURA_ELECTRONICA" ], "example": "FACTURA_ELECTRONICA" }, "fechaEmision": { "type": "string", "description": "Fecha y hora de emisión en hora local de Paraguay, sin zona ni offset. Si se omite, se usa la fecha y hora del servidor al recibir el request", "example": "2026-04-15T10:30:00", "pattern": "\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}" }, "tipoEmision": { "type": "string", "default": "NORMAL", "description": "Sólo se admite `NORMAL`: SIFEN todavía no habilita la emisión en contingencia", "enum": [ "NORMAL" ], "example": "NORMAL" }, "numeroEstablecimiento": { "type": "integer", "format": "int32", "description": "Establecimiento habilitado del emisor (1-999)", "example": 1 }, "puntoExpedicion": { "type": "integer", "format": "int32", "description": "Punto de expedición dentro del establecimiento (1-999)", "example": 1 }, "tipoTransaccion": { "type": "string", "description": "Naturaleza de la operación. Obligatorio para factura y autofactura; no se informa en notas de crédito, débito ni remisión", "enum": [ "VENTA_MERCADERIA", "PRESTACION_SERVICIOS", "MIXTO", "VENTA_ACTIVO_FIJO", "VENTA_DIVISAS", "COMPRA_DIVISAS", "PROMOCION_O_MUESTRAS", "DONACION", "ANTICIPO", "COMPRA_PRODUCTOS", "COMPRA_SERVICIOS", "VENTA_CREDITO_FISCAL", "MUESTRAS_MEDICAS" ], "example": "VENTA_MERCADERIA" }, "descuentoGlobalPorcentaje": { "type": "number", "description": "Porcentaje de descuento global aplicado a cada ítem de la operación (F010)", "example": 10, "maximum": 100, "minimum": 0 }, "monedaOperacion": { "type": "string", "default": "PYG", "description": "Moneda de la operación", "enum": [ "AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", "AUD", "AWG", "AZM", "BAM", "BBD", "BYN", "BDT", "BGN", "BHD", "BIF", "BMD", "BND", "BOB", "BOV", "BRL", "BSD", "BTN", "BWP", "BYR", "BZD", "CAD", "CDF", "CHF", "CHE", "CHW", "CLP", "CLF", "CNY", "COP", "COU", "CRC", "CUP", "CUC", "CVE", "CYP", "CZK", "DJF", "DKK", "DOP", "DZD", "EEK", "EGP", "ERN", "ETB", "EUR", "FJD", "FKP", "GBP", "GEL", "GHS", "GHC", "GIP", "GMD", "GNF", "GTQ", "GYD", "HKD", "HNL", "HRK", "HTG", "HUF", "IDR", "ILS", "INR", "IQD", "IRR", "ISK", "JMD", "JOD", "JPY", "KES", "KGS", "KHR", "KMF", "KPW", "KRW", "KWD", "KYD", "KZT", "LAK", "LBP", "LKR", "LRD", "LSL", "LTL", "LVL", "LYD", "MAD", "MZN", "MDL", "MGF", "MKD", "MGA", "MMK", "MNT", "MOP", "MRO", "MTL", "MUR", "XUA", "MVR", "MRU", "MWK", "MXN", "MXV", "MYR", "MZM", "NAD", "NGN", "NIO", "NOK", "NPR", "NZD", "OMR", "PAB", "PEN", "PGK", "PHP", "PKR", "PLN", "PYG", "QAR", "RON", "ROL", "RUB", "RWF", "SAR", "RSD", "SBD", "SCR", "SDD", "SDG", "SRD", "SEK", "SGD", "SHP", "SIT", "SKK", "SLL", "SOS", "SRG", "SSP", "STD", "SVC", "SYP", "SZL", "THB", "TJS", "TMM", "TND", "TRY", "TMT", "TOP", "TRL", "TTD", "TWD", "TZS", "UAH", "UGX", "USD", "USN", "UYU", "UYI", "UYW", "UZS", "VEB", "VND", "VUV", "VES", "WST", "STN", "XAF", "XAG", "XAU", "XCD", "XDR", "XOF", "XPD", "XPF", "XPT", "XSU", "XBA", "XBB", "XBC", "XTS", "XXX", "YER", "YUM", "ZMW", "ZWL", "ZAR", "ZMK", "ZWD" ], "example": "PYG" }, "tipoCambio": { "type": "number", "description": "Tipo de cambio global de la operación (D018)", "example": 7135.1256, "maximum": 99999.9999, "minimum": 0 }, "obligacionesAfectadas": { "type": "array", "description": "Códigos de obligaciones tributarias afectadas (D030)", "example": [ "211", "700" ], "items": { "type": "string" }, "maxItems": 11, "minItems": 0 }, "infoEmisor": { "type": "string", "description": "Texto libre adicional del emisor (B005), de 1 a 3000 caracteres en una sola línea", "example": "Pedido #4821", "maxLength": 3000, "minLength": 1 }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/ItemDocumento" } } }, "required": [ "numeroEstablecimiento", "puntoExpedicion", "tipoDocumento", "tipoEmision" ] }, "DomicilioAutofacturaDTO": { "type": "object", "additionalProperties": false, "description": "Dirección y códigos geográficos del vendedor o del lugar de la operación", "properties": { "direccion": { "type": "string", "description": "Dirección del vendedor o lugar de la transacción (E308/E316)", "example": "Av. España", "maxLength": 255, "minLength": 0 }, "departamento": { "type": "string", "description": "Código de departamento del catálogo SIFEN (E310/E317)", "example": "1", "minLength": 1, "pattern": "[0-9]{1,2}" }, "codigoDistrito": { "type": "integer", "format": "int32", "description": "Código de distrito opcional del catálogo SIFEN (E312/E319)", "example": 1, "maximum": 9999, "minimum": 1 }, "ciudad": { "type": "string", "description": "Código de ciudad del catálogo SIFEN (E314/E321)", "example": "1", "minLength": 1, "pattern": "[0-9]{1,5}" } }, "required": [ "ciudad", "departamento", "direccion" ] }, "EnergiaElectricaDTO": { "type": "object", "description": "Medición del sector de energía eléctrica (E791). Hasta 9 por factura (NT023)", "properties": { "numeroMedidor": { "type": "string", "description": "Número de medidor (E792)", "maxLength": 50, "minLength": 1 }, "codigoActividad": { "type": "integer", "format": "int32", "description": "Código de actividad (E793)", "maximum": 99, "minimum": 0 }, "codigoCategoria": { "type": "string", "description": "Código de categoría (E794)", "maxLength": 3, "minLength": 1 }, "lecturaAnterior": { "type": "number", "description": "Lectura anterior (E795)", "minimum": 0 }, "lecturaActual": { "type": "number", "description": "Lectura actual (E796)", "minimum": 0 }, "consumo": { "type": "number", "description": "Consumo (E797). Con ambas lecturas Sifende lo deriva como actual − anterior", "minimum": 0 } } }, "FacturaElectronicaRequest": { "allOf": [ { "$ref": "#/components/schemas/DocumentoElectronicoRequest" }, { "type": "object", "properties": { "receptor": { "$ref": "#/components/schemas/ReceptorDTO" }, "items": { "type": "array", "description": "Ítems del documento. Al menos uno", "items": { "$ref": "#/components/schemas/ItemDTO" }, "minItems": 1 }, "comision": { "type": "number", "description": "Comisión de la operación (F025), IVA 10% incluido. Se suma al total general y su IVA al total de IVA", "example": 55000, "minimum": 0 }, "tipoImpuesto": { "type": "string", "description": "Tipo de impuesto afectado (D013). Si se omite, `IVA`; ISC no está habilitado", "enum": [ "IVA", "ISC", "RENTA", "NINGUNO", "IVA_RENTA" ], "example": "IVA" }, "indicadorPresencia": { "type": "string", "description": "Indicador de presencia (E011). Si se omite, `OPERACION_PRESENCIAL`", "enum": [ "OPERACION_PRESENCIAL", "OPERACION_ELECTRONICA", "OPERACION_TELEMARKETING", "VENTA_A_DOMICILIO", "OPERACION_BANCARIA", "OPERACION_CICLICA", "OTRO" ], "example": "OPERACION_ELECTRONICA" }, "descripcionPresencia": { "type": "string", "description": "Descripción propia de la presencia (E012). Obligatoria y exclusiva de `indicadorPresencia = OTRO`", "example": "Venta en feria itinerante", "maxLength": 30, "minLength": 10, "pattern": "(?s).*\\S.*" }, "fechaFuturaRemision": { "type": "string", "format": "date", "description": "Fecha estimada del traslado de la mercadería, cuando se documentará con una nota de remisión electrónica (E013)", "example": "2026-04-20" }, "condicionOperacion": { "type": "string", "description": "`CONTADO` o `CREDITO`", "enum": [ "CONTADO", "CREDITO" ], "example": "CONTADO" }, "condicionPago": { "$ref": "#/components/schemas/CondicionPagoDTO", "description": "Forma anterior de un único medio de pago y del crédito. Excluyente con `pagos`/`credito`" }, "pagos": { "type": "array", "description": "Medios de pago, en orden. En `CONTADO` (1 a 999) cubren el total de la operación; en `CREDITO`\ndescriben la entrega inicial (0 a 999). Excluyente con `condicionPago`\n", "items": { "$ref": "#/components/schemas/PagoFacturaDTO" }, "maxItems": 999, "minItems": 0 }, "credito": { "$ref": "#/components/schemas/CreditoFacturaDTO", "description": "Condiciones del crédito. Obligatorio en `CREDITO` con `pagos`; ausente en `CONTADO`" }, "documentoAsociado": { "$ref": "#/components/schemas/DocumentoAsociadoDTO", "deprecated": true, "description": "No se admite en la factura electrónica: usar `documentosAsociados`, también para una sola referencia" }, "documentosAsociados": { "type": "array", "description": "Notas de remisión y facturas de anticipo referenciadas (H001), en orden. Hasta 99", "items": { "$ref": "#/components/schemas/AsociacionFacturaDTO" }, "maxItems": 99, "minItems": 0 }, "informacionFiscal": { "type": "string", "description": "Información de interés del Fisco respecto al DE (B006), de 1 a 3000 caracteres en una sola línea. Se imprime en el KuDE", "maxLength": 3000, "minLength": 1 }, "condicionAnticipo": { "type": "string", "description": "Condición del anticipo aplicado (D019). Obligatoria cuando la factura aplica anticipos", "enum": [ "ANTICIPO_GLOBAL", "ANTICIPO_POR_ITEM" ], "example": "ANTICIPO_GLOBAL" }, "anticipoGlobalPorcentaje": { "type": "number", "description": "Anticipo global como porcentaje del precio unitario de cada ítem; Sifende deriva EA007", "example": 30, "maximum": 100, "minimum": 0 }, "datosComerciales": { "$ref": "#/components/schemas/DatosComercialesDTO", "description": "Órdenes, asiento y datos adicionales de uso comercial" }, "informacionAdicional": { "type": "string", "description": "Información adicional de interés del emisor para el receptor (J003). Se imprime en el KuDE y no se envía a SIFEN", "maxLength": 5000, "minLength": 1, "pattern": "(?s).*\\S.*" }, "energia": { "type": "array", "description": "Sector de energía eléctrica (E791), hasta 9 mediciones", "items": { "$ref": "#/components/schemas/EnergiaElectricaDTO" }, "maxItems": 9, "minItems": 0 }, "seguro": { "$ref": "#/components/schemas/SeguroDTO", "description": "Sector de seguros (E800)" }, "supermercado": { "$ref": "#/components/schemas/SupermercadoDTO", "description": "Sector de supermercados (E810)" }, "transporte": { "$ref": "#/components/schemas/TransporteFacturaDTO", "description": "Transporte de la mercadería (E900), opcional en la factura" }, "carga": { "$ref": "#/components/schemas/CargaRemisionDTO", "description": "Datos generales de la carga (G050)" }, "comprasPublicas": { "$ref": "#/components/schemas/ComprasPublicasDTO", "description": "Contratación pública opcional (E020), en cualquier operación" }, "codigoContratacionDncp": { "type": "string", "description": "Código de contratación de compras públicas (E827), opcional en cualquier operación", "example": "DNCP-2026-001", "maxLength": 30, "minLength": 1, "pattern": ".*\\S.*" } } }, { "if": { "properties": { "receptor": { "properties": { "tipoOperacion": { "const": "B2F" } }, "required": [ "tipoOperacion" ] } }, "required": [ "receptor" ] }, "then": { "properties": { "tipoTransaccion": { "const": "PRESTACION_SERVICIOS" } }, "required": [ "tipoTransaccion" ] } }, { "if": { "properties": { "condicionOperacion": { "const": "CONTADO" } }, "required": [ "condicionOperacion" ] }, "then": { "oneOf": [ { "not": { "anyOf": [ { "required": [ "pagos" ] }, { "required": [ "credito" ] } ] }, "properties": { "condicionPago": { "not": { "anyOf": [ { "required": [ "plazoCredito" ] }, { "required": [ "plazoEstructurado" ] } ] }, "properties": { "tipo": { "const": "CONTADO" } }, "required": [ "monedaPago", "montoPago", "tipo", "tipoPago" ] } }, "required": [ "condicionPago" ] }, { "not": { "anyOf": [ { "required": [ "condicionPago" ] }, { "required": [ "credito" ] } ] }, "properties": { "pagos": { "type": "array", "minItems": 1 } }, "required": [ "pagos" ] } ] } }, { "if": { "properties": { "condicionOperacion": { "const": "CREDITO" } }, "required": [ "condicionOperacion" ] }, "then": { "oneOf": [ { "not": { "anyOf": [ { "required": [ "pagos" ] }, { "required": [ "credito" ] } ] }, "properties": { "condicionPago": { "allOf": [ { "allOf": [ { "if": { "properties": { "montoEntregaInicial": { "type": "number", "exclusiveMinimum": 0 } }, "required": [ "montoEntregaInicial" ] }, "then": { "allOf": [ { "if": { "properties": { "tipoPago": { "const": "CHEQUE" } }, "required": [ "tipoPago" ] }, "then": { "required": [ "bancoCheque", "numeroCheque" ] } } ], "required": [ "monedaPago", "tipoPago" ] } } ], "properties": { "montoEntregaInicial": { "type": "number", "exclusiveMaximum": 1000000000000000, "minimum": 0, "multipleOf": 0.0001 } } } ], "oneOf": [ { "not": { "anyOf": [ { "required": [ "cuotas" ] }, { "required": [ "detalleCuotas" ] } ] }, "oneOf": [ { "required": [ "plazoCredito" ] }, { "required": [ "plazoEstructurado" ] } ], "properties": { "condicionCredito": { "const": "PLAZO" }, "plazoCredito": { "type": "string", "maxLength": 15, "minLength": 2 }, "tipo": { "const": "CREDITO" } }, "required": [ "condicionCredito", "tipo" ] }, { "not": { "anyOf": [ { "required": [ "plazoCredito" ] }, { "required": [ "plazoEstructurado" ] } ] }, "properties": { "condicionCredito": { "const": "CUOTA" }, "cuotas": { "type": "integer", "maximum": 999, "minimum": 1 }, "detalleCuotas": { "type": "array", "items": { "$ref": "#/components/schemas/CuotaCreditoDTO" }, "maxItems": 999, "minItems": 1 }, "tipo": { "const": "CREDITO" } }, "required": [ "condicionCredito", "cuotas", "detalleCuotas", "tipo" ] } ] } }, "required": [ "condicionPago" ] }, { "not": { "required": [ "condicionPago" ] }, "properties": { "credito": { "oneOf": [ { "not": { "anyOf": [ { "required": [ "cuotas" ] }, { "required": [ "detalleCuotas" ] } ] }, "oneOf": [ { "required": [ "plazoCredito" ] }, { "required": [ "plazoEstructurado" ] } ], "properties": { "condicionCredito": { "const": "PLAZO" }, "plazoCredito": { "type": "string", "maxLength": 15, "minLength": 2 } }, "required": [ "condicionCredito" ] }, { "not": { "anyOf": [ { "required": [ "plazoCredito" ] }, { "required": [ "plazoEstructurado" ] } ] }, "properties": { "condicionCredito": { "const": "CUOTA" }, "cuotas": { "type": "integer", "maximum": 999, "minimum": 1 }, "detalleCuotas": { "type": "array", "items": { "$ref": "#/components/schemas/CuotaCreditoDTO" }, "maxItems": 999, "minItems": 1 } }, "required": [ "condicionCredito", "cuotas", "detalleCuotas" ] } ] } }, "required": [ "credito" ] } ] } }, { "allOf": [ { "if": { "properties": { "monedaOperacion": { "const": "PYG" } } }, "then": { "not": { "required": [ "tipoCambio" ] }, "properties": { "items": { "type": "array", "items": { "not": { "required": [ "tipoCambio" ] } } } } } }, { "if": { "properties": { "monedaOperacion": { "not": { "const": "PYG" } } }, "required": [ "monedaOperacion" ] }, "then": { "oneOf": [ { "properties": { "items": { "type": "array", "items": { "not": { "required": [ "tipoCambio" ] } } } }, "required": [ "tipoCambio" ] }, { "not": { "required": [ "tipoCambio" ] }, "properties": { "items": { "type": "array", "items": { "required": [ "tipoCambio" ] } } } } ] } } ] }, { "properties": { "tipoDocumento": { "const": "FACTURA_ELECTRONICA" } } } ], "description": "Factura electrónica — `tipoDocumento = FACTURA_ELECTRONICA`.", "required": [ "condicionOperacion", "items", "numeroEstablecimiento", "puntoExpedicion", "receptor", "tipoDocumento", "tipoEmision" ] }, "ItemAutofacturaDTO": { "type": "object", "additionalProperties": false, "properties": { "codigo": { "type": "string", "description": "Código interno del producto o servicio en tu sistema (E701)", "example": "PROD-001", "maxLength": 50, "minLength": 0 }, "descripcion": { "type": "string", "description": "Descripción del producto o servicio (E708)", "example": "Resma de papel A4 75g", "maxLength": 2000, "minLength": 0 }, "cantidad": { "type": "number", "description": "Cantidad, hasta 10 enteros y 8 decimales (E711)", "example": 10.12345678, "maximum": 10000000000, "minimum": 1e-8 }, "unidadMedida": { "type": "string", "description": "Unidad de medida del catálogo SIFEN (E714)", "enum": [ "kWh", "AA", "BG", "_4A", "AB", "BX", "CM", "CM2", "CM3", "BK", "CPM", "Ci", "DET", "Di", "DOC", "DPC", "BL", "GLL", "g", "GRO", "ha", "Hs", "SET", "E4", "kg", "kg_m2", "Km", "KT", "LT", "U_JGO", "ME", "ml", "m", "MT", "M2", "M3", "M5", "MCU", "MG", "ML", "MIL", "MM", "MM2", "Mi", "PK", "PAR", "BW", "FOT", "FTK", "PCE", "pm", "JR", "PUL", "KLT", "racion", "RM", "RO", "Se", "DR", "TN", "UNI", "UI", "GL", "Ya" ], "example": "UNI" }, "precioUnitario": { "type": "number", "description": "Precio unitario de la autofactura (E721)", "example": 11000, "minimum": 0 } }, "required": [ "cantidad", "codigo", "descripcion", "precioUnitario", "unidadMedida" ] }, "ItemDTO": { "type": "object", "description": "Ítem del documento. Sifende calcula los totales y el IVA a partir de estos campos: no se\nenvía ni el subtotal del ítem ni el total del documento.\n", "properties": { "codigo": { "type": "string", "description": "Código interno del producto o servicio en tu sistema (E701)", "example": "PROD-001", "maxLength": 50, "minLength": 0 }, "descripcion": { "type": "string", "description": "Descripción del producto o servicio (E708)", "example": "Resma de papel A4 75g", "maxLength": 2000, "minLength": 0 }, "cantidad": { "type": "number", "description": "Cantidad, hasta 10 enteros y 8 decimales (E711)", "example": 10.12345678, "maximum": 10000000000, "minimum": 1e-8 }, "unidadMedida": { "type": "string", "description": "Unidad de medida del catálogo SIFEN (E709)", "enum": [ "kWh", "AA", "BG", "_4A", "AB", "BX", "CM", "CM2", "CM3", "BK", "CPM", "Ci", "DET", "Di", "DOC", "DPC", "BL", "GLL", "g", "GRO", "ha", "Hs", "SET", "E4", "kg", "kg_m2", "Km", "KT", "LT", "U_JGO", "ME", "ml", "m", "MT", "M2", "M3", "M5", "MCU", "MG", "ML", "MIL", "MM", "MM2", "Mi", "PK", "PAR", "BW", "FOT", "FTK", "PCE", "pm", "JR", "PUL", "KLT", "racion", "RM", "RO", "Se", "DR", "TN", "UNI", "UI", "GL", "Ya" ], "example": "UNI" }, "precioUnitario": { "type": "number", "description": "Precio unitario sin descuentos, IVA incluido (E721)", "example": 11000, "minimum": 0 }, "tipoCambio": { "type": "number", "description": "Tipo de cambio del ítem (E725)", "example": 7135.1256, "maximum": 99999.9999, "minimum": 0 }, "afectacionTributaria": { "type": "string", "description": "Afectación del ítem al IVA (E731)", "enum": [ "GRAVADO", "EXONERADO", "EXENTO", "GRAVADO_PARCIAL" ], "example": "GRAVADO" }, "tasaIVA": { "type": "integer", "format": "int32", "description": "Tasa de IVA en porcentaje: 10, 5 o 0 (E734). Con `afectacionTributaria = GRAVADO` es 10 o 5", "example": 10 }, "propIVA": { "type": "number", "description": "Proporción gravada en porcentaje (E733). Sólo se informa para `afectacionTributaria = GRAVADO_PARCIAL`; en el resto la deriva Sifende", "example": 50, "maximum": 100, "minimum": 0 }, "descuentoParticular": { "type": "number", "description": "Descuento en importe sobre el precio unitario del ítem (EA002)", "example": 500, "minimum": 0 }, "descuentoParticularPorcentaje": { "type": "number", "description": "Alternativa a `descuentoParticular`: porcentaje sobre el precio unitario. Sifende deriva el importe (EA002) con la precisión de la moneda", "example": 12.5, "maximum": 100, "minimum": 0 }, "anticipoParticular": { "type": "number", "description": "Sólo factura: anticipo facturado aplicado sobre el precio unitario del ítem (EA006), en la moneda de la factura de anticipo", "example": 1000, "minimum": 0 }, "cdcAnticipo": { "type": "string", "description": "Sólo factura: CDC de la factura de anticipo que se aplica en el ítem (E719). Debe figurar en `documentosAsociados`", "pattern": "[0-9]{44}" }, "paisOrigen": { "type": "string", "description": "País de origen del producto (E712); su descripción se deriva", "enum": [ "DZA", "EGY", "LBY", "MAR", "SDN", "TUN", "ESH", "IOT", "BDI", "COM", "DJI", "ERI", "ETH", "ATF", "KEN", "MDG", "MWI", "MUS", "MYT", "MOZ", "REU", "RWA", "SYC", "SOM", "SSD", "UGA", "TZA", "ZMB", "ZWE", "AGO", "CMR", "CAF", "TCD", "COG", "COD", "GNQ", "GAB", "STP", "BWA", "LSO", "NAM", "ZAF", "SWZ", "BEN", "BFA", "CPV", "CIV", "GMB", "GHA", "GIN", "GNB", "LBR", "MLI", "MRT", "NER", "NGA", "SHN", "SEN", "SLE", "TGO", "AIA", "ATG", "ABW", "BHS", "BRB", "BES", "VGB", "CYM", "CUB", "CUW", "DMA", "DOM", "GRD", "GLP", "HTI", "JAM", "MTQ", "MSR", "PRI", "BLM", "KNA", "LCA", "MAF", "VCT", "SXM", "TTO", "TCA", "VIR", "BLZ", "CRI", "SLV", "GTM", "HND", "MEX", "NIC", "PAN", "ARG", "BOL", "BRA", "CHL", "COL", "ECU", "FLK", "GUF", "GUY", "PRY", "PER", "SGS", "SUR", "URY", "VEN", "BMU", "CAN", "GRL", "SPM", "USA", "ATA", "KAZ", "KGZ", "TJK", "TKM", "UZB", "CHN", "HKG", "MAC", "TWN", "PRK", "JPN", "MNG", "KOR", "BRN", "KHM", "IDN", "LAO", "MYS", "MMR", "PHL", "SGP", "THA", "TLS", "VNM", "AFG", "BGD", "BTN", "IND", "IRN", "MDV", "NPL", "PAK", "LKA", "ARM", "AZE", "BHR", "CYP", "GEO", "IRQ", "ISR", "JOR", "KWT", "LBN", "OMN", "QAT", "SAU", "PSE", "SYR", "TUR", "ARE", "YEM", "BLR", "BGR", "CZE", "HUN", "POL", "MDA", "ROU", "RUS", "SVK", "UKR", "ALA", "GGY", "JEY", "DNK", "EST", "FRO", "FIN", "ISL", "IRL", "IMN", "LVA", "LTU", "NOR", "SJM", "SWE", "GBR", "ALB", "AND", "BIH", "HRV", "GIB", "GRC", "VAT", "ITA", "MLT", "MNE", "PRT", "SMR", "SRB", "SVN", "ESP", "MKD", "AUT", "BEL", "FRA", "DEU", "LIE", "LUX", "MCO", "NLD", "CHE", "AUS", "CXR", "CCK", "HMD", "NZL", "NFK", "FJI", "NCL", "PNG", "SLB", "VUT", "GUM", "KIR", "MHL", "FSM", "NRU", "MNP", "PLW", "UMI", "ASM", "COK", "PYF", "NIU", "PCN", "WSM", "TKL", "TON", "TUV", "WLF", "NN" ], "example": "BRA" }, "codigoDncpGeneral": { "type": "string", "description": "Código DNCP general (E704), string de exactamente 8 dígitos, opcional en cualquier operación", "example": "00123456", "maxLength": 8, "minLength": 8, "pattern": "\\d{8}" }, "codigoDncpEspecifico": { "type": "string", "description": "Código DNCP específico (E705), string de 3 a 4 dígitos, opcional en cualquier operación", "example": "0123", "maxLength": 4, "minLength": 3, "pattern": "\\d{3,4}" }, "partidaArancelaria": { "type": "string", "description": "Partida arancelaria (E702), string de 4 dígitos", "example": "8471", "pattern": "(?=.*[1-9])[0-9]{4}" }, "ncm": { "type": "string", "description": "Nomenclatura común del Mercosur (E703), string de 6 a 8 dígitos", "example": "84713012", "pattern": "(?=.*[1-9])[0-9]{6,8}" }, "gtin": { "type": "string", "description": "GTIN del producto (E706), string", "example": "07891234567895", "pattern": "(?=.*[1-9])(?:[0-9]{8}|[0-9]{12,14})" }, "gtinPaquete": { "type": "string", "description": "GTIN del paquete (E707), string", "pattern": "(?=.*[1-9])(?:[0-9]{8}|[0-9]{12,14})" }, "observacion": { "type": "string", "description": "Información de interés del emisor sobre el ítem (E714)", "maxLength": 500, "minLength": 1 }, "lote": { "type": "string", "description": "Número de lote (E751)", "example": "L-2026-04", "maxLength": 80, "minLength": 1 }, "vencimiento": { "type": "string", "format": "date", "description": "Fecha de vencimiento de la mercadería (E752)", "example": "2027-12-31" }, "numeroSerie": { "type": "string", "description": "Número de serie (E753)", "maxLength": 10, "minLength": 1 }, "numeroPedido": { "type": "string", "description": "Número de pedido (E754)", "maxLength": 20, "minLength": 1 }, "numeroSeguimiento": { "type": "string", "description": "Número de seguimiento (E755)", "maxLength": 20, "minLength": 1 }, "numeroRegistroProducto": { "type": "string", "description": "Número de registro del producto ante la autoridad competente (E759, NT010)", "maxLength": 20, "minLength": 1 }, "numeroRegistroEntidadComercial": { "type": "string", "description": "Número de registro de la entidad comercial (E760, NT010)", "maxLength": 20, "minLength": 1 }, "nombreProducto": { "type": "string", "description": "Nombre del producto según el registro (E761, NT010)", "maxLength": 30, "minLength": 1 }, "vehiculoNuevo": { "$ref": "#/components/schemas/VehiculoNuevoDTO", "description": "Datos del vehículo nuevo vendido en el ítem (E770)" } }, "required": [ "afectacionTributaria", "cantidad", "codigo", "descripcion", "precioUnitario", "unidadMedida" ] }, "ItemDocumento": { "type": "object", "properties": { "descripcion": { "type": "string" }, "unidadMedida": { "type": "string", "enum": [ "kWh", "AA", "BG", "_4A", "AB", "BX", "CM", "CM2", "CM3", "BK", "CPM", "Ci", "DET", "Di", "DOC", "DPC", "BL", "GLL", "g", "GRO", "ha", "Hs", "SET", "E4", "kg", "kg_m2", "Km", "KT", "LT", "U_JGO", "ME", "ml", "m", "MT", "M2", "M3", "M5", "MCU", "MG", "ML", "MIL", "MM", "MM2", "Mi", "PK", "PAR", "BW", "FOT", "FTK", "PCE", "pm", "JR", "PUL", "KLT", "racion", "RM", "RO", "Se", "DR", "TN", "UNI", "UI", "GL", "Ya" ] }, "codigo": { "type": "string" }, "cantidad": { "type": "number" } } }, "ItemRemisionDTO": { "type": "object", "additionalProperties": { "type": "null" }, "properties": { "codigo": { "type": "string", "maxLength": 50, "minLength": 0 }, "descripcion": { "type": "string", "maxLength": 2000, "minLength": 0 }, "cantidad": { "type": "number", "maximum": 10000000000, "minimum": 1e-8 }, "unidadMedida": { "type": "string", "enum": [ "kWh", "AA", "BG", "_4A", "AB", "BX", "CM", "CM2", "CM3", "BK", "CPM", "Ci", "DET", "Di", "DOC", "DPC", "BL", "GLL", "g", "GRO", "ha", "Hs", "SET", "E4", "kg", "kg_m2", "Km", "KT", "LT", "U_JGO", "ME", "ml", "m", "MT", "M2", "M3", "M5", "MCU", "MG", "ML", "MIL", "MM", "MM2", "Mi", "PK", "PAR", "BW", "FOT", "FTK", "PCE", "pm", "JR", "PUL", "KLT", "racion", "RM", "RO", "Se", "DR", "TN", "UNI", "UI", "GL", "Ya" ] }, "codigoDncpGeneral": { "type": "string", "pattern": "\\d{8}" }, "codigoDncpEspecifico": { "type": "string", "pattern": "\\d{3,4}" }, "partidaArancelaria": { "type": "string", "pattern": "(?=.*[1-9])[0-9]{4}" }, "ncm": { "type": "string", "pattern": "(?=.*[1-9])[0-9]{6,8}" }, "gtin": { "type": "string", "pattern": "(?=.*[1-9])(?:[0-9]{8}|[0-9]{12,14})" }, "gtinPaquete": { "type": "string", "pattern": "(?=.*[1-9])(?:[0-9]{8}|[0-9]{12,14})" }, "paisOrigen": { "type": "string", "enum": [ "DZA", "EGY", "LBY", "MAR", "SDN", "TUN", "ESH", "IOT", "BDI", "COM", "DJI", "ERI", "ETH", "ATF", "KEN", "MDG", "MWI", "MUS", "MYT", "MOZ", "REU", "RWA", "SYC", "SOM", "SSD", "UGA", "TZA", "ZMB", "ZWE", "AGO", "CMR", "CAF", "TCD", "COG", "COD", "GNQ", "GAB", "STP", "BWA", "LSO", "NAM", "ZAF", "SWZ", "BEN", "BFA", "CPV", "CIV", "GMB", "GHA", "GIN", "GNB", "LBR", "MLI", "MRT", "NER", "NGA", "SHN", "SEN", "SLE", "TGO", "AIA", "ATG", "ABW", "BHS", "BRB", "BES", "VGB", "CYM", "CUB", "CUW", "DMA", "DOM", "GRD", "GLP", "HTI", "JAM", "MTQ", "MSR", "PRI", "BLM", "KNA", "LCA", "MAF", "VCT", "SXM", "TTO", "TCA", "VIR", "BLZ", "CRI", "SLV", "GTM", "HND", "MEX", "NIC", "PAN", "ARG", "BOL", "BRA", "CHL", "COL", "ECU", "FLK", "GUF", "GUY", "PRY", "PER", "SGS", "SUR", "URY", "VEN", "BMU", "CAN", "GRL", "SPM", "USA", "ATA", "KAZ", "KGZ", "TJK", "TKM", "UZB", "CHN", "HKG", "MAC", "TWN", "PRK", "JPN", "MNG", "KOR", "BRN", "KHM", "IDN", "LAO", "MYS", "MMR", "PHL", "SGP", "THA", "TLS", "VNM", "AFG", "BGD", "BTN", "IND", "IRN", "MDV", "NPL", "PAK", "LKA", "ARM", "AZE", "BHR", "CYP", "GEO", "IRQ", "ISR", "JOR", "KWT", "LBN", "OMN", "QAT", "SAU", "PSE", "SYR", "TUR", "ARE", "YEM", "BLR", "BGR", "CZE", "HUN", "POL", "MDA", "ROU", "RUS", "SVK", "UKR", "ALA", "GGY", "JEY", "DNK", "EST", "FRO", "FIN", "ISL", "IRL", "IMN", "LVA", "LTU", "NOR", "SJM", "SWE", "GBR", "ALB", "AND", "BIH", "HRV", "GIB", "GRC", "VAT", "ITA", "MLT", "MNE", "PRT", "SMR", "SRB", "SVN", "ESP", "MKD", "AUT", "BEL", "FRA", "DEU", "LIE", "LUX", "MCO", "NLD", "CHE", "AUS", "CXR", "CCK", "HMD", "NZL", "NFK", "FJI", "NCL", "PNG", "SLB", "VUT", "GUM", "KIR", "MHL", "FSM", "NRU", "MNP", "PLW", "UMI", "ASM", "COK", "PYF", "NIU", "PCN", "WSM", "TKL", "TON", "TUV", "WLF", "NN" ] }, "observacion": { "type": "string", "maxLength": 500, "minLength": 1 }, "tolerancia": { "type": "string", "enum": [ "TOLERANCIA_DE_QUIEBRA", "TOLERANCIO_DE_MERMA" ] }, "toleranciaCantidad": { "type": "number", "maximum": 9999999999.9999, "minimum": 0 }, "toleranciaPorcentaje": { "type": "number", "maximum": 100, "minimum": 0 }, "lote": { "type": "string", "maxLength": 80, "minLength": 1 }, "vencimiento": { "type": "string", "format": "date" }, "numeroSerie": { "type": "string", "maxLength": 10, "minLength": 1 }, "numeroPedido": { "type": "string", "maxLength": 20, "minLength": 1 }, "numeroSeguimiento": { "type": "string", "maxLength": 20, "minLength": 1 }, "numeroRegistroProducto": { "type": "string", "maxLength": 20, "minLength": 1 }, "numeroRegistroEntidadComercial": { "type": "string", "maxLength": 20, "minLength": 1 }, "nombreProducto": { "type": "string", "maxLength": 30, "minLength": 1 } }, "required": [ "cantidad", "codigo", "descripcion", "unidadMedida" ] }, "LocalRemisionDTO": { "type": "object", "properties": { "direccion": { "type": "string", "maxLength": 255, "minLength": 0 }, "numeroCasa": { "type": "integer", "format": "int32", "maximum": 999999, "minimum": 0 }, "complementoDireccion1": { "type": "string", "maxLength": 255, "minLength": 1, "pattern": "(?s).*\\S.*" }, "complementoDireccion2": { "type": "string", "maxLength": 255, "minLength": 1, "pattern": "(?s).*\\S.*" }, "departamento": { "type": "string", "minLength": 1 }, "codigoDistrito": { "type": "integer", "format": "int32" }, "ciudad": { "type": "string", "minLength": 1 }, "telefono": { "type": "string", "maxLength": 15, "minLength": 6, "pattern": "(?s).*\\S.*" } }, "required": [ "ciudad", "departamento", "direccion", "numeroCasa" ] }, "NotaCreditoElectronicaRequest": { "allOf": [ { "$ref": "#/components/schemas/DocumentoElectronicoRequest" }, { "type": "object", "properties": { "receptor": { "$ref": "#/components/schemas/ReceptorDTO" }, "items": { "type": "array", "description": "Ítems del documento. Al menos uno", "items": { "$ref": "#/components/schemas/ItemDTO" }, "minItems": 1 }, "comision": { "type": "number", "description": "Comisión de la operación (F025), IVA 10% incluido. Se suma al total general y su IVA al total de IVA", "example": 55000, "minimum": 0 }, "motivoEmision": { "type": "string", "description": "Motivo del ajuste", "enum": [ "DEVOLUCION_Y_AJUSTES_DE_PRECIOS", "DEVOLUCION", "DESCUENTO", "BONIFICACION", "CREDITO_INCOBRABLE", "RECUPERO_DE_COSTO", "RECUPERO_DE_GASTO", "AJUSTE_DE_PRECIO" ], "example": "DEVOLUCION" }, "documentoAsociado": { "$ref": "#/components/schemas/DocumentoAsociadoDTO", "description": "Documento que se está modificando" } } }, { "allOf": [ { "if": { "properties": { "monedaOperacion": { "const": "PYG" } } }, "then": { "not": { "required": [ "tipoCambio" ] }, "properties": { "items": { "type": "array", "items": { "not": { "required": [ "tipoCambio" ] } } } } } }, { "if": { "properties": { "monedaOperacion": { "not": { "const": "PYG" } } }, "required": [ "monedaOperacion" ] }, "then": { "oneOf": [ { "properties": { "items": { "type": "array", "items": { "not": { "required": [ "tipoCambio" ] } } } }, "required": [ "tipoCambio" ] }, { "not": { "required": [ "tipoCambio" ] }, "properties": { "items": { "type": "array", "items": { "required": [ "tipoCambio" ] } } } } ] } } ] }, { "properties": { "tipoDocumento": { "const": "NOTA_DE_CREDITO_ELECTRONICA" } } } ], "description": "Nota de crédito electrónica — `tipoDocumento = NOTA_DE_CREDITO_ELECTRONICA`. No lleva `tipoTransaccion` ni `condicionOperacion`.", "required": [ "documentoAsociado", "items", "motivoEmision", "numeroEstablecimiento", "puntoExpedicion", "receptor", "tipoDocumento", "tipoEmision" ] }, "NotaDebitoElectronicaRequest": { "allOf": [ { "$ref": "#/components/schemas/DocumentoElectronicoRequest" }, { "type": "object", "properties": { "receptor": { "$ref": "#/components/schemas/ReceptorDTO" }, "items": { "type": "array", "description": "Ítems del documento. Al menos uno", "items": { "$ref": "#/components/schemas/ItemDTO" }, "minItems": 1 }, "comision": { "type": "number", "description": "Comisión de la operación (F025), IVA 10% incluido. Se suma al total general y su IVA al total de IVA", "example": 55000, "minimum": 0 }, "motivoEmision": { "type": "string", "description": "Motivo del ajuste", "enum": [ "DEVOLUCION_Y_AJUSTES_DE_PRECIOS", "DEVOLUCION", "DESCUENTO", "BONIFICACION", "CREDITO_INCOBRABLE", "RECUPERO_DE_COSTO", "RECUPERO_DE_GASTO", "AJUSTE_DE_PRECIO" ], "example": "AJUSTE_DE_PRECIO" }, "documentoAsociado": { "$ref": "#/components/schemas/DocumentoAsociadoDTO", "description": "Documento que se está modificando" } } }, { "allOf": [ { "if": { "properties": { "monedaOperacion": { "const": "PYG" } } }, "then": { "not": { "required": [ "tipoCambio" ] }, "properties": { "items": { "type": "array", "items": { "not": { "required": [ "tipoCambio" ] } } } } } }, { "if": { "properties": { "monedaOperacion": { "not": { "const": "PYG" } } }, "required": [ "monedaOperacion" ] }, "then": { "oneOf": [ { "properties": { "items": { "type": "array", "items": { "not": { "required": [ "tipoCambio" ] } } } }, "required": [ "tipoCambio" ] }, { "not": { "required": [ "tipoCambio" ] }, "properties": { "items": { "type": "array", "items": { "required": [ "tipoCambio" ] } } } } ] } } ] }, { "properties": { "tipoDocumento": { "const": "NOTA_DE_DEBITO_ELECTRONICA" } } } ], "description": "Nota de débito electrónica — `tipoDocumento = NOTA_DE_DEBITO_ELECTRONICA`. No lleva `tipoTransaccion` ni `condicionOperacion`.", "required": [ "documentoAsociado", "items", "motivoEmision", "numeroEstablecimiento", "puntoExpedicion", "receptor", "tipoDocumento", "tipoEmision" ] }, "NotaRemisionElectronicaRequest": { "allOf": [ { "$ref": "#/components/schemas/DocumentoElectronicoRequest" }, { "type": "object", "properties": { "receptor": { "$ref": "#/components/schemas/ReceptorDTO" }, "items": { "type": "array", "description": "Ítems del documento. Al menos uno", "items": { "$ref": "#/components/schemas/ItemRemisionDTO" }, "maxItems": 999, "minItems": 1 }, "motivoTraslado": { "type": "string", "enum": [ "TRASLADO_POR_VENTAS", "TRASLADO_POR_CONSIGNACION", "EXPORTACION", "TRASLADO_POR_COMPRA", "IMPORTACION", "TRASLADO_POR_DEVOLUCION", "TRASLADO_ENTRE_LOCALES", "TRASLADO_BIENES_TRANSFORMACION", "TRASLADO_BIENES_REPARACION", "TRASLADO_POR_EMISOR_MOVIL", "EXHIBICION_O_DEMOSTRACION", "PARTICIPACION_EN_FERIAS", "TRASLADO_DE_ENCOMIENDAS", "DECOMISO", "OTRO" ] }, "descripcionMotivoTraslado": { "type": "string", "maxLength": 60, "minLength": 5, "pattern": "(?s).*\\S.*" }, "responsableEmision": { "type": "string", "enum": [ "EMISOR_FACTURA", "POSEEDOR_FACTURA_Y_BIENES", "EMPRESA_TRANSPORTISTA", "DESPACHANTE_DE_ADUANAS", "AGENTE_DE_TRANSPORTE_O_INTERMEDIARIO" ] }, "kilometrosRecorrido": { "type": "integer", "format": "int32", "maximum": 99999, "minimum": 1 }, "costoFlete": { "type": "number", "minimum": 0 }, "fechaFacturaFutura": { "type": "string", "format": "date", "description": "Obligatoria en venta sin asociaciones; mes/año no posterior a la emisión efectiva" }, "informacionFiscal": { "type": "string", "maxLength": 3000, "minLength": 1 }, "carga": { "$ref": "#/components/schemas/CargaRemisionDTO" }, "transporte": { "$ref": "#/components/schemas/TransporteRemisionDTO" }, "documentosAsociados": { "type": "array", "description": "Sólo facturas asociadas: CDC electrónico con prefijo 01 o tipoDocumentoImpreso FACTURA (H001a/2414)", "items": { "$ref": "#/components/schemas/DocumentoAsociadoRemisionDTO" }, "maxItems": 99, "minItems": 0 } } }, { "not": { "anyOf": [ { "required": [ "tipoCambio" ] }, { "required": [ "descuentoGlobalPorcentaje" ] } ] }, "properties": { "items": { "type": "array", "items": { "not": { "anyOf": [ { "required": [ "tipoCambio" ] }, { "required": [ "descuentoParticular" ] } ] } } }, "monedaOperacion": { "const": "PYG" } } }, { "properties": { "tipoDocumento": { "const": "NOTA_DE_REMISION_ELECTRONICA" } } } ], "description": "Nota de remisión electrónica — `tipoDocumento = NOTA_DE_REMISION_ELECTRONICA`. La emisión de NRE está disponible. Antes de iniciar el traslado, esperá a que la nota de remisión esté en estado APROBADO o APROBADO_OBSERVACION. La `direccion` del receptor es obligatoria: documenta un traslado físico de mercadería. Ejemplos sintéticos nacional/importación/exportación: sólo tramo paraguayo, no sustituyen documentación ni autorización aduanera. Ajustar fechas e identidad al emisor; el registro no equivale a aprobación SIFEN.", "examples": [ { "tipoDocumento": "NOTA_DE_REMISION_ELECTRONICA", "fechaEmision": "2026-09-09T10:00:00", "numeroEstablecimiento": 1, "puntoExpedicion": 1, "tipoEmision": "NORMAL", "receptor": { "tipoContribuyente": "NO_CONTRIBUYENTE", "tipoOperacion": "B2F", "tipoDocumento": "PASAPORTE", "numeroDocumento": "000123", "nombreRazonSocial": "Receptor sintético", "pais": "ARG", "direccion": "Domicilio de prueba", "numeroCasa": 0 }, "responsableEmision": "EMISOR_FACTURA", "kilometrosRecorrido": 1, "transporte": { "transportista": { "naturaleza": "NO_CONTRIBUYENTE", "nombreRazonSocial": "Transportista sintético", "tipoDocumento": "PASAPORTE", "numeroDocumento": "000123", "domicilioFiscal": "Domicilio sintético", "numeroDocumentoConductor": "000456", "nombreConductor": "Conductor sintético", "direccionConductor": "Dirección sintética" }, "tipoTransporte": "PROPIO", "modalidad": "TERRESTRE", "responsableFlete": "TRANSPORTE_PROPIO", "fechaInicioTraslado": "2026-09-09", "fechaFinTraslado": "2026-09-09", "salida": { "direccion": "Salida", "numeroCasa": 0, "departamento": "CENTRAL", "ciudad": "SAN LORENZO" }, "entregas": [ { "direccion": "Entrega", "numeroCasa": 0, "departamento": "CENTRAL", "ciudad": "SAN LORENZO" } ], "vehiculos": [ { "tipoVehiculo": "CAMION", "marca": "MARCA", "tipoIdentificacion": 1, "numeroIdentificacion": "001" } ] }, "items": [ { "codigo": "001", "descripcion": "Mercadería", "cantidad": 1, "unidadMedida": "UNI" } ], "motivoTraslado": "TRASLADO_POR_CONSIGNACION" }, { "tipoDocumento": "NOTA_DE_REMISION_ELECTRONICA", "fechaEmision": "2026-09-09T10:00:00", "numeroEstablecimiento": 1, "puntoExpedicion": 1, "tipoEmision": "NORMAL", "receptor": { "tipoContribuyente": "NO_CONTRIBUYENTE", "tipoOperacion": "B2F", "tipoDocumento": "PASAPORTE", "numeroDocumento": "000123", "nombreRazonSocial": "Receptor sintético", "pais": "ARG", "direccion": "Domicilio de prueba", "numeroCasa": 0 }, "responsableEmision": "EMISOR_FACTURA", "kilometrosRecorrido": 1, "transporte": { "transportista": { "naturaleza": "NO_CONTRIBUYENTE", "nombreRazonSocial": "Transportista sintético", "tipoDocumento": "PASAPORTE", "numeroDocumento": "000123", "domicilioFiscal": "Domicilio sintético", "numeroDocumentoConductor": "000456", "nombreConductor": "Conductor sintético", "direccionConductor": "Dirección sintética" }, "tipoTransporte": "PROPIO", "modalidad": "TERRESTRE", "responsableFlete": "TRANSPORTE_PROPIO", "fechaInicioTraslado": "2026-09-09", "fechaFinTraslado": "2026-09-09", "salida": { "direccion": "Salida", "numeroCasa": 0, "departamento": "CENTRAL", "ciudad": "SAN LORENZO" }, "entregas": [ { "direccion": "Entrega", "numeroCasa": 0, "departamento": "CENTRAL", "ciudad": "SAN LORENZO" } ], "vehiculos": [ { "tipoVehiculo": "CAMION", "marca": "MARCA", "tipoIdentificacion": 1, "numeroIdentificacion": "001" } ], "incoterm": "FOB", "paisDestino": "BRA", "numeroManifiesto": "000000000000001", "numeroDespachoImportacion": "0000000000000001" }, "items": [ { "codigo": "001", "descripcion": "Mercadería", "cantidad": 1, "unidadMedida": "UNI" } ], "motivoTraslado": "IMPORTACION" }, { "tipoDocumento": "NOTA_DE_REMISION_ELECTRONICA", "fechaEmision": "2026-09-09T10:00:00", "numeroEstablecimiento": 1, "puntoExpedicion": 1, "tipoEmision": "NORMAL", "receptor": { "tipoContribuyente": "NO_CONTRIBUYENTE", "tipoOperacion": "B2F", "tipoDocumento": "PASAPORTE", "numeroDocumento": "000123", "nombreRazonSocial": "Receptor sintético", "pais": "ARG", "direccion": "Domicilio de prueba", "numeroCasa": 0 }, "responsableEmision": "EMISOR_FACTURA", "kilometrosRecorrido": 1, "transporte": { "transportista": { "naturaleza": "NO_CONTRIBUYENTE", "nombreRazonSocial": "Transportista sintético", "tipoDocumento": "PASAPORTE", "numeroDocumento": "000123", "domicilioFiscal": "Domicilio sintético", "numeroDocumentoConductor": "000456", "nombreConductor": "Conductor sintético", "direccionConductor": "Dirección sintética" }, "tipoTransporte": "PROPIO", "modalidad": "TERRESTRE", "responsableFlete": "TRANSPORTE_PROPIO", "fechaInicioTraslado": "2026-09-09", "fechaFinTraslado": "2026-09-09", "salida": { "direccion": "Salida", "numeroCasa": 0, "departamento": "CENTRAL", "ciudad": "SAN LORENZO" }, "entregas": [ { "direccion": "Entrega", "numeroCasa": 0, "departamento": "CENTRAL", "ciudad": "SAN LORENZO" } ], "vehiculos": [ { "tipoVehiculo": "CAMION", "marca": "MARCA", "tipoIdentificacion": 1, "numeroIdentificacion": "001" } ], "incoterm": "FOB", "paisDestino": "BRA", "numeroManifiesto": "000000000000001" }, "items": [ { "codigo": "001", "descripcion": "Mercadería", "cantidad": 1, "unidadMedida": "UNI" } ], "motivoTraslado": "EXPORTACION" } ], "required": [ "items", "kilometrosRecorrido", "motivoTraslado", "numeroEstablecimiento", "puntoExpedicion", "receptor", "responsableEmision", "tipoDocumento", "tipoEmision", "transporte" ], "unevaluatedProperties": { "type": "null" } }, "PagoFacturaDTO": { "type": "object", "description": "Un medio de pago de la factura (E605). En contado cubre el total; en crédito, la entrega inicial", "properties": { "tipoPago": { "type": "string", "description": "Medio de pago (E606)", "enum": [ "EFECTIVO", "CHEQUE", "TARJETA_DE_CREDITO", "TARJETA_DE_DEBITO", "TRANSFERENCIA", "GIRO", "BILLETERA_ELECTRONICA", "TARJETA_EMPRESARIAL", "VALE", "RETENCION", "PAGO_POR_ANTICIPO", "VALOR_FISCAL", "VALOR_COMERCIAL", "COMPENSACION", "PERMUTA", "PAGO_BANCARIO", "PAGO_MOVIL", "DONACION", "PROMOCION", "CONSUMO_INTERNO", "PAGO_ELECTRONICO", "OTRO" ], "example": "TRANSFERENCIA" }, "descripcionTipoPago": { "type": "string", "description": "Descripción propia del medio (E607). Obligatoria y exclusiva de `tipoPago = OTRO`", "maxLength": 30, "minLength": 4, "pattern": "(?s).*\\S.*" }, "montoPago": { "type": "number", "description": "Importe aplicado a la factura, en `monedaPago` (E608)", "example": 60000, "minimum": 0 }, "monedaPago": { "type": "string", "description": "Moneda del pago (E609)", "enum": [ "AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", "AUD", "AWG", "AZM", "BAM", "BBD", "BYN", "BDT", "BGN", "BHD", "BIF", "BMD", "BND", "BOB", "BOV", "BRL", "BSD", "BTN", "BWP", "BYR", "BZD", "CAD", "CDF", "CHF", "CHE", "CHW", "CLP", "CLF", "CNY", "COP", "COU", "CRC", "CUP", "CUC", "CVE", "CYP", "CZK", "DJF", "DKK", "DOP", "DZD", "EEK", "EGP", "ERN", "ETB", "EUR", "FJD", "FKP", "GBP", "GEL", "GHS", "GHC", "GIP", "GMD", "GNF", "GTQ", "GYD", "HKD", "HNL", "HRK", "HTG", "HUF", "IDR", "ILS", "INR", "IQD", "IRR", "ISK", "JMD", "JOD", "JPY", "KES", "KGS", "KHR", "KMF", "KPW", "KRW", "KWD", "KYD", "KZT", "LAK", "LBP", "LKR", "LRD", "LSL", "LTL", "LVL", "LYD", "MAD", "MZN", "MDL", "MGF", "MKD", "MGA", "MMK", "MNT", "MOP", "MRO", "MTL", "MUR", "XUA", "MVR", "MRU", "MWK", "MXN", "MXV", "MYR", "MZM", "NAD", "NGN", "NIO", "NOK", "NPR", "NZD", "OMR", "PAB", "PEN", "PGK", "PHP", "PKR", "PLN", "PYG", "QAR", "RON", "ROL", "RUB", "RWF", "SAR", "RSD", "SBD", "SCR", "SDD", "SDG", "SRD", "SEK", "SGD", "SHP", "SIT", "SKK", "SLL", "SOS", "SRG", "SSP", "STD", "SVC", "SYP", "SZL", "THB", "TJS", "TMM", "TND", "TRY", "TMT", "TOP", "TRL", "TTD", "TWD", "TZS", "UAH", "UGX", "USD", "USN", "UYU", "UYI", "UYW", "UZS", "VEB", "VND", "VUV", "VES", "WST", "STN", "XAF", "XAG", "XAU", "XCD", "XDR", "XOF", "XPD", "XPF", "XPT", "XSU", "XBA", "XBB", "XBC", "XTS", "XXX", "YER", "YUM", "ZMW", "ZWL", "ZAR", "ZMK", "ZWD" ], "example": "PYG" }, "tipoCambio": { "type": "number", "description": "Tipo de cambio de `monedaPago` (E611). Obligatorio fuera de PYG; prohibido en PYG", "maximum": 99999.9999, "minimum": 0 }, "tarjeta": { "$ref": "#/components/schemas/TarjetaPagoDTO", "description": "Datos de la tarjeta (E620). Obligatorio y exclusivo de tarjeta de crédito o débito" }, "cheque": { "$ref": "#/components/schemas/ChequePagoDTO", "description": "Datos del cheque (E630). Obligatorio y exclusivo de `tipoPago = CHEQUE`" } }, "required": [ "monedaPago", "montoPago", "tipoPago" ] }, "PlazoEstructuradoDTO": { "type": "object", "properties": { "cantidad": { "type": "integer", "format": "int32", "maximum": 9999, "minimum": 1 }, "unidad": { "type": "string", "enum": [ "DIAS", "MESES" ] } }, "required": [ "cantidad", "unidad" ] }, "PolizaSeguroDTO": { "type": "object", "description": "Póliza de seguros (EA790)", "properties": { "codigo": { "type": "string", "description": "Código de la póliza (EA791)", "maxLength": 20, "minLength": 0 }, "unidadVigencia": { "type": "string", "description": "Unidad de tiempo de la vigencia (EA792): hora, día, mes, año", "example": "mes", "maxLength": 15, "minLength": 3 }, "vigencia": { "type": "number", "description": "Vigencia en la unidad indicada (EA793)", "example": 12, "minimum": 0 }, "numero": { "type": "string", "description": "Número de la póliza (EA794)", "maxLength": 25, "minLength": 0 }, "fechaInicioVigencia": { "type": "string", "format": "date-time", "description": "Inicio de vigencia (EA795), `AAAA-MM-DDThh:mm:ss`", "example": "2026-01-01T00:00:00" }, "fechaFinVigencia": { "type": "string", "format": "date-time", "description": "Fin de vigencia (EA796), no anterior al inicio", "example": "2026-12-31T23:59:59" }, "codigoItem": { "type": "string", "description": "Código de un ítem de la factura para asociar la póliza (EA797, NT008)", "maxLength": 50, "minLength": 1 } }, "required": [ "codigo", "numero", "unidadVigencia", "vigencia" ] }, "ReceptorDTO": { "type": "object", "allOf": [ { "if": { "properties": { "tipoContribuyente": { "const": "CONTRIBUYENTE" } }, "required": [ "tipoContribuyente" ] }, "then": { "required": [ "digitoVerificador", "tipoContribuyenteReceptor" ] } }, { "if": { "properties": { "tipoContribuyente": { "const": "NO_CONTRIBUYENTE" } }, "required": [ "tipoContribuyente" ] }, "then": { "required": [ "tipoDocumento" ] } }, { "if": { "properties": { "tipoOperacion": { "const": "B2F" } }, "required": [ "tipoOperacion" ] }, "then": { "not": { "anyOf": [ { "required": [ "tipoContribuyenteReceptor" ] }, { "required": [ "digitoVerificador" ] }, { "required": [ "departamento" ] }, { "required": [ "codigoDistrito" ] }, { "required": [ "ciudad" ] } ] }, "properties": { "tipoDocumento": { "not": { "const": "INNOMINADO" } }, "direccion": { "type": "string", "pattern": "\\S" }, "tipoContribuyente": { "const": "NO_CONTRIBUYENTE" }, "pais": { "not": { "const": "PRY" } } }, "required": [ "direccion", "nombreRazonSocial", "numeroCasa", "pais", "tipoContribuyente", "tipoDocumento" ] } }, { "if": { "properties": { "tipoOperacion": { "const": "B2G" } }, "required": [ "tipoOperacion" ] }, "then": { "not": { "required": [ "tipoDocumento" ] }, "properties": { "numeroDocumento": { "type": "string", "pattern": "\\d{3,8}" }, "tipoContribuyente": { "const": "CONTRIBUYENTE" }, "pais": { "const": "PRY" }, "digitoVerificador": { "type": "string", "pattern": "\\d" } }, "required": [ "digitoVerificador", "numeroDocumento", "pais", "tipoContribuyente", "tipoContribuyenteReceptor" ] } }, { "if": { "not": { "properties": { "tipoOperacion": { "const": "B2F" } }, "required": [ "tipoOperacion" ] } }, "then": { "required": [ "numeroDocumento" ] } } ], "description": "Destinatario del documento. Los nombres de los campos no cambian entre operaciones, pero\ncuáles son obligatorios lo decide `tipoContribuyente`, y es el motivo de rechazo más\nfrecuente al integrar:\n\n- `CONTRIBUYENTE` exige `tipoContribuyenteReceptor` y `digitoVerificador`, y no lleva\n `tipoDocumento`.\n- `NO_CONTRIBUYENTE` exige `tipoDocumento`, y no lleva los otros dos: SIFEN rechaza\n `tipoContribuyenteReceptor` en un no contribuyente con el código 1303.\n\nLas dos reglas van como `if`/`then` en este schema, así que un validador las detecta antes\nde mandar el request.\n", "properties": { "tipoContribuyente": { "type": "string", "description": "Naturaleza del receptor (D201). Siempre se envía", "enum": [ "CONTRIBUYENTE", "NO_CONTRIBUYENTE" ], "example": "CONTRIBUYENTE" }, "tipoOperacion": { "type": "string", "description": "Tipo de operación: B2B, B2C, B2G (organismo público) o B2F (cliente del exterior)", "enum": [ "B2B", "B2C", "B2G", "B2F" ], "example": "B2B" }, "tipoContribuyenteReceptor": { "type": "string", "description": "Persona física o jurídica (D205). Obligatorio si `tipoContribuyente = CONTRIBUYENTE`; no se envía para un no contribuyente", "enum": [ "PERSONA_FISICA", "PERSONA_JURIDICA" ], "example": "PERSONA_JURIDICA" }, "tipoDocumento": { "type": "string", "description": "Tipo de documento de identidad del receptor (D208). Su descripción D209 se deriva del catálogo. Obligatorio si `tipoContribuyente = NO_CONTRIBUYENTE`; no se envía para un contribuyente", "enum": [ "CEDULA_PARAGUAYA", "PASAPORTE", "CEDULA_EXTRANJERA", "CARNET_DE_RESIDENCIA", "INNOMINADO", "TARJETA_DIPLOMATICA", "OTRO" ], "example": "CEDULA_PARAGUAYA" }, "descripcionTipoDocumento": { "type": "string", "description": "Descripción propia del documento de identidad (D209). Obligatoria y exclusiva de `tipoDocumento = OTRO`", "example": "Carnet de refugiado", "maxLength": 41, "minLength": 9 }, "numeroDocumento": { "type": "string", "description": "RUC sin el dígito verificador para un contribuyente; número de identidad (D210) para un no contribuyente. Para el receptor innominado, el literal `0`. Opcional sólo en B2F", "example": "80012345" }, "nombreRazonSocial": { "type": "string", "description": "Nombre completo o razón social (D211). Para el receptor innominado, el literal `Sin Nombre`", "example": "Comercial San Roque S.A.", "maxLength": 255, "minLength": 4 }, "digitoVerificador": { "type": "string", "description": "Dígito verificador del RUC, un solo dígito. Obligatorio si `tipoContribuyente = CONTRIBUYENTE`", "example": "0", "pattern": "\\d" }, "nombreFantasia": { "type": "string", "description": "Nombre de fantasía del receptor (D212)", "example": "San Roque", "maxLength": 255, "minLength": 4 }, "direccion": { "type": "string", "description": "Domicilio del receptor (D213). Obligatorio para `tipoOperacion = B2F` y para la nota de remisión, que documenta un traslado físico; opcional en el resto", "example": "Avda. Mariscal López 1234", "maxLength": 255, "minLength": 0 }, "numeroCasa": { "type": "integer", "format": "int32", "description": "Número de casa (D218)", "example": 1234, "maximum": 999999, "minimum": 0 }, "departamento": { "type": "string", "description": "Departamento del catálogo paraguayo (D219)", "example": "CENTRAL" }, "codigoDistrito": { "type": "integer", "format": "int32", "description": "Código de distrito del catálogo paraguayo (D221)", "example": 1 }, "ciudad": { "type": "string", "description": "Ciudad del catálogo paraguayo (D223)", "example": "Asunción" }, "telefono": { "type": "string", "description": "Teléfono del receptor (D214)", "example": "021123456", "pattern": "^(\\s*|[\\s\\S]{6,15})$" }, "celular": { "type": "string", "description": "Teléfono móvil", "example": "0981123456", "pattern": "^(\\s*|[\\s\\S]{10,20})$" }, "email": { "type": "string", "format": "email", "description": "Si el envío automático está configurado, Sifende manda el KuDE a esta dirección", "example": "facturacion@sanroque.com.py", "pattern": "^(\\s*|[\\s\\S]{3,80})$" }, "codigoCliente": { "type": "string", "description": "Código interno con el que el emisor identifica al cliente (D217)", "example": "CLI-001", "maxLength": 15, "minLength": 3 }, "pais": { "type": "string", "default": "PRY", "description": "País del receptor en código ISO. Sólo se cambia para receptores del exterior", "enum": [ "DZA", "EGY", "LBY", "MAR", "SDN", "TUN", "ESH", "IOT", "BDI", "COM", "DJI", "ERI", "ETH", "ATF", "KEN", "MDG", "MWI", "MUS", "MYT", "MOZ", "REU", "RWA", "SYC", "SOM", "SSD", "UGA", "TZA", "ZMB", "ZWE", "AGO", "CMR", "CAF", "TCD", "COG", "COD", "GNQ", "GAB", "STP", "BWA", "LSO", "NAM", "ZAF", "SWZ", "BEN", "BFA", "CPV", "CIV", "GMB", "GHA", "GIN", "GNB", "LBR", "MLI", "MRT", "NER", "NGA", "SHN", "SEN", "SLE", "TGO", "AIA", "ATG", "ABW", "BHS", "BRB", "BES", "VGB", "CYM", "CUB", "CUW", "DMA", "DOM", "GRD", "GLP", "HTI", "JAM", "MTQ", "MSR", "PRI", "BLM", "KNA", "LCA", "MAF", "VCT", "SXM", "TTO", "TCA", "VIR", "BLZ", "CRI", "SLV", "GTM", "HND", "MEX", "NIC", "PAN", "ARG", "BOL", "BRA", "CHL", "COL", "ECU", "FLK", "GUF", "GUY", "PRY", "PER", "SGS", "SUR", "URY", "VEN", "BMU", "CAN", "GRL", "SPM", "USA", "ATA", "KAZ", "KGZ", "TJK", "TKM", "UZB", "CHN", "HKG", "MAC", "TWN", "PRK", "JPN", "MNG", "KOR", "BRN", "KHM", "IDN", "LAO", "MYS", "MMR", "PHL", "SGP", "THA", "TLS", "VNM", "AFG", "BGD", "BTN", "IND", "IRN", "MDV", "NPL", "PAK", "LKA", "ARM", "AZE", "BHR", "CYP", "GEO", "IRQ", "ISR", "JOR", "KWT", "LBN", "OMN", "QAT", "SAU", "PSE", "SYR", "TUR", "ARE", "YEM", "BLR", "BGR", "CZE", "HUN", "POL", "MDA", "ROU", "RUS", "SVK", "UKR", "ALA", "GGY", "JEY", "DNK", "EST", "FRO", "FIN", "ISL", "IRL", "IMN", "LVA", "LTU", "NOR", "SJM", "SWE", "GBR", "ALB", "AND", "BIH", "HRV", "GIB", "GRC", "VAT", "ITA", "MLT", "MNE", "PRT", "SMR", "SRB", "SVN", "ESP", "MKD", "AUT", "BEL", "FRA", "DEU", "LIE", "LUX", "MCO", "NLD", "CHE", "AUS", "CXR", "CCK", "HMD", "NZL", "NFK", "FJI", "NCL", "PNG", "SLB", "VUT", "GUM", "KIR", "MHL", "FSM", "NRU", "MNP", "PLW", "UMI", "ASM", "COK", "PYF", "NIU", "PCN", "WSM", "TKL", "TON", "TUV", "WLF", "NN" ], "example": "PRY" } }, "required": [ "nombreRazonSocial", "tipoContribuyente", "tipoOperacion" ] }, "SeguroDTO": { "type": "object", "description": "Sector de seguros (E800)", "properties": { "codigoEmpresa": { "type": "string", "description": "Código de la empresa de seguros en la Superintendencia de Seguros (E801)", "maxLength": 20, "minLength": 1 }, "polizas": { "type": "array", "description": "Pólizas (EA790), de 1 a 999", "items": { "$ref": "#/components/schemas/PolizaSeguroDTO" }, "maxItems": 999, "minItems": 0 } }, "required": [ "polizas" ] }, "SupermercadoDTO": { "type": "object", "description": "Sector de supermercados (E810). Describe la caja: el efectivo recibido y el vuelto no son\npagos de la factura, que se informan en `pagos` o `condicionPago`.\n", "properties": { "nombreCajero": { "type": "string", "description": "Nombre del cajero (E811)", "maxLength": 20, "minLength": 1 }, "efectivo": { "type": "number", "description": "Efectivo recibido (E812)", "minimum": 0 }, "vuelto": { "type": "number", "description": "Vuelto entregado (E813)", "minimum": 0 }, "donacion": { "type": "number", "description": "Monto de la donación (E814)", "minimum": 0 }, "descripcionDonacion": { "type": "string", "description": "Descripción de la donación (E815). Sólo con `donacion`", "maxLength": 20, "minLength": 1 } } }, "TarjetaPagoDTO": { "type": "object", "description": "Pago con tarjeta de crédito o débito (E620). Nunca se informa el número completo", "properties": { "tipoTarjeta": { "type": "string", "description": "Denominación (E621)", "enum": [ "VISA", "MASTERCARD", "AMERICAN_EXPRESS", "MAESTRO", "PANAL", "CABAL", "OTRO" ], "example": "VISA" }, "descripcionTipoTarjeta": { "type": "string", "description": "Descripción propia (E622). Obligatoria y exclusiva de `tipoTarjeta = OTRO`", "maxLength": 20, "minLength": 4, "pattern": "(?s).*\\S.*" }, "razonSocialProcesadora": { "type": "string", "description": "Razón social de la procesadora (E623)", "maxLength": 60, "minLength": 4, "pattern": "(?s).*\\S.*" }, "rucProcesadora": { "type": "string", "description": "RUC de la procesadora sin DV (E624)", "example": "80012345", "pattern": "[1-9][0-9]{1,6}[0-9A-D]" }, "digitoVerificadorProcesadora": { "type": "string", "description": "DV del RUC de la procesadora (E625). `0` es un valor", "example": "7", "pattern": "[0-9]" }, "formaProcesamientoPago": { "type": "string", "description": "Forma de procesamiento (E626)", "enum": [ "POS", "PAGO_ELECTRONICO", "OTRO" ], "example": "POS" }, "codigoAutorizacion": { "type": "string", "description": "Código de autorización (E627), como string: de 6 a 10 dígitos, desde 100000", "example": "123456", "pattern": "[1-9][0-9]{5,9}" }, "nombreTitular": { "type": "string", "description": "Nombre del titular (E628)", "maxLength": 30, "minLength": 4, "pattern": "(?s).*\\S.*" }, "ultimosCuatroDigitos": { "type": "string", "description": "Cuatro últimos dígitos (E629), como string", "example": "0001", "pattern": "(?!0000)[0-9]{4}" } }, "required": [ "formaProcesamientoPago", "tipoTarjeta" ] }, "TransporteFacturaDTO": { "type": "object", "description": "Transporte de la mercadería facturada (E900). Opcional en la FE: salida, entregas, vehículos y transportista se informan cuando se conocen", "properties": { "tipoTransporte": { "type": "string", "enum": [ "PROPIO", "TERCERO" ] }, "modalidad": { "type": "string", "enum": [ "TERRESTRE", "FLUVIAL", "AEREO", "MULTIMODAL" ] }, "responsableFlete": { "type": "string", "enum": [ "EMISOR_FACTURA_ELECTRONICA", "RECEPTOR_FACTURA_ELECTRONICA", "TERCERO", "AGENTE_INTERMEDIARIO", "TRANSPORTE_PROPIO" ] }, "incoterm": { "type": "string", "enum": [ "CFR", "CIF", "CIP", "CPT", "DAP", "DAT", "DDP", "EXW", "FAS", "FCA", "FOB" ] }, "numeroManifiesto": { "type": "string", "maxLength": 15, "minLength": 1, "pattern": "(?s).*\\S.*" }, "numeroDespachoImportacion": { "type": "string", "maxLength": 16, "minLength": 16, "pattern": "(?s).*\\S.*" }, "fechaInicioTraslado": { "type": "string", "format": "date" }, "fechaFinTraslado": { "type": "string", "format": "date" }, "paisDestino": { "type": "string", "enum": [ "DZA", "EGY", "LBY", "MAR", "SDN", "TUN", "ESH", "IOT", "BDI", "COM", "DJI", "ERI", "ETH", "ATF", "KEN", "MDG", "MWI", "MUS", "MYT", "MOZ", "REU", "RWA", "SYC", "SOM", "SSD", "UGA", "TZA", "ZMB", "ZWE", "AGO", "CMR", "CAF", "TCD", "COG", "COD", "GNQ", "GAB", "STP", "BWA", "LSO", "NAM", "ZAF", "SWZ", "BEN", "BFA", "CPV", "CIV", "GMB", "GHA", "GIN", "GNB", "LBR", "MLI", "MRT", "NER", "NGA", "SHN", "SEN", "SLE", "TGO", "AIA", "ATG", "ABW", "BHS", "BRB", "BES", "VGB", "CYM", "CUB", "CUW", "DMA", "DOM", "GRD", "GLP", "HTI", "JAM", "MTQ", "MSR", "PRI", "BLM", "KNA", "LCA", "MAF", "VCT", "SXM", "TTO", "TCA", "VIR", "BLZ", "CRI", "SLV", "GTM", "HND", "MEX", "NIC", "PAN", "ARG", "BOL", "BRA", "CHL", "COL", "ECU", "FLK", "GUF", "GUY", "PRY", "PER", "SGS", "SUR", "URY", "VEN", "BMU", "CAN", "GRL", "SPM", "USA", "ATA", "KAZ", "KGZ", "TJK", "TKM", "UZB", "CHN", "HKG", "MAC", "TWN", "PRK", "JPN", "MNG", "KOR", "BRN", "KHM", "IDN", "LAO", "MYS", "MMR", "PHL", "SGP", "THA", "TLS", "VNM", "AFG", "BGD", "BTN", "IND", "IRN", "MDV", "NPL", "PAK", "LKA", "ARM", "AZE", "BHR", "CYP", "GEO", "IRQ", "ISR", "JOR", "KWT", "LBN", "OMN", "QAT", "SAU", "PSE", "SYR", "TUR", "ARE", "YEM", "BLR", "BGR", "CZE", "HUN", "POL", "MDA", "ROU", "RUS", "SVK", "UKR", "ALA", "GGY", "JEY", "DNK", "EST", "FRO", "FIN", "ISL", "IRL", "IMN", "LVA", "LTU", "NOR", "SJM", "SWE", "GBR", "ALB", "AND", "BIH", "HRV", "GIB", "GRC", "VAT", "ITA", "MLT", "MNE", "PRT", "SMR", "SRB", "SVN", "ESP", "MKD", "AUT", "BEL", "FRA", "DEU", "LIE", "LUX", "MCO", "NLD", "CHE", "AUS", "CXR", "CCK", "HMD", "NZL", "NFK", "FJI", "NCL", "PNG", "SLB", "VUT", "GUM", "KIR", "MHL", "FSM", "NRU", "MNP", "PLW", "UMI", "ASM", "COK", "PYF", "NIU", "PCN", "WSM", "TKL", "TON", "TUV", "WLF", "NN" ] }, "salida": { "$ref": "#/components/schemas/LocalRemisionDTO" }, "entregas": { "type": "array", "items": { "$ref": "#/components/schemas/LocalRemisionDTO" }, "maxItems": 99, "minItems": 0 }, "vehiculos": { "type": "array", "items": { "$ref": "#/components/schemas/VehiculoRemisionDTO" }, "maxItems": 4, "minItems": 0 }, "transportista": { "$ref": "#/components/schemas/TransportistaRemisionDTO" } }, "required": [ "modalidad", "responsableFlete" ] }, "TransporteRemisionDTO": { "type": "object", "properties": { "tipoTransporte": { "type": "string", "enum": [ "PROPIO", "TERCERO" ] }, "modalidad": { "type": "string", "enum": [ "TERRESTRE", "FLUVIAL", "AEREO", "MULTIMODAL" ] }, "responsableFlete": { "type": "string", "enum": [ "EMISOR_FACTURA_ELECTRONICA", "RECEPTOR_FACTURA_ELECTRONICA", "TERCERO", "AGENTE_INTERMEDIARIO", "TRANSPORTE_PROPIO" ] }, "incoterm": { "type": "string", "enum": [ "CFR", "CIF", "CIP", "CPT", "DAP", "DAT", "DDP", "EXW", "FAS", "FCA", "FOB" ] }, "numeroManifiesto": { "type": "string", "maxLength": 15, "minLength": 1, "pattern": "(?s).*\\S.*" }, "numeroDespachoImportacion": { "type": "string", "maxLength": 16, "minLength": 16, "pattern": "(?s).*\\S.*" }, "fechaInicioTraslado": { "type": "string", "format": "date" }, "fechaFinTraslado": { "type": "string", "format": "date" }, "paisDestino": { "type": "string", "enum": [ "DZA", "EGY", "LBY", "MAR", "SDN", "TUN", "ESH", "IOT", "BDI", "COM", "DJI", "ERI", "ETH", "ATF", "KEN", "MDG", "MWI", "MUS", "MYT", "MOZ", "REU", "RWA", "SYC", "SOM", "SSD", "UGA", "TZA", "ZMB", "ZWE", "AGO", "CMR", "CAF", "TCD", "COG", "COD", "GNQ", "GAB", "STP", "BWA", "LSO", "NAM", "ZAF", "SWZ", "BEN", "BFA", "CPV", "CIV", "GMB", "GHA", "GIN", "GNB", "LBR", "MLI", "MRT", "NER", "NGA", "SHN", "SEN", "SLE", "TGO", "AIA", "ATG", "ABW", "BHS", "BRB", "BES", "VGB", "CYM", "CUB", "CUW", "DMA", "DOM", "GRD", "GLP", "HTI", "JAM", "MTQ", "MSR", "PRI", "BLM", "KNA", "LCA", "MAF", "VCT", "SXM", "TTO", "TCA", "VIR", "BLZ", "CRI", "SLV", "GTM", "HND", "MEX", "NIC", "PAN", "ARG", "BOL", "BRA", "CHL", "COL", "ECU", "FLK", "GUF", "GUY", "PRY", "PER", "SGS", "SUR", "URY", "VEN", "BMU", "CAN", "GRL", "SPM", "USA", "ATA", "KAZ", "KGZ", "TJK", "TKM", "UZB", "CHN", "HKG", "MAC", "TWN", "PRK", "JPN", "MNG", "KOR", "BRN", "KHM", "IDN", "LAO", "MYS", "MMR", "PHL", "SGP", "THA", "TLS", "VNM", "AFG", "BGD", "BTN", "IND", "IRN", "MDV", "NPL", "PAK", "LKA", "ARM", "AZE", "BHR", "CYP", "GEO", "IRQ", "ISR", "JOR", "KWT", "LBN", "OMN", "QAT", "SAU", "PSE", "SYR", "TUR", "ARE", "YEM", "BLR", "BGR", "CZE", "HUN", "POL", "MDA", "ROU", "RUS", "SVK", "UKR", "ALA", "GGY", "JEY", "DNK", "EST", "FRO", "FIN", "ISL", "IRL", "IMN", "LVA", "LTU", "NOR", "SJM", "SWE", "GBR", "ALB", "AND", "BIH", "HRV", "GIB", "GRC", "VAT", "ITA", "MLT", "MNE", "PRT", "SMR", "SRB", "SVN", "ESP", "MKD", "AUT", "BEL", "FRA", "DEU", "LIE", "LUX", "MCO", "NLD", "CHE", "AUS", "CXR", "CCK", "HMD", "NZL", "NFK", "FJI", "NCL", "PNG", "SLB", "VUT", "GUM", "KIR", "MHL", "FSM", "NRU", "MNP", "PLW", "UMI", "ASM", "COK", "PYF", "NIU", "PCN", "WSM", "TKL", "TON", "TUV", "WLF", "NN" ] }, "salida": { "$ref": "#/components/schemas/LocalRemisionDTO" }, "entregas": { "type": "array", "items": { "$ref": "#/components/schemas/LocalRemisionDTO" }, "maxItems": 99, "minItems": 1 }, "vehiculos": { "type": "array", "items": { "$ref": "#/components/schemas/VehiculoRemisionDTO" }, "maxItems": 4, "minItems": 1 }, "transportista": { "$ref": "#/components/schemas/TransportistaRemisionDTO" } }, "required": [ "entregas", "fechaFinTraslado", "fechaInicioTraslado", "modalidad", "responsableFlete", "salida", "tipoTransporte", "transportista", "vehiculos" ] }, "TransportistaRemisionDTO": { "type": "object", "properties": { "naturaleza": { "type": "string", "enum": [ "CONTRIBUYENTE", "NO_CONTRIBUYENTE" ] }, "nombreRazonSocial": { "type": "string", "maxLength": 60, "minLength": 4 }, "ruc": { "type": "string", "pattern": "\\d{3,8}" }, "digitoVerificador": { "type": "string", "pattern": "\\d" }, "tipoDocumento": { "type": "string", "enum": [ "CEDULA_PARAGUAYA", "PASAPORTE", "CEDULA_EXTRANJERA", "CARNET_DE_RESIDENCIA" ] }, "numeroDocumento": { "type": "string", "maxLength": 20, "minLength": 1, "pattern": "(?s).*\\S.*" }, "nacionalidad": { "type": "string", "enum": [ "DZA", "EGY", "LBY", "MAR", "SDN", "TUN", "ESH", "IOT", "BDI", "COM", "DJI", "ERI", "ETH", "ATF", "KEN", "MDG", "MWI", "MUS", "MYT", "MOZ", "REU", "RWA", "SYC", "SOM", "SSD", "UGA", "TZA", "ZMB", "ZWE", "AGO", "CMR", "CAF", "TCD", "COG", "COD", "GNQ", "GAB", "STP", "BWA", "LSO", "NAM", "ZAF", "SWZ", "BEN", "BFA", "CPV", "CIV", "GMB", "GHA", "GIN", "GNB", "LBR", "MLI", "MRT", "NER", "NGA", "SHN", "SEN", "SLE", "TGO", "AIA", "ATG", "ABW", "BHS", "BRB", "BES", "VGB", "CYM", "CUB", "CUW", "DMA", "DOM", "GRD", "GLP", "HTI", "JAM", "MTQ", "MSR", "PRI", "BLM", "KNA", "LCA", "MAF", "VCT", "SXM", "TTO", "TCA", "VIR", "BLZ", "CRI", "SLV", "GTM", "HND", "MEX", "NIC", "PAN", "ARG", "BOL", "BRA", "CHL", "COL", "ECU", "FLK", "GUF", "GUY", "PRY", "PER", "SGS", "SUR", "URY", "VEN", "BMU", "CAN", "GRL", "SPM", "USA", "ATA", "KAZ", "KGZ", "TJK", "TKM", "UZB", "CHN", "HKG", "MAC", "TWN", "PRK", "JPN", "MNG", "KOR", "BRN", "KHM", "IDN", "LAO", "MYS", "MMR", "PHL", "SGP", "THA", "TLS", "VNM", "AFG", "BGD", "BTN", "IND", "IRN", "MDV", "NPL", "PAK", "LKA", "ARM", "AZE", "BHR", "CYP", "GEO", "IRQ", "ISR", "JOR", "KWT", "LBN", "OMN", "QAT", "SAU", "PSE", "SYR", "TUR", "ARE", "YEM", "BLR", "BGR", "CZE", "HUN", "POL", "MDA", "ROU", "RUS", "SVK", "UKR", "ALA", "GGY", "JEY", "DNK", "EST", "FRO", "FIN", "ISL", "IRL", "IMN", "LVA", "LTU", "NOR", "SJM", "SWE", "GBR", "ALB", "AND", "BIH", "HRV", "GIB", "GRC", "VAT", "ITA", "MLT", "MNE", "PRT", "SMR", "SRB", "SVN", "ESP", "MKD", "AUT", "BEL", "FRA", "DEU", "LIE", "LUX", "MCO", "NLD", "CHE", "AUS", "CXR", "CCK", "HMD", "NZL", "NFK", "FJI", "NCL", "PNG", "SLB", "VUT", "GUM", "KIR", "MHL", "FSM", "NRU", "MNP", "PLW", "UMI", "ASM", "COK", "PYF", "NIU", "PCN", "WSM", "TKL", "TON", "TUV", "WLF", "NN" ] }, "domicilioFiscal": { "type": "string", "maxLength": 150, "minLength": 0 }, "numeroDocumentoConductor": { "type": "string", "maxLength": 20, "minLength": 0 }, "nombreConductor": { "type": "string", "maxLength": 60, "minLength": 4 }, "direccionConductor": { "type": "string", "maxLength": 255, "minLength": 0 }, "nombreAgente": { "type": "string", "maxLength": 60, "minLength": 4, "pattern": "(?s).*\\S.*" }, "rucAgente": { "type": "string", "pattern": "\\d{3,8}" }, "digitoVerificadorAgente": { "type": "string", "pattern": "\\d" }, "direccionAgente": { "type": "string", "maxLength": 255, "minLength": 1, "pattern": "(?s).*\\S.*" } }, "required": [ "direccionConductor", "domicilioFiscal", "naturaleza", "nombreConductor", "nombreRazonSocial", "numeroDocumentoConductor" ] }, "VehiculoNuevoDTO": { "type": "object", "description": "Datos del vehículo nuevo vendido en el ítem (E770)", "properties": { "tipoOperacion": { "type": "string", "description": "Tipo de operación de venta (E771)", "enum": [ "VENTA_A_REPRESENTANTE", "VENTA_AL_CONSUMIDOR_FINAL", "VENTA_AL_GOBIERNO", "VENTA_A_FLOTA_DE_VEHICULOS" ], "example": "VENTA_AL_CONSUMIDOR_FINAL" }, "chasis": { "type": "string", "description": "Chasis (E773)", "example": "9BWZZZ377VT004251", "pattern": "[0-9A-Za-z]{17}" }, "color": { "type": "string", "description": "Color (E774)", "maxLength": 10, "minLength": 1 }, "potencia": { "type": "integer", "format": "int32", "description": "Potencia del motor en CV (E775)", "maximum": 9999, "minimum": 1 }, "capacidadMotor": { "type": "integer", "format": "int32", "description": "Capacidad del motor en cc (E776)", "maximum": 9999, "minimum": 1 }, "pesoNeto": { "type": "number", "description": "Peso neto en toneladas (E777)", "minimum": 0 }, "pesoBruto": { "type": "number", "description": "Peso bruto en toneladas (E778)", "minimum": 0 }, "tipoCombustible": { "type": "string", "description": "Tipo de combustible (E779)", "enum": [ "GASOLINA", "DIESEL", "ETANOL", "GNV", "FLEX", "OTRO" ], "example": "DIESEL" }, "descripcionCombustible": { "type": "string", "description": "Combustible propio (E780). Obligatorio y exclusivo de `tipoCombustible = OTRO`", "maxLength": 20, "minLength": 3 }, "numeroMotor": { "type": "string", "description": "Número de motor (E781)", "maxLength": 21, "minLength": 1 }, "capacidadTraccion": { "type": "number", "description": "Capacidad máxima de tracción en toneladas (E782)", "minimum": 0 }, "anioFabricacion": { "type": "integer", "format": "int32", "description": "Año de fabricación (E783)", "example": 2026, "maximum": 9999, "minimum": 1000 }, "tipoVehiculo": { "type": "string", "description": "Tipo de vehículo (E784)", "example": "Camioneta", "maxLength": 10, "minLength": 4 }, "capacidadPasajeros": { "type": "integer", "format": "int32", "description": "Capacidad máxima de pasajeros sentados (E785)", "maximum": 999, "minimum": 1 } } }, "VehiculoRemisionDTO": { "type": "object", "properties": { "tipoVehiculo": { "type": "string", "maxLength": 10, "minLength": 4 }, "marca": { "type": "string", "maxLength": 10, "minLength": 0 }, "tipoIdentificacion": { "type": "integer", "format": "int32", "maximum": 2, "minimum": 1 }, "numeroIdentificacion": { "type": "string", "maxLength": 20, "minLength": 1, "pattern": "(?s).*\\S.*" }, "matricula": { "type": "string", "maxLength": 7, "minLength": 6, "pattern": "(?s).*\\S.*" }, "datosAdicionales": { "type": "string", "maxLength": 20, "minLength": 1, "pattern": "(?s).*\\S.*" }, "numeroVuelo": { "type": "string", "maxLength": 6, "minLength": 6, "pattern": "(?s).*\\S.*" } }, "required": [ "marca", "tipoIdentificacion", "tipoVehiculo" ] }, "VendedorAutofacturaDTO": { "type": "object", "additionalProperties": false, "description": "Vendedor de la compra documentada por la autofactura (grupo E4)", "properties": { "naturaleza": { "type": "string", "description": "Naturaleza del vendedor (E301)", "enum": [ "NO_CONTRIBUYENTE", "EXTRANJERO" ], "example": "NO_CONTRIBUYENTE" }, "tipoDocumento": { "type": "string", "description": "Tipo de documento de identidad del vendedor (E304)", "enum": [ "CEDULA_PARAGUAYA", "PASAPORTE", "CEDULA_EXTRANJERA", "CARNET_DE_RESIDENCIA" ], "example": "CEDULA_PARAGUAYA" }, "numeroDocumento": { "type": "string", "description": "Número de documento de identidad del vendedor (E306)", "example": "1234567", "minLength": 1, "pattern": "[0-9]{5,12}" }, "nombre": { "type": "string", "description": "Nombre y apellido del vendedor (E307)", "example": "María González", "maxLength": 60, "minLength": 4 }, "domicilio": { "$ref": "#/components/schemas/DomicilioAutofacturaDTO", "description": "Dirección y ubicación del vendedor (E308, E310–E315)" }, "numeroCasa": { "type": "integer", "format": "int32", "description": "Número de casa del vendedor; informar cero cuando no tiene numeración (E309)", "example": 0, "maximum": 999999, "minimum": 0 } }, "required": [ "domicilio", "naturaleza", "nombre", "numeroCasa", "numeroDocumento", "tipoDocumento" ] }, "DocumentoElectronicoEmisionResponseDTO": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid", "description": "Identificador público del documento", "example": "550e8400-e29b-41d4-a716-446655440000" }, "deId": { "type": "integer", "format": "int64", "description": "PK numérica del documento", "example": 4821 }, "cdc": { "type": "string", "description": "Código de Control del Documento Electrónico, 44 dígitos", "example": "01800123451001001000000122026042710000000006" }, "estado": { "type": "string", "description": "Siempre `PENDIENTE` en la emisión. Los estados terminales se consultan con `statusUrl`", "example": "PENDIENTE" }, "ambiente": { "type": "string", "description": "Ambiente inmutable en el que se emitió el documento", "example": "PROD" }, "tipoDocumento": { "type": "string", "description": "Eco del tipo emitido", "example": "FACTURA_ELECTRONICA" }, "numeroDocumento": { "type": "integer", "format": "int64", "description": "Correlativo asignado dentro del punto de expedición", "example": 122 }, "numeroFormateado": { "type": "string", "description": "Número en formato establecimiento-puntoExpedición-correlativo", "example": "001-001-0000122" }, "fechaCreacion": { "type": "string", "format": "date-time", "description": "Momento en que Sifende registró el documento", "example": "2026-04-27T10:30:00" }, "qrUrl": { "type": "string", "description": "URL del QR oficial de SIFEN, para embeber en tu UI o en el KuDE" }, "statusUrl": { "type": "string", "description": "URL absoluta para hacer polling del estado. También viaja en el header `Location`" }, "kudeUrl": { "type": "string", "description": "URL absoluta del KuDE en PDF, disponible una vez aprobado el documento" }, "itiDe": { "type": "integer", "format": "int32" } } }, "EventoNominacionRequest": { "type": "object", "description": "Datos necesarios para nominar el receptor de una factura electrónica innominada", "properties": { "receptor": { "$ref": "#/components/schemas/ReceptorNominadoRequest" }, "motivo": { "type": "string", "maxLength": 500, "minLength": 5 } }, "required": [ "motivo", "receptor" ] }, "ReceptorNominadoRequest": { "type": "object", "description": "Receptor que reemplazará al receptor innominado de la factura electrónica", "properties": { "naturaleza": { "type": "string", "enum": [ "CONTRIBUYENTE", "NO_CONTRIBUYENTE" ] }, "tipoOperacion": { "type": "string", "enum": [ "B2B", "B2C", "B2G", "B2F" ] }, "pais": { "type": "string", "enum": [ "DZA", "EGY", "LBY", "MAR", "SDN", "TUN", "ESH", "IOT", "BDI", "COM", "DJI", "ERI", "ETH", "ATF", "KEN", "MDG", "MWI", "MUS", "MYT", "MOZ", "REU", "RWA", "SYC", "SOM", "SSD", "UGA", "TZA", "ZMB", "ZWE", "AGO", "CMR", "CAF", "TCD", "COG", "COD", "GNQ", "GAB", "STP", "BWA", "LSO", "NAM", "ZAF", "SWZ", "BEN", "BFA", "CPV", "CIV", "GMB", "GHA", "GIN", "GNB", "LBR", "MLI", "MRT", "NER", "NGA", "SHN", "SEN", "SLE", "TGO", "AIA", "ATG", "ABW", "BHS", "BRB", "BES", "VGB", "CYM", "CUB", "CUW", "DMA", "DOM", "GRD", "GLP", "HTI", "JAM", "MTQ", "MSR", "PRI", "BLM", "KNA", "LCA", "MAF", "VCT", "SXM", "TTO", "TCA", "VIR", "BLZ", "CRI", "SLV", "GTM", "HND", "MEX", "NIC", "PAN", "ARG", "BOL", "BRA", "CHL", "COL", "ECU", "FLK", "GUF", "GUY", "PRY", "PER", "SGS", "SUR", "URY", "VEN", "BMU", "CAN", "GRL", "SPM", "USA", "ATA", "KAZ", "KGZ", "TJK", "TKM", "UZB", "CHN", "HKG", "MAC", "TWN", "PRK", "JPN", "MNG", "KOR", "BRN", "KHM", "IDN", "LAO", "MYS", "MMR", "PHL", "SGP", "THA", "TLS", "VNM", "AFG", "BGD", "BTN", "IND", "IRN", "MDV", "NPL", "PAK", "LKA", "ARM", "AZE", "BHR", "CYP", "GEO", "IRQ", "ISR", "JOR", "KWT", "LBN", "OMN", "QAT", "SAU", "PSE", "SYR", "TUR", "ARE", "YEM", "BLR", "BGR", "CZE", "HUN", "POL", "MDA", "ROU", "RUS", "SVK", "UKR", "ALA", "GGY", "JEY", "DNK", "EST", "FRO", "FIN", "ISL", "IRL", "IMN", "LVA", "LTU", "NOR", "SJM", "SWE", "GBR", "ALB", "AND", "BIH", "HRV", "GIB", "GRC", "VAT", "ITA", "MLT", "MNE", "PRT", "SMR", "SRB", "SVN", "ESP", "MKD", "AUT", "BEL", "FRA", "DEU", "LIE", "LUX", "MCO", "NLD", "CHE", "AUS", "CXR", "CCK", "HMD", "NZL", "NFK", "FJI", "NCL", "PNG", "SLB", "VUT", "GUM", "KIR", "MHL", "FSM", "NRU", "MNP", "PLW", "UMI", "ASM", "COK", "PYF", "NIU", "PCN", "WSM", "TKL", "TON", "TUV", "WLF", "NN" ] }, "tipoContribuyente": { "type": "string", "enum": [ "PERSONA_FISICA", "PERSONA_JURIDICA" ] }, "ruc": { "type": "string", "pattern": "\\d{3,8}" }, "digitoVerificador": { "type": "string", "pattern": "\\d" }, "tipoDocumento": { "type": "string", "enum": [ "CEDULA_PARAGUAYA", "PASAPORTE", "CEDULA_EXTRANJERA", "CARNET_DE_RESIDENCIA", "INNOMINADO", "TARJETA_DIPLOMATICA", "OTRO" ] }, "descripcionTipoDocumento": { "type": "string", "maxLength": 41, "minLength": 9 }, "numeroDocumento": { "type": "string", "pattern": "[0-9A-Za-z-]{1,20}" }, "nombreRazonSocial": { "type": "string", "maxLength": 255, "minLength": 4 }, "nombreFantasia": { "type": "string", "maxLength": 255, "minLength": 4 }, "direccion": { "type": "string", "maxLength": 255, "minLength": 0 }, "numeroCasa": { "type": "integer", "format": "int32", "maximum": 999999, "minimum": 0 }, "departamento": { "type": "string", "enum": [ "CAPITAL", "CONCEPCION", "SAN_PEDRO", "CORDILLERA", "GUAIRA", "CAAGUAZU", "CAAZAPA", "ITAPUA", "MISIONES", "PARAGUARI", "ALTO_PARANA", "CENTRAL", "NEEMBUCU", "AMAMBAY", "PTE_HAYES", "BOQUERON", "ALTO_PARAGUAY", "CANINDEYU", "CHACO", "NUEVA_ASUNCION" ] }, "codigoDistrito": { "type": "integer", "format": "int32", "minimum": 1 }, "codigoCiudad": { "type": "integer", "format": "int32", "minimum": 1 }, "telefono": { "type": "string", "maxLength": 15, "minLength": 6 }, "celular": { "type": "string", "maxLength": 20, "minLength": 10 }, "email": { "type": "string", "format": "email" }, "codigoCliente": { "type": "string", "maxLength": 15, "minLength": 3 } }, "required": [ "naturaleza", "nombreRazonSocial", "pais", "tipoOperacion" ] }, "EventoSifenDTO": { "type": "object", "properties": { "eventoSifenId": { "type": "integer", "format": "int64" }, "documentoElectronicoId": { "type": "integer", "format": "int64" }, "contribuyenteId": { "type": "integer", "format": "int64" }, "ambiente": { "type": "string" }, "tipoEvento": { "type": "string" }, "estadoEvento": { "type": "string" }, "cdc": { "type": "string" }, "motivo": { "type": "string" }, "protocoloAutorizacion": { "type": "string" }, "codigoRespuesta": { "type": "string" }, "mensajeRespuesta": { "type": "string" }, "fechaCreacion": { "type": "string", "format": "date-time" }, "fechaProcesamiento": { "type": "string", "format": "date-time" }, "numeroTimbrado": { "type": "integer", "format": "int32" }, "establecimiento": { "type": "string" }, "puntoExpedicion": { "type": "string" }, "numeroInicio": { "type": "string" }, "numeroFin": { "type": "string" }, "tipoDocumento": { "type": "integer", "format": "int32" }, "serieNumero": { "type": "string" } } }, "CancelacionRequest": { "type": "object", "properties": { "motivo": { "type": "string", "maxLength": 500, "minLength": 5 } }, "required": [ "motivo" ] }, "EventoInutilizacionRequest": { "type": "object", "properties": { "numeroTimbrado": { "type": "integer", "format": "int32" }, "establecimiento": { "type": "string", "maxLength": 3, "minLength": 3 }, "puntoExpedicion": { "type": "string", "maxLength": 3, "minLength": 3 }, "numeroInicio": { "type": "string", "maxLength": 7, "minLength": 1 }, "numeroFin": { "type": "string", "maxLength": 7, "minLength": 1 }, "tipoDocumento": { "type": "integer", "format": "int32" }, "motivo": { "type": "string", "maxLength": 500, "minLength": 5 }, "serie": { "type": "string", "maxLength": 2, "minLength": 0 } }, "required": [ "establecimiento", "motivo", "numeroFin", "numeroInicio", "numeroTimbrado", "puntoExpedicion", "tipoDocumento" ] }, "EnumValueDTO": { "type": "object", "properties": { "name": { "type": "string" }, "label": { "type": "string" }, "val": { "type": "integer", "format": "int32" }, "extra": { "type": "string" } } }, "CodigoNombre": { "type": "object", "properties": { "codigo": { "type": "integer", "format": "int32", "description": "Código SIFEN (cDepRec / cDisRec / cCiuRec).", "example": 1 }, "nombre": { "type": "string", "example": "CAPITAL" } } }, "Domicilio": { "type": "object", "properties": { "departamento": { "$ref": "#/components/schemas/CodigoNombre" }, "distrito": { "$ref": "#/components/schemas/CodigoNombre" }, "localidad": { "$ref": "#/components/schemas/CodigoNombre" }, "barrio": { "type": "string" }, "direccion": { "type": "string" }, "numeroPuerta": { "type": "string" }, "referencias": { "type": "string" } } }, "Padron": { "type": "object", "description": "Datos de un contribuyente o ciudadano según el padrón de la SET. Los nombres de campo y las enumeraciones son los del receptor de un documento electrónico.", "properties": { "numeroDocumento": { "type": "string", "description": "RUC base o número de cédula, normalizado: sólo dígitos, sin DV.", "example": "80002201" }, "tipoContribuyente": { "type": "string", "description": "CONTRIBUYENTE si el documento está inscripto como tal; NO_CONTRIBUYENTE si sólo figura como ciudadano.", "enum": [ "CONTRIBUYENTE", "NO_CONTRIBUYENTE" ], "example": "CONTRIBUYENTE" }, "tipoDocumento": { "type": "string", "description": "Tipo de documento de identidad; sólo para un no contribuyente.", "enum": [ "CEDULA_PARAGUAYA", "PASAPORTE", "CEDULA_EXTRANJERA", "CARNET_DE_RESIDENCIA", "INNOMINADO", "TARJETA_DIPLOMATICA", "OTRO" ], "example": "CEDULA_PARAGUAYA" }, "tipoContribuyenteReceptor": { "type": "string", "description": "Persona física o jurídica (D207); null para un no contribuyente.", "enum": [ "PERSONA_FISICA", "PERSONA_JURIDICA" ], "example": "PERSONA_JURIDICA" }, "digitoVerificador": { "type": "string", "description": "Dígito verificador del RUC.", "example": "7" }, "nombreRazonSocial": { "type": "string", "description": "Razón social o nombre completo.", "example": "EMPRESA S.A" }, "nombreComercial": { "type": "string" }, "email": { "type": "string", "description": "Correo electronico" }, "estado": { "type": "string", "description": "Estado del contribuyente tal como lo informa la SET.", "example": "ACTIVO" }, "estadoRuc": { "type": "string", "description": "Código SET del estado, el mismo que usa el contribuyente en Sifende.", "enum": [ "ACT", "SUS", "SAD", "BLQ", "CAN", "CDE" ], "example": "ACT" }, "tipoSociedad": { "$ref": "#/components/schemas/TipoSociedad" }, "esPersonaJuridica": { "type": "boolean" }, "esEntidadPublica": { "type": "boolean" }, "exportador": { "type": "boolean" }, "domicilio": { "$ref": "#/components/schemas/Domicilio", "description": "Domicilio fiscal con los códigos geográficos de SIFEN, si el padrón lo tiene." }, "consultadoEn": { "type": "string", "format": "date-time" } } }, "TipoSociedad": { "type": "object", "properties": { "codigo": { "type": "string", "example": "SOCIEDAD_ANONIMA" }, "descripcion": { "type": "string", "example": "SOCIEDAD ANONIMA" } } }, "ApiResponsePadron": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Padron" }, "timestamp": { "type": "string", "format": "date-time" }, "errors": { "type": "array", "items": { "type": "string" } } } }, "ApiResponseListCiudadDTO": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/CiudadDTO" } }, "timestamp": { "type": "string", "format": "date-time" }, "errors": { "type": "array", "items": { "type": "string" } } } }, "CiudadDTO": { "type": "object", "properties": { "ciudadId": { "type": "integer", "format": "int32" }, "distritoId": { "type": "integer", "format": "int32" }, "codigo": { "type": "integer", "format": "int32" }, "nombre": { "type": "string" } } }, "ApiResponseListDepartamentoDTO": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/DepartamentoDTO" } }, "timestamp": { "type": "string", "format": "date-time" }, "errors": { "type": "array", "items": { "type": "string" } } } }, "DepartamentoDTO": { "type": "object", "properties": { "departamentoId": { "type": "integer", "format": "int32" }, "codigo": { "type": "integer", "format": "int32" }, "nombre": { "type": "string" } } }, "ApiResponseListDistritoDTO": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/DistritoDTO" } }, "timestamp": { "type": "string", "format": "date-time" }, "errors": { "type": "array", "items": { "type": "string" } } } }, "DistritoDTO": { "type": "object", "properties": { "distritoId": { "type": "integer", "format": "int32" }, "departamentoId": { "type": "integer", "format": "int32" }, "codigo": { "type": "integer", "format": "int32" }, "nombre": { "type": "string" } } }, "DocumentoElectronicoStatusDTO": { "type": "object", "properties": { "cdc": { "type": "string" }, "estado": { "type": "string" }, "ambiente": { "type": "string" }, "numeroDocumento": { "type": "integer", "format": "int64" }, "fechaCreacion": { "type": "string", "format": "date-time" }, "protocoloAutorizacion": { "type": "string" }, "mensajeRechazo": { "type": "string" }, "itiDe": { "type": "integer", "format": "int32" } } }, "PlanConsumoDTO": { "type": "object", "properties": { "codigoPlan": { "type": "string" }, "nombrePlan": { "type": "string" }, "inicioPeriodo": { "type": "string", "format": "date-time" }, "finPeriodo": { "type": "string", "format": "date-time" }, "documentosIncluidos": { "type": "integer", "format": "int64" }, "consumoConfirmado": { "type": "integer", "format": "int64" }, "reservasActivas": { "type": "integer", "format": "int64" }, "documentosDisponibles": { "type": "integer", "format": "int64" }, "permiteAdicionales": { "type": "boolean" }, "precioDocumentoAdicionalPyg": { "type": [ "integer", "null" ], "format": "int64" }, "adicionalesFacturables": { "type": "integer", "format": "int64" }, "costoEstimadoPyg": { "type": "integer", "format": "int64" } }, "required": [ "adicionalesFacturables", "codigoPlan", "consumoConfirmado", "costoEstimadoPyg", "documentosDisponibles", "documentosIncluidos", "finPeriodo", "inicioPeriodo", "nombrePlan", "permiteAdicionales", "precioDocumentoAdicionalPyg", "reservasActivas" ] }, "PageDTOEventoSifenDTO": { "type": "object", "properties": { "content": { "type": "array", "items": { "$ref": "#/components/schemas/EventoSifenDTO" } }, "page": { "type": "integer", "format": "int32" }, "size": { "type": "integer", "format": "int32" }, "totalElements": { "type": "integer", "format": "int64" }, "totalPages": { "type": "integer", "format": "int32" } } }, "ActividadEconomica": { "type": "object", "properties": { "codigo": { "type": "string" }, "descripcion": { "type": "string" } }, "required": [ "codigo", "descripcion" ] }, "ContribuyenteIntegracionDTO": { "type": "object", "properties": { "ruc": { "type": "string" }, "digitoVerificador": { "type": "string" }, "razonSocial": { "type": "string" }, "nombreFantasia": { "type": [ "string", "null" ] }, "tipoContribuyente": { "type": "string", "enum": [ "PERSONA_FISICA", "PERSONA_JURIDICA" ] }, "ambiente": { "type": "string", "enum": [ "DEV", "PROD", "SANDBOX" ] }, "actividadesEconomicas": { "type": "array", "items": { "$ref": "#/components/schemas/ActividadEconomica" } }, "direccion": { "type": [ "string", "null" ] }, "numeroCasa": { "type": [ "integer", "null" ], "format": "int32" }, "departamento": { "anyOf": [ { "$ref": "#/components/schemas/Ubicacion" }, { "type": "null" } ] }, "distrito": { "anyOf": [ { "$ref": "#/components/schemas/Ubicacion" }, { "type": "null" } ] }, "ciudad": { "anyOf": [ { "$ref": "#/components/schemas/Ubicacion" }, { "type": "null" } ] }, "telefono": { "type": "string" }, "email": { "type": "string" }, "timbrado": { "anyOf": [ { "$ref": "#/components/schemas/Timbrado" }, { "type": "null" } ] }, "establecimientos": { "type": "array", "items": { "$ref": "#/components/schemas/Establecimiento" } }, "logoUrl": { "type": [ "string", "null" ] }, "estadoConfiguracion": { "$ref": "#/components/schemas/EstadoConfiguracion" } }, "required": [ "actividadesEconomicas", "ambiente", "ciudad", "departamento", "digitoVerificador", "direccion", "distrito", "email", "establecimientos", "estadoConfiguracion", "logoUrl", "nombreFantasia", "numeroCasa", "razonSocial", "ruc", "telefono", "timbrado", "tipoContribuyente" ] }, "Establecimiento": { "type": "object", "properties": { "numeroEstablecimiento": { "type": "integer", "format": "int32" }, "nombreSucursal": { "type": [ "string", "null" ] }, "activo": { "type": "boolean" }, "puntosExpedicion": { "type": "array", "items": { "$ref": "#/components/schemas/PuntoExpedicion" } } }, "required": [ "activo", "nombreSucursal", "numeroEstablecimiento", "puntosExpedicion" ] }, "EstadoConfiguracion": { "type": "object", "properties": { "certificadoConfigurado": { "type": "boolean" }, "certificadoVence": { "type": [ "string", "null" ], "format": "date" }, "certificadoVigente": { "type": "boolean" }, "cscConfigurado": { "type": "boolean" }, "timbradoVigente": { "type": "boolean" }, "direccionConfigurada": { "type": "boolean" }, "actividadEconomicaConfigurada": { "type": "boolean" }, "listoParaEmitir": { "type": "boolean" } }, "required": [ "actividadEconomicaConfigurada", "certificadoConfigurado", "certificadoVence", "certificadoVigente", "cscConfigurado", "direccionConfigurada", "listoParaEmitir", "timbradoVigente" ] }, "PuntoExpedicion": { "type": "object", "properties": { "puntoExpedicion": { "type": "integer", "format": "int32" }, "activo": { "type": "boolean" } }, "required": [ "activo", "puntoExpedicion" ] }, "Timbrado": { "type": "object", "properties": { "numero": { "type": "integer", "format": "int32" }, "fechaInicioVigencia": { "type": "string", "format": "date" } }, "required": [ "fechaInicioVigencia", "numero" ] }, "Ubicacion": { "type": "object", "properties": { "codigo": { "type": "integer", "format": "int32" }, "descripcion": { "type": "string" } }, "required": [ "codigo", "descripcion" ] }, "ProblemDetail": { "type": "object", "description": "Error en formato RFC 9457. Se sirve como `application/problem+json`.", "properties": { "type": { "type": "string", "description": "URI del tipo de error. Apunta a la página de la documentación que lo explica", "example": "https://sifende.com.py/docs/solucion-problemas/validation-error" }, "title": { "type": "string", "description": "Resumen legible del tipo de error", "example": "Error de validación" }, "status": { "type": "integer", "description": "Código HTTP", "example": 400 }, "detail": { "type": "string", "description": "Descripción del caso concreto", "example": "La solicitud contiene 1 error(es) de validación" }, "instance": { "type": "string", "description": "Ruta que produjo el error", "example": "/api/v1/documento-electronico" }, "traceId": { "type": "string", "description": "Identificador de la petición. Es el dato que hay que pasarle a soporte", "example": "8f1c2b3a4d5e6f70" }, "errores": { "type": "object", "additionalProperties": { "type": "string" }, "description": "Sólo en errores de validación: un mensaje por campo, indexado por el nombre del campo tal como se envió" }, "campo": { "type": "string", "description": "Campo del request que causó el rechazo, incluido un header cuando corresponda", "example": "receptor.tipoContribuyenteReceptor" }, "valorRecibido": { "type": "string", "description": "Valor que llegó en el request", "example": "RUC" }, "valoresAceptados": { "type": "array", "description": "Sólo en errores de enumeración: los valores válidos, con su descripción" } } } }, "responses": { "BadRequest": { "description": "El request no pasó la validación. `errores` trae un mensaje por campo", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetail" }, "examples": { "receptorIncompleto": { "summary": "Receptor contribuyente sin los campos que exige un contribuyente", "value": { "type": "https://sifende.com.py/docs/solucion-problemas/validation-error", "title": "Error de validación", "status": 400, "detail": "La solicitud contiene 2 error(es) de validación", "errores": { "receptor.tipoContribuyenteReceptor": "Tipo de contribuyente receptor es obligatorio para un contribuyente", "receptor.digitoVerificador": "Dígito verificador es obligatorio y debe contener un dígito" }, "traceId": "8f1c2b3a4d5e6f70" } }, "enumInvalido": { "summary": "Valor que no existe en la enumeración. `valoresAceptados` lista los válidos", "value": { "type": "https://sifende.com.py/docs/solucion-problemas/invalid-enum-value", "title": "Valor de enumeración inválido", "status": 400, "detail": "El campo 'receptor.tipoDocumento' recibió 'RUC', que no es un valor permitido. Valores aceptados: [CEDULA_PARAGUAYA, PASAPORTE, CEDULA_EXTRANJERA, CARNET_DE_RESIDENCIA, INNOMINADO, TARJETA_DIPLOMATICA, OTRO]", "campo": "receptor.tipoDocumento", "valorRecibido": "RUC", "valoresAceptados": [ { "codigo": "CEDULA_PARAGUAYA", "descripcion": "Cédula paraguaya" }, { "codigo": "PASAPORTE", "descripcion": "Pasaporte" } ], "traceId": "8f1c2b3a4d5e6f70" } }, "formatoInvalido": { "summary": "Tipo de dato equivocado en un campo", "value": { "type": "https://sifende.com.py/docs/solucion-problemas/invalid-format", "title": "Formato de campo inválido", "status": 400, "detail": "El campo 'items[0].cantidad' recibió un valor de tipo incorrecto: se esperaba un número decimal", "campo": "items[0].cantidad", "tipoEsperado": "número decimal", "traceId": "8f1c2b3a4d5e6f70" } } } } } }, "Unauthorized": { "description": "Falta la API key, está revocada o no corresponde al ambiente. El filtro conserva su error JSON.", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "const": "Invalid or expired API key" } }, "required": [ "error" ] }, "examples": { "apiKeyInvalida": { "value": { "error": "Invalid or expired API key" } } } } } }, "NotFound": { "description": "El recurso no existe, o le falta al contribuyente una precondición de emisión", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetail" }, "examples": { "timbrado": { "summary": "El contribuyente no tiene timbrado vigente cargado", "value": { "type": "https://sifende.com.py/docs/solucion-problemas/timbrado-not-found", "title": "Timbrado no encontrado", "status": 404, "detail": "No hay un timbrado configurado para el contribuyente", "traceId": "8f1c2b3a4d5e6f70" } }, "documento": { "summary": "El CDC no corresponde a un documento del contribuyente", "value": { "type": "https://sifende.com.py/docs/solucion-problemas/documento-electronico-not-found", "title": "Documento electrónico no encontrado", "status": 404, "detail": "No se encontró el documento con CDC 01800123451001001000000122026042710000000006", "traceId": "8f1c2b3a4d5e6f70" } } } } } }, "UnprocessableEntity": { "description": "El request es válido pero el documento no cumple una regla de SIFEN", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetail" }, "examples": { "generacion": { "value": { "type": "https://sifende.com.py/docs/solucion-problemas/documento-electronico-generation-error", "title": "Error al generar el documento electrónico", "status": 422, "detail": "El total del documento no coincide con la suma de los ítems", "traceId": "8f1c2b3a4d5e6f70" } } } } } }, "EmissionUnprocessableEntity": { "description": "El documento incumple una regla de SIFEN o la clave corresponde a otro tipo de operación", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetail" }, "examples": { "generacion": { "value": { "type": "https://sifende.com.py/docs/solucion-problemas/documento-electronico-generation-error", "title": "Error al generar el documento electrónico", "status": 422, "detail": "El total del documento no coincide con la suma de los ítems", "traceId": "8f1c2b3a4d5e6f70" } }, "claveReutilizada": { "summary": "La misma clave fue usada para otro tipo de operación", "value": { "type": "https://sifende.com.py/docs/solucion-problemas/idempotency-key-reused", "title": "Clave de idempotencia reutilizada", "status": 422, "detail": "La clave de idempotencia ya fue usada para otro tipo de operación" } }, "receptorPublico": { "summary": "TuRUC confirmó que el receptor requiere una operación B2G", "value": { "type": "https://sifende.com.py/docs/solucion-problemas/public-recipient-requires-b2g", "title": "El receptor público requiere una operación B2G", "status": 422, "detail": "TuRUC confirmó que el receptor es un organismo o entidad del Estado", "errores": { "receptor.tipoOperacion": "Seleccione B2G para un receptor público" }, "traceId": "8f1c2b3a4d5e6f70" } }, "contratacionPublica": { "summary": "El código de contratación no es anterior a la fecha efectiva", "value": { "type": "https://sifende.com.py/docs/solucion-problemas/public-procurement-data-invalid", "title": "Datos de contratación pública inválidos", "status": 422, "detail": "Los datos de contratación pública contradicen la fecha de emisión", "errores": { "comprasPublicas.fechaEmisionCodigo": "Fecha de emisión del código debe ser anterior a la fecha efectiva del documento" }, "traceId": "8f1c2b3a4d5e6f70" } } } } } }, "DocumentQuotaExceeded": { "description": "El plan no admite más documentos en el período actual; la solicitud no se ejecutó", "content": { "application/problem+json": { "schema": { "allOf": [ { "$ref": "#/components/schemas/ProblemDetail" }, { "type": "object", "properties": { "type": { "const": "https://sifende.com.py/docs/solucion-problemas/document-quota-exceeded" }, "title": { "const": "Cupo mensual de documentos agotado" }, "status": { "const": 403 }, "detail": { "type": "string", "description": "Descripción del cupo agotado para el plan efectivo" }, "codigoPlan": { "type": "string", "description": "Código público del plan efectivo", "example": "GRATIS" }, "nombrePlan": { "type": "string", "description": "Nombre legible del plan efectivo", "example": "Gratis" }, "documentosIncluidos": { "type": "integer", "description": "Documentos incluidos en el período", "example": 100 }, "consumoConfirmado": { "type": "integer", "description": "Documentos confirmados del período", "example": 95 }, "reservasActivas": { "type": "integer", "description": "Documentos en proceso que ocupan capacidad", "example": 5 }, "documentosDisponibles": { "type": "integer", "description": "Capacidad incluida disponible", "example": 0 }, "inicioPeriodo": { "type": "string", "format": "date-time", "description": "Inicio inclusivo del período", "example": "2026-08-10T04:00:00Z" }, "finPeriodo": { "type": "string", "format": "date-time", "description": "Fin exclusivo del período", "example": "2026-09-10T04:00:00Z" }, "accion": { "type": "string", "description": "Acción recomendada antes de volver a emitir" }, "traceId": { "type": "string", "description": "Identificador de la petición. Es el dato que hay que pasarle a soporte" } }, "required": [ "accion", "codigoPlan", "consumoConfirmado", "detail", "documentosDisponibles", "documentosIncluidos", "finPeriodo", "inicioPeriodo", "nombrePlan", "reservasActivas", "status", "title", "traceId", "type" ] } ] }, "examples": { "cupoAgotado": { "summary": "Cupo mensual agotado para un plan sin adicionales", "value": { "type": "https://sifende.com.py/docs/solucion-problemas/document-quota-exceeded", "title": "Cupo mensual de documentos agotado", "status": 403, "detail": "El plan Gratis tiene ocupados los 100 documentos incluidos del período actual.", "codigoPlan": "GRATIS", "nombrePlan": "Gratis", "documentosIncluidos": 100, "consumoConfirmado": 95, "reservasActivas": 5, "documentosDisponibles": 0, "inicioPeriodo": "2026-08-10T04:00:00Z", "finPeriodo": "2026-09-10T04:00:00Z", "accion": "Esperá a que se libere capacidad o cambiá a un plan que permita documentos adicionales antes de volver a emitir.", "traceId": "8f1c2b3a4d5e6f70" } } } } } }, "DocumentArchived": { "description": "El documento está conservado, pero fuera del período de acceso del plan actual", "content": { "application/problem+json": { "schema": { "type": "object", "additionalProperties": false, "properties": { "type": { "const": "https://api.sifende.com.py/problems/document-archived" }, "title": { "const": "Documento archivado" }, "status": { "const": 403 }, "detail": { "const": "El período de acceso incluido en el plan actual ha finalizado." } }, "required": [ "detail", "status", "title", "type" ] }, "examples": { "documentoArchivado": { "summary": "El período de acceso del plan actual finalizó", "value": { "type": "https://api.sifende.com.py/problems/document-archived", "title": "Documento archivado", "status": 403, "detail": "El período de acceso incluido en el plan actual ha finalizado." } } } } } }, "InternalError": { "description": "Error inesperado. En métodos que modifican estado el resultado queda indeterminado: consultá el estado antes de reintentar, porque un reintento a ciegas puede duplicar el documento", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetail" }, "examples": { "indeterminado": { "value": { "type": "https://sifende.com.py/docs/solucion-problemas/internal-error", "title": "Error interno del servidor", "status": 500, "detail": "Ocurrió un error inesperado y el resultado de la operación es indeterminado: puede haberse aplicado o no. No reintentes el envío sin antes consultar el estado, porque un reintento a ciegas puede duplicar el documento.", "resultadoIndeterminado": true, "accion": "Consultá el estado del recurso antes de reenviar. Si no podés determinarlo, contactá a soporte con el traceId.", "traceId": "8f1c2b3a4d5e6f70" } } } } } }, "KuDePending": { "description": "Preparación pendiente; esta respuesta no es un PDF. Seguir Location, que sólo consulta. Si sigue pendiente después de 2 minutos, repetir una vez la descarga sin soloConsulta.", "headers": { "Location": { "description": "Misma ruta con soloConsulta=true", "required": true, "schema": { "type": "string", "example": "/api/v1/documento-electronico/{cdc}/kude?soloConsulta=true" } }, "Retry-After": { "required": true, "schema": { "const": "5" } }, "Cache-Control": { "required": true, "schema": { "const": "no-store" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "estado": { "const": "PENDIENTE" }, "url": { "type": "null" } }, "required": [ "estado", "url" ] } } } }, "KuDeGenerationError": { "description": "No se pudo obtener el KuDE por un error interno. La extensión estado=FALLIDO sólo aparece cuando existe cierre terminal; no depende del HTTP.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetail" }, "examples": { "kude-generation-error": { "value": { "type": "https://sifende.com.py/docs/solucion-problemas/kude-generation-error", "status": 500, "detail": "No se pudo obtener el KuDE por un error interno." } } } } } }, "KuDeUnavailable": { "description": "El KuDE no está disponible temporalmente. La extensión estado=FALLIDO sólo aparece cuando existe cierre terminal; no depende del HTTP.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetail" }, "examples": { "kude-unavailable": { "value": { "type": "https://sifende.com.py/docs/solucion-problemas/kude-unavailable", "status": 503, "detail": "El KuDE no está disponible temporalmente." } } } } } }, "KuDeNotSupported": { "description": "KuDE no implementado para este tipo de documento.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetail" }, "examples": { "kude-not-supported": { "value": { "type": "https://sifende.com.py/docs/solucion-problemas/kude-not-supported", "status": 501, "detail": "KuDE no implementado para este tipo de documento." } } } } } }, "IdempotencyBadRequest": { "description": "El request o Idempotency-Key no pasó la validación", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetail" }, "examples": { "receptorIncompleto": { "summary": "Receptor contribuyente sin los campos que exige un contribuyente", "value": { "type": "https://sifende.com.py/docs/solucion-problemas/validation-error", "title": "Error de validación", "status": 400, "detail": "La solicitud contiene 2 error(es) de validación", "errores": { "receptor.tipoContribuyenteReceptor": "Tipo de contribuyente receptor es obligatorio para un contribuyente", "receptor.digitoVerificador": "Dígito verificador es obligatorio y debe contener un dígito" }, "traceId": "8f1c2b3a4d5e6f70" } }, "enumInvalido": { "summary": "Valor que no existe en la enumeración. `valoresAceptados` lista los válidos", "value": { "type": "https://sifende.com.py/docs/solucion-problemas/invalid-enum-value", "title": "Valor de enumeración inválido", "status": 400, "detail": "El campo 'receptor.tipoDocumento' recibió 'RUC', que no es un valor permitido. Valores aceptados: [CEDULA_PARAGUAYA, PASAPORTE, CEDULA_EXTRANJERA, CARNET_DE_RESIDENCIA, INNOMINADO, TARJETA_DIPLOMATICA, OTRO]", "campo": "receptor.tipoDocumento", "valorRecibido": "RUC", "valoresAceptados": [ { "codigo": "CEDULA_PARAGUAYA", "descripcion": "Cédula paraguaya" }, { "codigo": "PASAPORTE", "descripcion": "Pasaporte" } ], "traceId": "8f1c2b3a4d5e6f70" } }, "formatoInvalido": { "summary": "Tipo de dato equivocado en un campo", "value": { "type": "https://sifende.com.py/docs/solucion-problemas/invalid-format", "title": "Formato de campo inválido", "status": 400, "detail": "El campo 'items[0].cantidad' recibió un valor de tipo incorrecto: se esperaba un número decimal", "campo": "items[0].cantidad", "tipoEsperado": "número decimal", "traceId": "8f1c2b3a4d5e6f70" } }, "claveInvalida": { "summary": "Clave vacía, repetida o fuera del formato permitido", "value": { "type": "https://sifende.com.py/docs/solucion-problemas/validation-error", "title": "Clave de idempotencia inválida", "status": 400, "detail": "Idempotency-Key debe enviarse una sola vez", "campo": "Idempotency-Key" } } } } } }, "IdempotencyConflict": { "description": "La operación sigue en curso, su resultado es indeterminado o el replay expiró", "headers": { "Retry-After": { "description": "Segundos antes del próximo intento; sólo se envía para idempotency-in-progress", "schema": { "type": "integer", "description": "Segundos de espera", "example": 2 } } }, "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetail" }, "examples": { "enProceso": { "summary": "La operación sigue en curso; sólo este caso incluye Retry-After", "value": { "type": "https://sifende.com.py/docs/solucion-problemas/idempotency-in-progress", "title": "Solicitud idempotente en proceso", "status": 409, "detail": "Ya existe una solicitud con esta clave en proceso; reintentá después del intervalo indicado" } }, "outcomeDesconocido": { "summary": "El efecto externo no pudo determinarse y no debe reenviarse", "value": { "type": "https://sifende.com.py/docs/solucion-problemas/idempotency-outcome-unknown", "title": "Resultado idempotente indeterminado", "status": 409, "detail": "El resultado de la operación es indeterminado; no vuelvas a enviar la operación" } }, "claveExpirada": { "summary": "El replay ya no está disponible y la clave permanece reservada", "value": { "type": "https://sifende.com.py/docs/solucion-problemas/idempotency-key-expired", "title": "Clave de idempotencia expirada", "status": 409, "detail": "El resultado asociado a la clave de idempotencia expiró y ya no puede reproducirse; la clave no puede reutilizarse" } } } } } }, "IdempotencyKeyReused": { "description": "La misma clave fue usada para otro tipo de operación", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetail" }, "examples": { "claveReutilizada": { "value": { "type": "https://sifende.com.py/docs/solucion-problemas/idempotency-key-reused", "title": "Clave de idempotencia reutilizada", "status": 422, "detail": "La clave de idempotencia ya fue usada para otro tipo de operación" } } } } } }, "IdempotencyUnavailable": { "description": "SIFEN no confirmó el resultado", "headers": { "Retry-After": { "description": "Segundos antes del próximo intento; sólo se envía para idempotency-upstream-unknown", "schema": { "type": "integer", "description": "Segundos de espera", "example": 2 } } }, "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetail" }, "examples": { "upstreamDesconocido": { "summary": "SIFEN no confirmó el resultado; se debe reintentar con la misma clave", "value": { "type": "https://sifende.com.py/docs/solucion-problemas/idempotency-upstream-unknown", "title": "Resultado SIFEN no confirmado", "status": 503, "detail": "No se pudo confirmar el resultado en SIFEN; reintentá con la misma Idempotency-Key después del intervalo indicado" } } } } } } }, "securitySchemes": { "apiKey": { "type": "http", "description": "API key de Sifende en el header `Authorization: Bearer {api-key}`.\nAdemás de autenticar, fija el contribuyente emisor y un ambiente inmutable DEV, PROD o\nSANDBOX: por eso ninguno de los dos se envía en el body.\nEn PROD, la clave requiere un plan que incluya la API de integración; si no, toda ruta\nresponde 403 `plan-operation-not-allowed`.\n", "scheme": "bearer" } } } } ```