Self-hosted DIAN API

La API DIAN Colombia que corre en tu propia infraestructura

Descargas el binario, activas tu licencia y lo despliegas donde quieras: tu VPS, tu Docker, tu desktop. Tu data, tus certificados y los de tus clientes nunca salen de tu red. Pagas plano por licencia, no por documento facturado.

Binario Go · sin runtimeLicencia firmada Ed25519Updates firmados ante cambios DIANSolo Colombia (DIAN)
bash — apidian start
$ curl -L https://updates.lyroo.com.co/latest/apidian-linux-amd64 -o apidian
$ chmod +x apidian

$ LICENSE_KEY="eyJhbGciOiJFZERTQSI..." ./apidian start
# Verifica firma Ed25519 contra public key embebida...
[INFO]  License OK · plan=pro · max_nits=10 · expires=2027-05-04
[INFO]  Heartbeat scheduled · interval=24h
[INFO]  Update channel=stable · current=2.0.1 · up to date
[INFO]  Server starting · port=8080

$ curl -X POST http://localhost:8080/api/v1/documents/invoice \
  -H "Authorization: Bearer $TOKEN" \
  -d '{ "company_id": 1, ... }'
{ "cufe": "901db8b9...", "status_code": "00", "is_valid": true }
Por que Lyroo

Lo que nos hace diferentes

No competimos con todos. Hacemos una sola cosa, bien: facturacion electronica DIAN para devs que ya tienen su propio producto.

Self-hosted, tu data nunca sale

Corres el binario donde quieras: tu VPS, tu Docker, tu desktop con Wails. Los certificados .p12 de tus clientes y sus facturas nunca tocan nuestros servidores. Cumplimiento de soberania de datos sin papeleo.

Licencia firmada Ed25519, sin lock-in

Tu licencia es un JWS firmado con curva Ed25519. El binario la valida offline contra una public key embebida — no necesita pegarle a nuestro servidor para funcionar. Si nosotros desaparecemos manana, tu binario sigue firmando.

Updates firmados ante cambios DIAN

Cuando DIAN publica una nueva resolucion o cambia un catalogo, lanzamos un update firmado. Tu binario te notifica, descarga la nueva version (verificando SHA256 + firma) y sigue cumpliendo sin que tengas que recompilar nada.

Multi-tenant nativo desde el dia 1

Cada NIT tiene su propio SMTP, certificado, resolucion, logo y origenes CORS. Aislamiento por company_id en todas las queries. Un solo binario maneja varios NITs sin levantar instancias separadas.

Pago plano, sin per-doc fees

Pagas la licencia mensual en COP y emites todos los documentos de tu cupo. Sin micro-cobros por factura, sin sorpresas a fin de mes. Si te pasas del cupo, te avisamos antes de bloquear — nunca interrumpimos tus facturas reales.

100% enfocado en Colombia

No intentamos ser una solucion regional generica. Solo DIAN Colombia: UBL 2.1 CO, catalogos DIAN actualizados, formatos POS y contingencia segun resolucion vigente. Cuando DIAN cambia, nosotros cambiamos.

Capacidades

Todo lo que necesitas para integrar DIAN en tu sistema

7 tipos de documento DIAN

  • Factura electronica (Tipo 01)
  • Documento Soporte (Tipo 05)
  • POS 80mm (Tipo 20)
  • Contingencia + batch (Tipo 25)
  • Notas credito y debito (91, 92, 95)
  • Nomina electronica con CUNE (Tipo 102)

Firma + transmision DIAN

  • XML UBL 2.1 conforme DIAN
  • Firma XAdES-EPES
  • PKCS12 BER decoder puro Go
  • CUFE/CUDE/CUNE + DV (SHA-384)
  • WS-Security SOAP + BinarySecurityToken
  • SendBillSync, SendTestSetAsync, GetStatusZip

Multi-tenant nativo

  • Multiples NITs por cuenta
  • RBAC: super_admin, company_admin, operator, read_only
  • Aislamiento por company_id en todas las queries
  • Registro por invitacion (codigo de un solo uso)
  • Login + JWT + verify email + reset password
  • TransactionManager para atomicidad

