v1 Última actualización: Mayo 2026

API de Facturación Electrónica

Emite documentos tributarios electrónicos (DTE) ante el SII de Chile desde cualquier sistema, con una sola llamada HTTP. Diseñada para integradores, ERPs y plataformas de software.

Introducción

La API de Lael permite emitir, consultar y descargar documentos tributarios electrónicos ante el Servicio de Impuestos Internos (SII) de Chile. Está basada en REST, usa JSON en todas las respuestas y sigue el patrón asíncrono: el request inicial retorna HTTP 202 de forma inmediata con un tracking_id, y el resultado final se entrega vía webhook.

URL base

# Producción
https://api.lael.cl/v1

# Sandbox / Certificación SII (documentos sin validez legal)
https://apicert.lael.cl/v1
Usa api.lael.cl para producción y apicert.lael.cl para el sandbox de certificación del SII (documentos válidos técnicamente pero sin efecto tributario real). El ambiente queda determinado por el dominio y por el prefijo de tu API Key (lael_test_ en sandbox vs lael_live_ en producción).

Autenticación

Todas las rutas requieren el header X-API-Key con tu API Key:

X-API-Key: lael_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Las API Keys son secretas y deben transmitirse únicamente desde tu servidor (nunca desde el browser o app móvil). Si una key es comprometida, puedes revocarla desde el portal de partners y generar una nueva.

PrefijoAmbienteEfecto SII
lael_test_SandboxSII certificación — sin validez tributaria
lael_live_ProducciónSII producción — documentos válidos legalmente
Cada API Key está asociada a un único RUT emisor. Si necesitas emitir en nombre de varios RUTs, crea una key por cada RUT desde el portal.

Sandbox vs Producción

CaracterísticaSandboxProducción
API Keylael_test_...lael_live_...
SIIAmbiente certificaciónAmbiente producción
Folios CAFCAFs de pruebaCAFs reales del emisor
Validez legalNo
CobroGratisSegún plan
DisponibilidadInmediata al registrarseRequiere aprobación

Inicio rápido (5 minutos)

1. Crea tu cuenta y obtén una API Key sandbox.

2. Sube tu certificado .p12 en el portal o vía API.

3. Emite tu primer DTE:

curl -X POST https://apicert.lael.cl/v1/dte/generar \
  -H "X-API-Key: lael_test_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "Documento": {
      "Encabezado": {
        "IdentificacionDTE": { "TipoDTE": 33, "FechaEmision": "2026-05-30" },
        "Emisor":   { "Rut": "76.123.456-7", "RazonSocial": "Mi Empresa SpA",
                      "GiroEmis": "Servicios TI", "DireccionOrigen": "Av. X 123",
                      "ComunaOrigen": "Santiago", "Ciudad": "Santiago" },
        "Receptor": { "Rut": "12.345.678-9", "RazonSocial": "Cliente SA",
                      "Direccion": "Calle Y 456", "Comuna": "Las Condes" },
        "Totales":  { "MontoNeto": 100000, "TasaIVA": 19, "IVA": 19000,
                      "MontoTotal": 119000 }
      },
      "Detalles": [{ "Nombre": "Servicio de desarrollo", "Cantidad": 1,
                     "Precio": 119000, "MontoItem": 119000 }]
    },
    "Certificado": { "Rut": "76123456-7", "Password": "mi_password_p12" }
  }'
<?php
// Con SDK PHP: composer require lael-cl/sdk
use LaelCl\Client;
use LaelCl\Dte\FacturaAfecta;

$lael = new Client('lael_test_xxxxxxxxxxxxxxxx');

$factura = FacturaAfecta::make()
    ->emisor('76.123.456-7', 'Mi Empresa SpA')
    ->receptor('12.345.678-9', 'Cliente SA')
    ->agregar('Servicio de desarrollo', cantidad: 1, precio: 100000)
    ->total(119000, neto: 100000, iva: 19000);

$resultado = $lael->dte()->emitir($factura)->esperar(timeoutSeg: 60);

echo $resultado->folio;       // Folio asignado
echo $resultado->urls->pdf;  // URL permanente del PDF

4. Consulta el estado con GET /v1/dte/status/{tracking_id} o espera el webhook.

Precio y MontoItem incluyen IVA (bruto) en documentos afectos (33, 39, 46, 61…). El sistema calcula el neto y el IVA a partir del monto bruto. En los Totales sí declaras MontoNeto e IVA por separado.

POST /v1/dte/generar

Emite un DTE ante el SII. Responde HTTP 202 de forma inmediata con un tracking_id. El documento se procesa en segundo plano.

