Electronic Invoicing
/v1/api/facturacionUnified endpoint — issues all 10 electronic document types (FE, NC, ND, DS, NC-DS, Export, Contingency T03/T04, POS, POS Adjustment Note).
/v1/api/facturacion/fastFast asynchronous emission (~30-50ms) — atomic consecutive reservation, CUFE and QR calculation, XAdES digital signing, and BullMQ queueing for DIAN transmission.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| id_tipo_documento | integer | Yes | 1=FE, 2=NC, 3=ND, 4=DS, 5=NC-DS, 6=Export, 7=Contingency T03, 8=Contingency T04, 9=POS, 10=POS Adjustment |
| transmit | boolean | No | true to transmit to DIAN immediately |
| async | boolean | No | true = 202 Accepted response + background processing via BullMQ. false (default) = synchronous. |
| customer | object | Yes | Customer data (see sub-table) |
| invoice_lines | array | Yes | Document lines (FE & DS). For NC use credit_note_lines, for ND use debit_note_lines |
| legal_monetary_totals | object | No | Monetary totals |
| tax_totals | array | No | Tax summary |
| payment_form | object | No | Payment form |
| notes | string | No | Notes |
| id_documento_referencia | integer | No | NC/ND only: ID of the original document it applies to |
| id_concepto_nota | string | No | NC/ND only: Concept/reason code |
| referencia_externa | string | No | Unique reference from your system (e.g., "ORD-001"). Prevents duplicates — if it exists, returns 409 |
Customer Sub-table
| Field | Type | Required | Description |
|---|---|---|---|
| identification_number | string | Yes | Customer NIT or CC |
| name | string | Yes | Business name |
| string | Yes | Email for document delivery | |
| type_document_identification.code | string | No | 13=CC, 31=NIT, 22=CE, 41=Pasaporte |
| type_organization.code | string | No | 1=Legal Entity, 2=Natural Person |
| address | string | No | Address |
| municipality.code | string | No | DANE municipality code |
| municipality.name | string | No | Municipality name |
Invoice Lines Sub-table
| Field | Type | Required | Description |
|---|---|---|---|
| description | string | Yes | Product/service description |
| invoiced_quantity | number | Yes | Quantity |
| line_extension_amount | number | Yes | Line subtotal (without taxes) |
| price_amount | number | Yes | Unit price |
| unit_measure.code | string | No | Unit of measure code (94=Unit) |
| tax_totals | array | No | Taxes for this line |
Request Example
{
"id_tipo_documento": 1,
"referencia_externa": "ORD-2026-001",
"transmit": true,
"async": false,
"customer": {
"identification_number": "900123456",
"name": "Empresa XYZ SAS",
"email": "facturacion@xyz.com",
"type_document_identification": {
"code": "31"
},
"type_organization": {
"code": "1"
},
"address": "Calle 123 #45-67, Bogotá",
"municipality": {
"code": "11001",
"name": "Bogotá D.C."
}
},
"invoice_lines": [
{
"description": "Servicio de consultoría",
"invoiced_quantity": 1,
"line_extension_amount": 1000000,
"price_amount": 1000000,
"unit_measure": {
"code": "94"
},
"tax_totals": [
{
"tax_code": "01",
"tax_name": "IVA",
"percent": 19,
"taxable_amount": 1000000,
"tax_amount": 190000
}
]
}
],
"legal_monetary_totals": {
"line_extension_amount": 1000000,
"tax_exclusive_amount": 1000000,
"tax_inclusive_amount": 1190000,
"payable_amount": 1190000
},
"tax_totals": [
{
"tax_code": "01",
"tax_name": "IVA",
"percent": 19,
"taxable_amount": 1000000,
"tax_amount": 190000
}
]
}Sync Response (200 OK)
{
"success": true,
"message": "Factura Electrónica procesado exitosamente",
"data": {
"documento": {
"id": 1,
"prefijo": "SETT",
"numero": "001",
"cufe": "sha384...",
"total": 1190000
},
"xml": "<Invoice>...</Invoice>",
"cufe": "a1b2c3d4e5f6...",
"cufe_scheme": "CUFE-SHA384",
"qr_url": "https://catalogo-vpfe.dian.gov.co/document/searchqr?documentkey=a1b2c3...",
"transmission": {
"isValid": true,
"statusCode": "00",
"statusDescription": "Procesado Correctamente",
"errors": [],
"zipKey": "uuid-track-id",
"retryable": false
}
}
}Fast / Async Emission Response (202 Accepted)
{
"success": true,
"estado": "PENDIENTE_DIAN",
"id_documento": 10452,
"prefijo": "FE",
"numero": 1001,
"cufe": "a1b2c3d4e5f67890123456789abcdef0123456789abcdef0123456789abcdef...",
"qr_url": "https://catalogo-vpfe.dian.gov.co/document/searchqr?documentkey=a1b2c3...",
"consultar_en": "/v1/api/facturacion/10452/estado",
"mensaje": "Factura creada y encolada para transmisión DIAN"
}curl -X POST https://api.jcflow.com.co/v1/api/facturacion \
-H "X-Api-Key: sk_test_tu_api_key_aqui" \
-H "Content-Type: application/json" \
-d '{"id_tipo_documento":1,"referencia_externa":"ORD-2026-001","transmit":true,"async":false,"customer":{"identification_number":"900123456","name":"Empresa XYZ SAS","email":"facturacion@xyz.com","type_document_identification":{"code":"31"},"type_organization":{"code":"1"},"address":"Calle 123 #45-67, Bogotá","municipality":{"code":"11001","name":"Bogotá D.C."}},"invoice_lines":[{"description":"Servicio de consultoría","invoiced_quantity":1,"line_extension_amount":1000000,"price_amount":1000000,"unit_measure":{"code":"94"},"tax_totals":[{"tax_code":"01","tax_name":"IVA","percent":19,"taxable_amount":1000000,"tax_amount":190000}]}],"legal_monetary_totals":{"line_extension_amount":1000000,"tax_exclusive_amount":1000000,"tax_inclusive_amount":1190000,"payable_amount":1190000},"tax_totals":[{"tax_code":"01","tax_name":"IVA","percent":19,"taxable_amount":1000000,"tax_amount":190000}]}'- Synchronous Transmission: In the production environment (or when using production API keys sk_live_...), document transmission is always processed synchronously (SendBillSync) to prevent rejections due to lack of authorization for asynchronous batch processing.
- Suppression of Empty Taxes: To avoid restrictive warnings (such as FAX05 and FAX14 notifications) on the DIAN portal, the system dynamically suppresses empty ICA (03) and INC (04) blocks with base/percentage at 0.00 when operating in production.
- Date and Signature Alignment: The emission date and time in the XML document are automatically synchronized in real-time with the digital signature timestamp (using Colombia time zone -05:00), completely eliminating rejections caused by rule FAD09e.
- Transactional Recalculation of CUFE/CUDE: The CUFE/CUDE code is dynamically recalculated and injected, integrating the official time offset of -05:00 in both the mathematical calculation and the IssueTime tag of the XML, ensuring exact consistency.
Check Status (Polling)
/v1/api/facturacion/:id/statusCheck the current status of a document. Useful for polling when using async mode.
Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id_empresa | integer | Yes | Company ID (query param) |
| check_dian | boolean | No | true = Query DIAN GetStatus live if doc is In Queue |
| ambiente | string | No | 1=Production, 2=Testing (default: 2) |
Document States
| Code | State | Description |
|---|---|---|
| 1 | Borrador | Saved, not transmitted |
| 2 | Enviado/Aceptado | DIAN accepted the document |
| 3 | En Cola | Processing in background (async mode) |
| 4 | Rechazado | DIAN rejected the document |
| 5 | Waiting DIAN | Circuit Breaker open — DIAN unavailable. Will be resent automatically. |
| 6 | Dead Letter | Exhausted 5 retries. Recovery Cron will re-queue automatically when DIAN is back. |
{
"success": true,
"data": {
"id": 1,
"prefijo": "SETT",
"numero": "001",
"id_tipo_documento": 1,
"id_estado_documento": 2,
"estado": "Enviado/Aceptado",
"cufe": "a1b2c3d4e5f6...",
"qr_url": "https://catalogo-vpfe.dian.gov.co/...",
"dian_track_id": "uuid-zip-key",
"dian_response": {
"isValid": true,
"statusCode": "00",
"statusDescription": "Procesado Correctamente"
},
"total": 1190000,
"fecha_emision": "2026-04-24",
"created_at": "2026-04-24T10:30:00Z",
"updated_at": "2026-04-24T10:30:05Z"
}
}Contingency Batch Send
/v1/api/facturacion/contingencia/enviarSends all pending contingency documents (T03/T04) to DIAN. Documents are queued in BullMQ for async processing.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| id_empresa | integer | Yes | Company ID |
| documento_ids | array | No | Specific IDs to send. If empty, sends ALL pending. |
{
"success": true,
"message": "15 documento(s) encolado(s) para transmisión.",
"data": {
"total_pendientes": 15,
"total_encolados": 15,
"total_errores": 0,
"documentos": [
{ "id": 10, "prefijo": "SETT", "numero": "100", "job_id": "bull-789" },
{ "id": 11, "prefijo": "SETT", "numero": "101", "job_id": "bull-790" }
]
}
}Utility endpoints
/v1/api/facturacion/reenviar/:idResend a draft or failed document to DIAN. Regenerates XML, signs and transmits.
/v1/api/facturacion/consecutivo/:tipoGets the next available consecutive number for a document type.
/v1/api/facturacion/suscripcionChecks subscription status: documents used, available, and limit.
🌐 Export Invoices (Multi-currency & Incoterms)
To issue export invoices (Type 02 / Operation 10), specify the foreign currency (USD, EUR), daily TRM exchange rate and Incoterms (CIF, FOB, EXW, FCA, etc.):
{
"id_tipo_documento": 2,
"id_tipo_operacion": "10",
"id_tipo_moneda": 149,
"exchange_rate": {
"source_currency": "USD",
"target_currency": "COP",
"calculation_rate": 4150.50,
"date": "2026-08-29"
},
"delivery": {
"delivery_terms": "FOB"
},
"customer": {
"name": "Global Tech Logistics LLC",
"identification_number": "US99887766",
"country_code": "US",
"type_document_identification": { "code": "41" },
"type_organization": { "code": "1" },
"email": "invoices@globaltech.us"
},
"invoice_lines": [
{
"description": "Exportación de Café Especial Colombiano (Sacos 70kg)",
"invoiced_quantity": 50,
"price_amount": 280.00,
"line_extension_amount": 14000.00,
"unit_measure": { "code": "KGM" }
}
],
"legal_monetary_totals": {
"line_extension_amount": 14000.00,
"tax_exclusive_amount": 14000.00,
"tax_inclusive_amount": 14000.00,
"payable_amount": 14000.00
},
"transmit": true
}🏥 Sectoral Invoicing (Health RIPS, Transport RNDC, Fuels)
Health Sector (RIPS)
Operation SS-SinAporte / SS-Recaudo (MinSalud Res. 2275/2023). Emits the Interoperabilidad block: provider code, payment modality, coverage, contract, copays and moderator fees.
Cargo Transport (RNDC)
Operation 12. Integrates cargo dispatch and official MinTransporte cargo manifest.
Fuels & Gas Stations
Automatic support for Fuel Tax (24), Surcharge (25) and Sordicom (26).
WebSocket Events (Real-time)
facturacion:update — Document accepted/rejected by DIAN (status, errors, zipKey)
facturacion:error — Max retries exhausted. Document will be marked as recoverable and resent automatically.
contingencia:batch — Contingency batch send started
Rooms: empresa_{id}, user_{id}
🛡️ DIAN Resilience Engine
| Layer | Mechanism | Detail |
|---|---|---|
| Circuit Breaker | Outage detection | 5 consecutive failures → pause sends 60s → automatic test → resume if DIAN responds |
| Exponential Backoff | Progressive retries | 5 attempts: 10s → 20s → 40s → 80s → 160s |
| Dead Letter Queue | Failed queue | After 5 attempts → state 6 (automatically recoverable) |
| Recovery Cron | Auto recovery | Every 5 min searches for state 5/6 docs and re-queues them if DIAN is available |
| Rate Limiter | Speed control | Max 10 req/sec to DIAN WS, 3 concurrent workers |
Circuit Breaker
CLOSED ──(5 failures)──▸ OPEN ──(60s)──▸ HALF_OPEN ──(2 successes)──▸ CLOSED
▲ │ fail
└─────────────────┘ (escalating timeout: 60s → 120s → 5min)Document States
| State | ID | Description |
|---|---|---|
| Borrador | 1 | Generated, not transmitted to DIAN |
| Accepted | 2 | DIAN accepted and validated the document |
| In Queue | 3 | Processing via BullMQ (async mode) |
| Rejected | 4 | DIAN rejected the document (business error) |
| Waiting DIAN | 5 | Circuit Breaker open — will be resent automatically |
| Dead Letter | 6 | Exhausted 5 retries — Recovery Cron will re-queue |
📊 Performance (Benchmark)
Stress test results on a local server with 500 electronic invoices burst-processed with 25 concurrent connections (without DIAN transmission).
Latency Distribution
| Metric | Value |
|---|---|
| Total requests | 500 |
| Concurrency | 25 |
| Total time | 1.78s |
| Throughput | 281 req/s |
| Avg Latency | 82ms |
| Median (P50) | 75ms |
| P95 | 162ms |
| P99 | 178ms |
| Max | 179ms |