Webhooks salientes

  • Firma HMAC-SHA256
  • Reintentos con backoff exponencial
  • Eventos: document.created/signed/approved
  • Eventos: document.rejected/failed
  • Cola async buffered
  • Timeline de eventos en document_events

Recursos y catalogos DIAN

  • 1.122+ municipios y 33 departamentos CO
  • Tipos de documento, organizacion, regimen, responsabilidad
  • Impuestos (IVA, INC, ICA), medios y formas de pago
  • CRUD de clientes con busqueda por NIT
  • CRUD de items / productos
  • Resoluciones DIAN con contadores atomicos por NIT

Operaciones y observabilidad

  • Metricas Prometheus en /metrics
  • Request ID + structured JSON logs
  • Audit log inmutable de operaciones
  • Rate limiting per-IP (token bucket)
  • Circuit breaker para SOAP DIAN
  • Graceful shutdown + health checks

PDF + Email por tenant

  • PDF carta A4 + ticket POS 80mm
  • Logo + QR embebido por empresa
  • SMTP propio por NIT (factura sale del correo del cliente)
  • Cola async con backoff exponencial (202 Accepted)
  • Reintentos automaticos
  • Fallback a SMTP global si el tenant no configuro

Licencia + updates firmados

  • Licencia JWS Ed25519 validada offline
  • Public key embebida al compilar el binario
  • Heartbeat cada 24h (uso + version)
  • Modo grace 7 dias si pierde internet
  • Update manifest firmado · SHA256 verificado
  • Updates criticos cuando DIAN cambia normativa

Seguridad

  • JWT HS256 (golang-jwt v5)
  • Bcrypt cost 12 para passwords
  • AES-256-GCM para cert .p12 + SMTP at-rest
  • CORS por tenant: cada empresa registra origenes
  • Audit log inmutable + invitation_redemptions
  • Rate limiting + circuit breaker DIAN
Sandbox

Descarga, activa y prueba en tu maquina

Sandbox gratis para siempre. Te emitimos una licencia sandbox firmada, descargas el binario y corre todo en tu localhost. Mismo API que produccion, sin pegar a la DIAN real.

Descarga el binario y arranca

Un solo binario estatico Go (~25 MB). Disponible para Linux, Windows y macOS, mas la version embebida (dian-go-embedded) para meterlo dentro de una app desktop con Wails. Sin runtime, sin Docker obligatorio, sin instalador.

Simulador DIAN integrado

En sandbox las requests no pegan al WS real de la DIAN. Un simulador local devuelve respuestas sinteticas en milisegundos: approved, rejected, pending o failed segun el escenario que fuerces con un header.

Multi-tenant real (3 empresas)

Crea hasta 3 NITs de prueba para validar el aislamiento por company_id, configurar SMTP por tenant y probar el flow real con multiples empresas antes de pasar a produccion.

Webhooks contra localhost

Como corres el binario en tu maquina, los webhooks pueden apuntar a localhost directo. Cada evento llega firmado con HMAC-SHA256 en el header X-Lyroo-Signature.

Fuerza el escenario que quieras probar

Pasa un header opcional X-Sandbox-Scenario en sandbox y el simulador devuelve esa respuesta. Asi pruebas tu manejo de errores sin esperar que la DIAN realmente rechace algo.

00Aprobado
66Rechazado por reglas
90En proceso
99Error tecnico DIAN
bash — sandbox simulator
$ curl -X POST http://localhost:8080/api/v1/documents/invoice \
  -H "Authorization: Bearer $SANDBOX_TOKEN" \
  -H "X-Sandbox-Scenario: 66" \
  -d '{ "company_id": 1, ... }'

# Respuesta sintetica del simulador (sin pegar a DIAN):
{
  "document_id": 42,
  "number": "FE-42",
  "cufe": "sandbox-fake-cufe-...",
  "status_code": "66",
  "is_valid": false,
  "message": "Documento rechazado por reglas de validacion",
  "errors": [
    "DIAN: Sandbox simulator forced rejection (X-Sandbox-Scenario: 66)"
  ],
  "_sandbox": true
}

