Documentación de la API de JCFlow
Integra facturación electrónica DIAN en tu aplicación
La API de JCFlow te permite emitir facturas electrónicas, notas crédito, notas débito y documentos soporte directamente desde tu sistema ERP, POS o aplicación personalizada.
URL Base
https://api.jcflow.com.co/v1/apiFormato de Respuesta
El formato de respuesta siempre incluye success (boolean), message (string) y data (object|array).
{
"success": true,
"message": "Operación exitosa",
"data": { }
}Tipos de Documento Soportados
| Código | Tipo | Descripción |
|---|---|---|
| 1 | FE | Factura Electrónica de Venta |
| 2 | NC | Nota Crédito Electrónica |
| 3 | ND | Nota Débito Electrónica |
| 4 | DS | Documento Soporte Electrónico |
Autenticación
Todas las peticiones requieren autenticación mediante API Key en el header.
Nombre del Header
X-Api-Key: sk_test_tu_api_key_aquiClaves de prueba
Las API Keys con prefijo sk_test_ operan en ambiente de pruebas.
Claves de producción
Las API Keys con prefijo sk_live_ operan en ambiente real de la DIAN.
curl -X GET https://api.jcflow.com.co/v1/api/api-keys/test \
-H "X-Api-Key: sk_test_tu_api_key_aqui"⚡ Rate Limiting
Cada API Key tiene un límite de peticiones por minuto (por defecto 100 req/min). Los headers de respuesta informan el estado del rate limit:
| Header | Descripción |
|---|---|
| X-RateLimit-Limit | Máximo de peticiones permitidas por ventana |
| X-RateLimit-Remaining | Peticiones restantes en la ventana actual |
| X-RateLimit-Reset | Timestamp Unix cuando se reinicia la ventana |
| Retry-After | Segundos para esperar (solo en respuestas 429) |
// Ejemplo: Retry con backoff exponencial
async function apiCall(url, options, retries = 3) {
for (let i = 0; i < retries; i++) {
const res = await fetch(url, options);
if (res.status === 429) {
const retryAfter = res.headers.get('Retry-After') || 5;
await new Promise(r => setTimeout(r, retryAfter * 1000 * (i + 1)));
continue;
}
return res.json();
}
throw new Error('Rate limit exceeded after retries');
}🔒 Idempotencia
Usa el campo referencia_externa para garantizar que un documento no se emita más de una vez. Este campo actúa como clave de idempotencia protegida por un lock distribuido Redis.
{
"id_tipo_documento": 1,
"referencia_externa": "INV-2026-00042",
"invoice_lines": [...]
}Respuestas de Duplicado
| Código | Error Code | Escenario |
|---|---|---|
| 409 | DUPLICATE_REFERENCE | Documento ya existe con esa referencia_externa |
| 409 | DUPLICATE_IN_PROGRESS | Otra petición con la misma referencia está siendo procesada |
| 409 | DUPLICATE_PAYLOAD | Payload idéntico enviado en los últimos 5 minutos |