POST /v1/dte/generar

Body (JSON)

CampoTipoReq.Descripción
DocumentoobjectRequeridoEstructura del DTE
Documento.Encabezado.IdentificacionDTE.TipoDTEintRequeridoTipo de documento (ver tabla)
Documento.Encabezado.IdentificacionDTE.FechaEmisionstringRequeridoFecha contable AAAA-MM-DD
Documento.Encabezado.EmisorobjectRequeridoDatos del emisor
Documento.Encabezado.ReceptorobjectRequeridoDatos del receptor
Documento.Encabezado.Totales.MontoTotalintRequeridoMonto total en CLP (entero)
Documento.DetallesarrayRequeridoLíneas de detalle (mín. 1)
Documento.Referenciaarray|nullOpcionalRequerido para NC (61), ND (56) y exportación 111/112
Certificado.RutstringOpcionalRUT del cert. Si omites, usa el del vault
Certificado.PasswordstringOpcionalPassword del .p12. Si omites, usa el del vault
IdempotencyKeystringOpcionalClave única por request para evitar duplicados en reintentos

Respuesta — 202 Accepted

{
  "ok": true,
  "data": {
    "tracking_id":     "01HWXYZ1234ABCDEF567890AB",
    "status":          "pendiente",
    "tipo_dte":        33,
    "rut_emisor":      "76.123.456-7",
    "sandbox":         false,
    "idempotency_key": "mi-erp-doc-9999",
    "urls": {
      "status": "https://api.lael.cl/v1/dte/status/01HWXYZ...",
      "pdf":    "https://api.lael.cl/v1/dte/doc/a1b2c3d4e5f6.../pdf",
      "xml":    "https://api.lael.cl/v1/dte/doc/b2c3d4e5f6a1.../xml"
    },
    "estimado_ms": 8000
  }
}
Las URLs de PDF y XML son permanentes y opacas (token de 32 chars aleatorios). No requieren X-API-Key para acceder. Puedes compartirlas directamente con el receptor.

GET /v1/dte/status/{tracking_id}

Consulta el estado de un documento. Úsalo para polling o para verificar el resultado final.

GET /v1/dte/status/{tracking_id}

Valores de status

ValorSignificado
pendienteEn cola, esperando procesamiento
procesandoFirmando y enviando al SII
completadoSII aceptó el documento
fallidoFalló tras 5 intentos — revisar error
canceladoCancelado manualmente

Respuesta cuando status: "completado"

{
  "ok": true,
  "data": {
    "tracking_id": "01HWXYZ...",
    "status":      "completado",
    "tipo_dte":    33,
    "folio":       125,
    "rut_emisor":  "76.123.456-7",
    "monto_total": 119000,
    "emitido_at":  "2026-05-30T14:32:11-04:00",
    "sii": {
      "track_id": "987654321",
      "estado":   "EPR",
      "glosa":    "Envio Procesado"
    },
    "urls": { "pdf": "...", "xml": "..." },
    "intentos":  1,
    "error":     null
  }
}

GET /v1/dte/doc/{url_token}/pdf

GET /v1/dte/doc/{url_token}/pdf

Descarga o muestra el PDF del DTE. No requiere X-API-Key — la URL es opaca y permanente (válida 6 años).

Content-Type: application/pdf

GET /v1/dte/doc/{url_token}/xml

GET /v1/dte/doc/{url_token}/xml

Descarga el XML original del DTE, firmado y con el timbre SII. Custodiado por 6 años. No requiere X-API-Key.

Content-Type: application/xml; charset=utf-8

POST /v1/partner/webhook

POST /v1/partner/webhook

Registra o actualiza la URL de webhook donde Lael enviará las notificaciones cuando el SII procese un DTE.

CampoTipoReq.Descripción
urlstringRequeridoURL HTTPS de tu servidor
eventosarrayOpcionalDefault: todos los eventos

Respuesta incluye el secret para verificar firmas HMAC. Guárdalo en un lugar seguro.

GET /v1/partner/uso

GET /v1/partner/uso?mes=2026-05

Retorna el resumen de consumo del período (excluye sandbox). Útil para billing interno.

{
  "ok": true,
  "data": {
    "periodo":          "2026-05",
    "total_emitidos":  87,
    "total_rechazados": 2,
    "desglose_tipo":   [{ "tipo_dte": 33, "emitidos": 85 }]
  }
}

POST /v1/partner/cert

POST /v1/partner/cert

Sube el certificado digital .p12 de un RUT emisor. La password se cifra con AES-256 — nunca se almacena en texto plano.