Importante

Sandbox es solo para desarrollo. Los CUFE generados llevan prefijo sandbox- y los documentos no son legalmente validos. Para empezar a emitir facturas reales necesitas: licencia de produccion (Starter+), certificado de firma digital DIAN del cliente y resolucion de facturacion vigente.

Quickstart

De licencia a facturando en 5 pasos

01

Solicita tu licencia

El acceso no es publico (asi blindamos la plataforma). Nos cuentas tu uso esperado y te emitimos una LICENSE_KEY: un JWS firmado con Ed25519 que contiene tu plan, max NITs, max docs/mes y fecha de expiracion. Sandbox es gratis para siempre.

# Recibes por email:
LICENSE_KEY=eyJhbGciOiJFZERTQSIsImtpZCI6Imx5cm9vLTIwMjYtMDEifQ
.eyJzdWIiOiJjdXN0X2FiYzEyMyIsInBsYW4iOiJzYW5kYm94Iiw
ibWF4X25pdHMiOjMsImV4cCI6MTc2MTUzNjAwMH0
.<sig-ed25519>
02

Descarga el binario y arranca

Un solo binario estatico Go: ~25 MB, sin runtime, sin dependencias. Disponible para Linux/Windows/macOS y como libreria embebida (dian-go-embedded) si prefieres meterlo dentro de tu app desktop.

$ curl -L https://updates.lyroo.com.co/latest/apidian-linux-amd64 -o apidian
$ chmod +x apidian

$ LICENSE_KEY="eyJhbGc..." ./apidian start
[INFO] License OK · plan=sandbox · expires=2027-05-04
[INFO] Server starting · port=8080
03

Configura DIAN: software, certificado y resolucion

Tres llamadas para subir el .p12 (multipart), registrar tu Software ID y crear la resolucion. El password del certificado se cifra at-rest con AES-256-GCM. Todo queda en tu Postgres local — nunca toca nuestros servidores.

PUT  /api/v1/companies/{id}/config/software
PUT  /api/v1/companies/{id}/config/certificate    # multipart
POST /api/v1/companies/{id}/config/resolution
PUT  /api/v1/companies/{id}/config/environment    # 1=prod, 2=hab
04

Emite tu primera factura

Un solo endpoint hace el flow completo: crea el documento, firma con tu .p12, transmite a DIAN, devuelve CUFE y status. En sandbox el simulador responde en milisegundos sin pegar al WS real.

POST /api/v1/documents/invoice
{
  "company_id": 1,
  "type_document_id": 1,
  "resolution_id": 1,
  "customer": { ... },
  "items": [ ... ]
}

# Response:
{ "cufe": "901db8b9...", "status_code": "00", "is_valid": true }
05

Recibe updates ante cambios DIAN

El binario hace heartbeat cada 24h y consulta el manifest de updates firmado Ed25519. Cuando DIAN cambia algo, te notifica en logs (y opcional: instala automaticamente). Tu sigues cumpliendo sin recompilar.

[INFO] Update available: v2.1.0 (current: v2.0.1)
[INFO] Critical: yes — DIAN resolucion 165 (UBL 2.1 ajustes)
[INFO] Released: 2026-05-10 · SHA256 verified · sig OK

$ apidian update --apply
[INFO] Downloaded · verified · restarting...

Coleccion Postman lista con 109 requests en 12 carpetas. Ver documentacion completa →

Planes

Tarifa plana mensual, sin sorpresas

Eliges un cupo de documentos al mes y pagas plano. Si te acercas al limite, te avisamos antes de bloquearte. Sandbox gratis, sin permanencia, en pesos colombianos.

Sandbox

Para probar la API sin compromiso

Gratispara siempre
  • Binario completo · sin limites de tiempo
  • Hasta 3 NITs de prueba (multi-tenant)
  • Simulador DIAN integrado · sin pegar al WS real
  • Documentos ilimitados (sin valor legal)
  • Webhooks contra localhost / ngrok
  • Coleccion Postman + Swagger embebido
