Up to 200 documents per month
Gs. 1,000,000 per year (2 months free)
Send a JSON, get an identifier back, and the ECAV gateway signs, transmits to the DNIT and returns the CDC, the XML and the KuDE. It is the same API the Odoo module uses.
It is a REST e-invoicing gateway for Paraguay, built for systems that are not Odoo: an in-house or third-party ERP, a point of sale, an e-commerce site, recurring billing. You build the document as JSON. The gateway builds the XML, validates it, signs it with your certificate, sends it to SIFEN, polls the batch and stores the XML and the KuDE.
The model is asynchronous: every issue answers 202 with an identifier, and the result is polled or arrives by webhook. There is no synchronous mode. Average latency is under 2 seconds, so polling the result every second feels almost immediate without holding a connection open.
If you already use Odoo you probably do not need the API: the Odoo module uses this same gateway.
https://sifen.ecav.com.py.Authorization: Bearer sk_live_.... For testing you use an sk_test_... key.context.environment and must match the key prefix.To get a key, write to us. Before the first call you need the DNIT requirements sorted out: .p12 certificate, enablement as an electronic issuer, timbrado and CSC.
With a POST /v1/sifen/documents. The body has four parts: document_kind (factura, autofactura, nota_credito, nota_debito or remision), invoice_data (the document: receiver, items, payment condition), params_data (the issuer and the timbrado) and context (certificate, CSC, environment and a reference of your own).
curl -X POST https://sifen.ecav.com.py/v1/sifen/documents \
-H "Authorization: Bearer sk_test_XXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: FAC-2026-0001" \
-d @factura.json
{
"document_kind": "factura",
"invoice_data": {
"establecimiento": "001",
"punto": "001",
"tipoTransaccion": 2,
"tipoImpuesto": 1,
"moneda": "PYG",
"condicion": { "tipo": 1, "entregas": [{ "tipo": 1, "monto": 110000 }] },
"cliente": { "ruc": "5012345-6", "razonSocial": "Cliente SA" },
"items": [{ "descripcion": "Servicio mensual", "cantidad": 1, "precioUnitario": 110000 }]
},
"params_data": { "ruc": "80000000-7", "timbradoNumero": "12345678" },
"context": {
"certificate_b64": "<.p12 en base64>",
"certificate_password": "<contraseña del .p12>",
"csc": "<CSC>",
"csc_id": "0001",
"environment": "test",
"document_ref": "FAC-2026-0001"
}
}
The gateway answers right away, without waiting for the DNIT:
HTTP/1.1 202 Accepted
{
"request_id": "req-8f3a1c2e9b7d4e60",
"poll_url": "/v1/sifen/documents/req-8f3a1c2e9b7d4e60",
"webhook_will_fire": true,
"processing_delayed": false
}
Two details that save trouble:
request_id and the document is not issued twice. The key is unique per tenant. Use, for example, the document's identifier in your system.context as certificate_b64 and certificate_password. The other ways to deliver it are in the integration manual.The complete field reference by document type, the webhook verification code and the certificate options are not published here: they are delivered in the integration manual when your account is activated. Ask for your key and we will send it.
With GET /v1/sifen/documents/{request_id or CDC}. It works with the identifier of the issue or with the document's CDC, and you only see your own tenant's documents.
curl https://sifen.ecav.com.py/v1/sifen/documents/req-8f3a1c2e9b7d4e60 \
-H "Authorization: Bearer sk_test_XXXXXXXXXXXXXXXX"
{
"request_id": "req-8f3a1c2e9b7d4e60",
"cdc": "01800000007001001000000122026110511234567892",
"state": "accepted",
"sifen_status_code": "0260",
"sifen_status_message": "Autorización del DE satisfactoria",
"xml_url": "<URL firmada del XML>",
"kude_url": "<URL firmada del KuDE>",
"extra": { "protocolo": "<número de autorización>" }
}
The state field takes one of these values: pending (queued), signed (signed, with CDC and XML, waiting for the DNIT), accepted (approved), accepted_obs (approved with remarks), rejected, cancelled, inutilized or error (technical error, no SIFEN verdict). sifen_status_code and sifen_status_message carry the DNIT code and message; extra.protocolo is the authorization number the DNIT adds to the document.
If you need the DNIT's answer right now and not the one we already have on record, POST /v1/sifen/documents/{id}/consult asks SIFEN using the certificate you send in context.
Every state change can be delivered with a POST to your URL. Deliveries are signed with HMAC-SHA256 using your webhook secret, and carry headers to verify the signature, identify the event and drop repeats. Delivery is at least once, so one may repeat; if your endpoint fails many times in a row, the gateway disables it. Webhooks and polling coexist: you can use both. The verification code is in the integration manual.
| Endpoint | What it is for |
|---|---|
POST /v1/sifen/documents |
Issue a document. |
POST /v1/sifen/documents/batch |
Issue up to 50 documents in one request. Each is validated separately: an invalid one does not take down the rest. |
GET /v1/sifen/documents/{request_id or CDC} |
Get the state and the links to the XML and the KuDE. |
POST /v1/sifen/documents/{id}/consult |
Ask SIFEN on the spot. |
POST /v1/sifen/documents/{cdc}/cancel |
Cancel an approved document, with its reason. |
POST /v1/sifen/range/inutilize |
Invalidate a numbering range. |
POST /v1/sifen/documents/{cdc}/nominacion and /transporte |
Buyer confirmation and transport data events. |
POST /v1/sifen/documents/{cdc}/kude |
Regenerate the KuDE. |
POST /v1/sifen/receptor-events/... |
Receiver events: conformity, disagreement, non-recognition and notification. |
GET /v1/sifen/events/{request_id} |
Result of an event (cancellation, range invalidation, etc.). |
GET /v1/sifen/ruc/{ruc} and /ruc-search |
Look up the DNIT registry by RUC or by name. |
The RUC lookup is the same one behind the free RUC lookup tool. To decode or validate a CDC without writing code, use the CDC validator.
| Code | When |
|---|---|
| 202 | Document queued. |
| 401 | The key is missing, invalid or revoked. |
| 402 | The plan spending limit was reached. |
| 403 | Subscription suspended or paused. |
| 404 | The document does not exist or is not in your tenant. |
| 413 | The body exceeds the maximum size. |
| 422 | Validation failed. The response says which field. |
| 429 | Queue saturated. It carries Retry-After: retry after that time. |
A document the DNIT rejects does not use up quota: it is deducted only when SIFEN accepts the document.
With an sk_test_ key and context.environment set to test, the gateway uses the DNIT test environment. According to the DNIT test guide, the test timbrado there is the RUC without its check digit, 8 digits, and the document carries the test-environment legend, which the gateway adds. The DNIT also offers a prevalidator to check an XML before sending it. The first month of ECAV SIFEN is free with no card.
The plans are those of ECAV SIFEN, by monthly document volume, and apply to all three routes (API, Odoo and portal). There is more detail on pricing.
Up to 200 documents per month
Gs. 1,000,000 per year (2 months free)
Up to 500 documents per month
Gs. 2,000,000 per year (2 months free)
Unlimited documents (fair use) · VAT included
Gs. 3,000,000 per year (2 months free)
Fair use on Business: above 3,000 documents a month we reach out to make sure you are on the best plan.
No. Every issue answers 202 with a request_id and the result is polled with a GET or arrives by webhook. Average latency is under 2 seconds.
Send the Idempotency-Key header with a value that is unique per operation, for example the document's identifier in your system. If you retry with the same key you get the same request_id and no new issue.
Yes. POST /v1/sifen/documents/batch accepts up to 50 documents per request; each one is validated and queued separately, and the gateway groups them into the same SIFEN batch.
The document stays in process and is not lost: the gateway retries the submission when the DNIT does not answer, and your system checks the result by request_id until there is a verdict, or receives it by webhook.
With POST /v1/sifen/documents/{cdc}/cancel and a reason. If the deadline the DNIT sets for that document type has passed, the gateway answers 422 with the detail.
In the integration manual we deliver when your account is activated: it has the fields of each document type, the code to verify webhooks and the certificate options. Write to us to ask for your key and get it.
From Gs. 100,000 a month depending on document volume, with the first month free. See the plans above and pricing.