CampoTipoReq.Descripción
rut_emisorstringRequeridoRUT sin puntos, con guión
p12_base64stringRequeridoContenido del .p12 en base64
passwordstringRequeridoPassword del certificado
curl -X POST https://api.lael.cl/v1/partner/cert \
  -H "X-API-Key: lael_live_xxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "rut_emisor": "76123456-7",
    "p12_base64": "'"$(base64 -w0 /ruta/certificado.p12)"'",
    "password":   "mi_password"
  }'

Tipos de DTE soportados

TipoDTENombreReferenciaNotas
33 Factura Afecta Documento más común. IVA 19%.
34 Factura Exenta Sin IVA (servicios exentos).
39 Boleta Electrónica RUT receptor 66.666.666-6 si no hay individualización.
41 Boleta Exenta Sin IVA + sin individualización de receptor.
46 Factura de Compra El emisor compra al receptor (retención IVA).
52 Guía de Despacho Requiere TipoDespacho e IndTraslado.
56 Nota de Débito Aumenta el valor de un DTE. Requiere Referencia.
61 Nota de Crédito Anula o disminuye. Requiere Referencia.
110 Factura de Exportación Receptor: 55.555.555-5.
111 NC de Exportación Requiere Referencia.
112 ND de Exportación Requiere Referencia.

Webhooks

Lael envía un POST a tu URL cuando el estado de un DTE cambia. El body es JSON y está firmado con HMAC-SHA256.

Eventos disponibles

EventoCuándo se dispara
dte.completadoSII aceptó el documento (EPR/SOK)
dte.rechazadoSII rechazó el documento (RCH)
dte.errorFalló tras 5 intentos de envío

Estructura del payload

{
  "evento":      "dte.completado",
  "tracking_id": "01HWXYZ1234ABCDEF567890AB",
  "timestamp":   "2026-05-30T18:32:15Z",
  "sandbox":     false,
  "data": {
    "tipo_dte":   33,
    "folio":      125,
    "rut_emisor": "76.123.456-7",
    "monto_total":119000,
    "sii_estado": "EPR",
    "urls": {
      "pdf": "https://api.lael.cl/v1/dte/doc/.../pdf",
      "xml": "https://api.lael.cl/v1/dte/doc/.../xml"
    }
  }
}

Verificar la firma HMAC-SHA256

$body   = file_get_contents('php://input');
$secret = 'tu_webhook_secret';
$firma  = 'sha256=' . hash_hmac('sha256', $body, $secret);

if (!hash_equals($firma, $_SERVER['HTTP_X_LAEL_SIGNATURE'])) {
    http_response_code(401);
    exit;
}

$data = json_decode($body, true);
// Procesar $data['evento'], $data['tracking_id'], etc.
const crypto = require('crypto');

app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const firma    = 'sha256=' + crypto
    .createHmac('sha256', process.env.LAEL_WEBHOOK_SECRET)
    .update(req.body)
    .digest('hex');

  if (firma !== req.headers['x-lael-signature']) {
    return res.status(401).send('Unauthorized');
  }

  const data = JSON.parse(req.body);
  console.log(data.evento, data.tracking_id);
  res.sendStatus(200);
});
import hmac, hashlib
from flask import request, abort

SECRET = b'tu_webhook_secret'

@app.route('/webhook', methods=['POST'])
def webhook():
    body      = request.get_data()
    firma     = 'sha256=' + hmac.new(SECRET, body, hashlib.sha256).hexdigest()
    recibida  = request.headers.get('X-Lael-Signature', '')

    if not hmac.compare_digest(firma, recibida):
        abort(401)

    data = request.json
    return '', 200
Si tu endpoint responde con HTTP 2xx, el webhook se marca como exitoso. Si responde con error o no responde en 10 segundos, se reintenta automáticamente: +5 min, luego +30 min. Tras 3 fallos aparece una alerta en tu dashboard.

Manejo de errores

Todas las respuestas de error usan el campo ok: false y error con descripción en español.

{
  "ok":    false,
  "error": "TipoDTE 99 no es soportado. Soportados: 33, 34, 39, 41, 46, 52, 56, 61, 110, 111, 112"
}
HTTPCausa común
400Body malformado o falta JSON
401X-API-Key ausente, inválida o revocada
403Token sandbox intentando acceder a recurso de producción
404tracking_id no encontrado o no pertenece al partner
422Payload válido pero con datos inválidos (RUT, TipoDTE, etc.)
429Rate limit excedido (300 req/min por token)
500Error interno — contáctanos si persiste

Límites y tarifas

Rate limits