Solicitar licencia

Starter

Para tu primer cliente real

$19.900COP /mes
  • Hasta 500 documentos/mes
  • 1 NIT en produccion
  • Updates firmados Ed25519 incluidos
  • Webhooks + reintentos automaticos
  • PDFs ilimitados (carta + POS 80mm)
  • Soporte por email · respuesta en 48h
Solicitar licencia
Mas popular

Pro

Para integradores con varios clientes

$49.900COP /mes
  • Hasta 5.000 documentos/mes
  • Hasta 10 NITs (multi-tenant)
  • Todos los tipos DIAN (incl. nomina)
  • Updates firmados con notificacion
  • Audit log + metricas Prometheus
  • Soporte WhatsApp + email
Solicitar licencia

Scale

Para alto volumen y muchos NITs

$129.900COP /mes
  • Hasta 50.000 documentos/mes
  • Hasta 50 NITs multi-tenant
  • Auto-update opt-in para criticos DIAN
  • Rate limits personalizados
  • Metricas Prometheus + Grafana
  • Soporte prioritario WhatsApp
Hablar con ventas

Enterprise

Custom

Para volumen muy alto, on-premise air-gapped, integraciones complejas o regulatorios particulares (banca, salud, gobierno).

Documentos y NITs ilimitados
Despliegue air-gapped (sin internet) opcional
SLA negociado por contrato
Soporte con gestor de cuenta dedicado
DPA + clausulas de confidencialidad
Integracion con tu IAM/SSO
Onboarding y migracion asistida
Codigo fuente bajo escrow opcional
Hablar con ventas

¿Por que self-hosted cuesta menos que la version managed?

La infraestructura la pones tu — un VPS de $5/mes en DigitalOcean/Hetzner es suficiente. Nosotros solo cobramos por la licencia + updates + soporte, no por hosting. Cuando salga la version managed, paga el diferencial y nosotros corremos todo por ti.

Todos los planes self-hosted incluyen: licencia firmada Ed25519, updates ante cambios DIAN, sandbox ilimitado, sin permanencia, sin cargos por NIT inactivo. El certificado de firma DIAN (.p12) lo aporta el cliente. Solo Colombia — nos enfocamos exclusivamente en DIAN.

FAQ

Lo que devs preguntan antes de integrar

Tu LICENSE_KEY es un JWS firmado con Ed25519. El binario lo valida offline contra una public key embebida al compilar — no necesita internet para arrancar ni para firmar facturas. Hay un heartbeat opcional cada 24h que reporta uso y verifica si hay updates; si pierdes internet, el binario sigue funcionando 7 dias en modo grace, despues empieza a advertir, y a los 14 dias deja de firmar nuevas facturas. Las ya firmadas nunca se invalidan.

No. El binario corre en tu infraestructura (tu VPS, tu Docker, tu desktop). Tus certificados .p12, las facturas, los CUFEs, los emails de tus clientes — todo vive en tu Postgres local. Lo unico que viaja a nuestros servidores es el heartbeat con conteos agregados (cuantos NITs activos, cuantos docs emitidos en el mes, version del binario). Sin metadata de facturas, sin clientes, sin XMLs.

Mantenemos un manifest firmado Ed25519 en updates.lyroo.com.co. El binario lo consulta en cada heartbeat. Cuando publicamos un update (especialmente los criticos por cambios DIAN), tu binario lo detecta, te avisa en logs y opcionalmente lo descarga y aplica solo (verificando SHA256 + firma). En self-hosted decides tu cuando aplicar; en plan Scale puedes activar auto-update para criticos.

En sandbox no necesitas nada de la DIAN: el simulador local te devuelve respuestas sinteticas. Para produccion necesitas tres cosas que aporta tu cliente final: (1) certificado de firma digital .p12 vigente, (2) resolucion de facturacion electronica activa con su rango de numeracion y (3) Software ID y PIN registrados en el portal MUISCA.

Lo aporta tu cliente final. Cada NIT factura con su propio certificado, emitido a su nombre por una entidad certificadora autorizada en Colombia (Andes SCD, Certicamara, GSE, etc.). El binario lo recibe via PUT /companies/{id}/config/certificate y lo cifra at-rest con AES-256-GCM en tu propia BD. El password del certificado tambien queda cifrado. Nunca sale de tu infraestructura.

Minimo: 1 vCPU, 512 MB RAM, 10 GB disco, Postgres 14+. En la practica corre comodo en un VPS de $5/mes (DigitalOcean, Hetzner, Vultr) o en una Raspberry Pi 4. El binario es estatico Go, sin runtime. Tambien puedes embebirlo en una app desktop con Wails (la libreria dian-go-embedded). No requiere kubernetes ni docker — un systemd unit alcanza.

Si, en sandbox puedes registrar URLs locales (localhost, 127.0.0.1) o de tunneling (ngrok, cloudflared). Cada evento llega firmado con HMAC-SHA256 en el header X-Lyroo-Signature; valida la firma en tu handler usando el secret que recibes al registrar el webhook. En produccion solo aceptamos URLs HTTPS publicas.

Te enviamos avisos por email a 80% y 95% del cupo. Si llegas al 100% no te bloqueamos a mitad de mes: te ofrecemos pasar al siguiente plan o pagar overage por documentos extra hasta fin de mes. La idea es que nunca interrumpamos tus facturas reales por una decision de billing.

Depende del plan: Sandbox 3, Starter 1, Pro 10, Scale 50, Enterprise ilimitado. Cada NIT tiene su propio certificado, resolucion, SMTP, logo, origenes CORS y aislamiento por company_id en todas las queries. Es multi-tenant nativo, no un parche encima de monotenant.

Del email de tu cliente. Cada NIT configura su propio SMTP via PUT /companies/{id}/config/smtp y todas las facturas de ese NIT salen desde esa cuenta. El password SMTP se cifra con AES-256-GCM antes de guardarse. Si un NIT no configura SMTP propio, cae al SMTP global como fallback.

No. CORS solo aplica si tu integracion corre en navegador. Si llamas server-to-server (backend, scripts, jobs, Postman) no necesitas configurar nada de CORS, solo un JWT valido. Si tu app es SPA o web, cada NIT registra sus dominios via PUT /companies/{id}/config/cors-origins y el servidor responde headers CORS solo cuando el Origin esta en el allow-list.

Los siete principales: Factura electronica (Tipo 01), Documento Soporte (Tipo 05), POS 80mm (Tipo 20), Contingencia con batch send (Tipo 25), Notas Credito (91), Notas Debito (92), Nota Credito de Documento Soporte (95) y Nomina electronica con CUNE (Tipo 102). Todos generan XML UBL 2.1 conforme DIAN, firmado XAdES-EPES y transmitido via SOAP con WS-Security.

Si, en plan Enterprise. La validacion de licencia es offline (JWS Ed25519 contra public key embebida) asi que arranca sin internet. Lo que pierdes en air-gapped: heartbeat de uso (no podemos saber tu consumo) y updates automaticos (te enviamos el binario nuevo por canal seguro cuando DIAN cambia). Tambien necesitas conexion al WS DIAN para transmitir facturas reales — eso es de DIAN, no nuestro.

Tenemos un circuit breaker alrededor del SOAP DIAN: si falla 5 veces seguidas, se abre por 30 segundos para no saturar. Las requests durante ese tiempo se rechazan rapidamente con codigo claro para que tu app reintente o entre en flujo de contingencia (Tipo 25). Cuando la DIAN se recupera, el batch-send envia las contingencias acumuladas.

Limite de payload: 10 MiB por request (configurable). En la practica eso son varios miles de items por factura. Si necesitas mas, hablamos en Enterprise.

¿Otra pregunta? Escribenos a hola@lyroo.com.co.

Listo para correr DIAN en tu infraestructura

Sandbox gratis con simulador DIAN. Binario listo para Linux, Windows, macOS y desktop. Soporte directo del equipo que construye la API.

El acceso requiere licencia firmada (Sandbox gratis) para mantener el estandar de la plataforma.