LímiteValor
Requests por minuto (por token)300
Body máximo del request5 MB
Reintentos automáticos ante falla SII5 (backoff: 2 min → 15 → 1h → 6h → 12h)

Planes

Free
$0/mes
Para evaluar la integración · válido 1 mes
  • ✓ 50 DTEs en producción
  • ✓ Sandbox SII ilimitado
  • ✓ Todos los tipos de documento
  • ✗ Sin webhooks
  • ✗ Sin renovación automática
Medido
$12.990/mes
Para volúmenes bajos o variables
  • ✓ 100 DTEs incluidos por mes
  • ✓ $20 por DTE adicional
  • ✓ Sandbox SII ilimitado
  • ✓ Todos los tipos de documento
  • ✓ Webhooks incluidos
Ilimitado
$39.990/mes
Para plataformas con alto volumen
  • ✓ DTEs ilimitados
  • ✓ Sin cargos adicionales
  • ✓ Sandbox SII ilimitado
  • ✓ Todos los tipos de documento
  • ✓ Webhooks incluidos

Servicios de Certificación SII (pago único + IVA)

Cuando tu sistema necesita certificarse ante el SII para emitir un tipo de documento, puedes contratar el servicio de certificación con Lael. Realizamos el proceso completo por ti.

Set de CertificaciónTipos DTEPrecio
Boleta Electrónica 39 / 41 $29.990
Factura Afecta + ND + NC 33 / 56 / 61 $39.990
Factura Exenta + ND + NC 34 / 56 / 61 $49.990
Guía de Despacho 52 $59.990
Factura de Compra 46 $69.990
Exportación — Factura + ND + NC 110 / 111 / 112 $79.990
¿Necesitas certificar más de un set? Contáctanos para un presupuesto con descuento por volumen. contacto@lael.cl

Licencias de Software (pago único)

Para integradores que prefieren operar en su propia infraestructura sin suscripción mensual.

API DTE + Folios
$1.990.000 + IVA
$2.368.100 precio final (IVA inc.)
  • ✓ Licencia perpetua por RUT emisor
  • ✓ Emisión de todos los tipos DTE
  • ✓ Gestión de folios CAF incluida
  • ✓ Actualizaciones por 12 meses
  • ✓ 1 hora de onboarding técnico
Certificador DTE
$990.000 + IVA
$1.178.100 precio final (IVA inc.)
  • ✓ Wizard de certificación SII
  • ✓ Todos los sets de certificación
  • ✓ Compatible con API DTE + Folios
  • ✓ Actualizaciones por 12 meses
  • ✓ 1 hora de onboarding técnico
Pack completo (API DTE + Folios + Certificador): precio especial — contáctanos en contacto@lael.cl

SDK PHP

Instala el SDK oficial vía Composer para una integración con tipado fuerte, polling automático y manejo de errores:

composer require lael-cl/sdk
<?php
use LaelCl\Client;
use LaelCl\Dte\FacturaAfecta;
use LaelCl\Dte\NotaCredito;
use LaelCl\Exception\DteRechazadoException;

$lael = new Client('lael_live_xxxxxxxx');

// ─── Emitir factura afecta ───────────────────────────────────────
$factura = FacturaAfecta::make()
    ->emisor('76.123.456-7', 'Mi Empresa SpA')
    ->receptor('12.345.678-9', 'Cliente SA')
    ->agregar('Consultoría', cantidad: 1, precio: 500000)
    ->total(595000, neto: 500000, iva: 95000);

try {
    $r = $lael->dte()->emitir($factura)->esperar(timeoutSeg: 60);

    echo "Folio: "  . $r->folio      . PHP_EOL;
    echo "PDF:   "  . $r->urls->pdf  . PHP_EOL;
    echo "Track: "  . $r->sii->trackId . PHP_EOL;

} catch (DteRechazadoException $e) {
    // SII rechazó el documento
    error_log("DTE rechazado: " . $e->getMessage());
}

// ─── Verificar webhook ────────────────────────────────────────────
use LaelCl\Webhook\WebhookVerifier;

$body  = file_get_contents('php://input');
$firma = $_SERVER['HTTP_X_LAEL_SIGNATURE'];

if (WebhookVerifier::verify($body, $firma, 'mi_secret')) {
    $data = json_decode($body, true);
    // $data['evento'] === 'dte.completado'
}
El SDK PHP está disponible en github.com/lael-cl/sdk-php con documentación completa, tests y ejemplos.

¿Listo para integrar?

Crea tu cuenta, obtén una API Key sandbox y emite tu primer DTE en minutos.

Prueba Lael gratis
14 días · Sin tarjeta
Empezar