Facturiadocs
Emisión

Crear documentos

La emisión mínima, la emisión completa, qué completamos por ti y cómo leer los documentos que ya emitiste.

La emisión mínima

El punto de guardar el perfil emisor en la empresa es que una factura son tres campos.

curl -sS https://api.facturia.cl/v1/documents \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Facturia-Empresa: $EMPRESA" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "tipo_dte": 33,
    "receptor": { "rut": "76543212-K" },
    "items": [
      { "description": "Desarrollo a medida — agosto", "quantity": 1, "unit_price": 2400000 }
    ]
  }'

Qué completamos por ti

CampoDe dónde sale
Bloque emisor (RUT, razón social, giro, dirección, comuna, acteco)el perfil de la empresa
folioel siguiente folio del CAF activo para este tipo
issue_datehoy en America/Santiago
Razón social, giro, dirección y comuna del receptorla libreta de direcciones de la empresa, si no el registro de contribuyentes del SII, resuelto por RUT
totalscalculados desde items bajo las reglas tributarias del tipo
payment_terms, currency, indicatorsvalores por defecto sensatos (contado, CLP)

Si el receptor no se puede resolver y el tipo requiere esos campos, recibes 400 receptor_incomplete nombrando exactamente cuáles enviar — nunca un rechazo silencioso del SII tres minutos después.

La emisión completa

Todo lo que el SII te deja decir, dicho explícitamente.

curl -sS https://api.facturia.cl/v1/documents \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Facturia-Empresa: $EMPRESA" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "tipo_dte": 33,
    "external_id": "order-8842",
    "issue_date": "2026-08-14",
    "prices_include_tax": false,
    "receptor": {
      "rut": "76543212-K",
      "legal_name": "Comercial Andina Ltda.",
      "giro": "Venta al por mayor de alimentos",
      "address": { "street": "Los Militares 5001, of. 302", "comuna": "Las Condes", "city": "Santiago" },
      "contact": "[email protected]",
      "email_document_to": ["[email protected]", "[email protected]"]
    },
    "items": [
      {
        "description": "Licencia plataforma — plan Enterprise",
        "detail": "Periodo 2026-08-01 a 2026-08-31",
        "quantity": 12, "unit": "UN", "unit_price": 180000,
        "discount_percent": 5,
        "item_code": { "type": "INT1", "value": "PLAT-ENT" }
      },
      { "description": "Servicio exento de capacitación", "quantity": 1, "unit_price": 300000, "exempt": true }
    ],
    "global_discounts": [ { "type": "percent", "value": 2, "applies_to": "afecto", "reason": "Acuerdo comercial" } ],
    "references": [
      { "tipo_dte": 801, "folio": "OC-99213", "date": "2026-08-01", "code": null, "reason": "Orden de compra" }
    ],
    "payment": { "terms": "credito", "due_date": "2026-09-13", "method": "transferencia" },
    "totals": { "net": 2352000, "iva": 446880, "exempt": 300000, "total": 3098880 },
    "pdf": { "format": "carta", "cedible": true, "public": true },
    "xml": { "public": true },
    "notes": "Gracias por su compra.",
    "metadata": { "crm_deal": "D-1182", "cost_center": "LATAM" }
  }'

Los cuatro campos que conviene entender

Trampa

prices_include_tax es el origen del bug del 19%

Por defecto depende del tipo: true para boletas (39/41), false para todo lo demás. Ponlo explícito y normalizamos en cualquier dirección.

Es la fuente número uno de errores de 19% en la facturación chilena. Que sea un campo con nombre en vez de una convención implícita es deliberado: si tu sistema guarda precios brutos y emites una factura, dilo.

  • totals es opcional y, cuando viene, es una aserción. Si nuestro cálculo difiere aunque sea en un peso, recibes 422 totals_mismatch con ambas cifras y no se emite nada. Un sistema financiero debería mandarlo siempre.
  • references con code: 1|2|3 son los códigos de referencia del SII (1 = anula el documento referenciado, 2 = corrige texto, 3 = corrige montos). Las referencias a documentos que no son DTE (orden de compra, contrato) usan los códigos de tipo_dte del SII en el rango 800 y omiten code.
  • metadata es un mapa de strings arbitrario (≤ 20 llaves, ≤ 500 caracteres cada una) que guardamos y devolvemos intacto. Nunca llega al SII.
  • email_document_to envía el PDF y el XML al receptor cuando el documento llega a accepted.

El objeto documento

{
  "id": "doc_01K2R7Q4XW9M3B8ZC5YHTVJD6N",
  "object": "document",
  "mode": "live",
  "empresa": { "id": "emp_01K2R6ZC4P8QW1VN7T3MHDY9EK", "rut": "77928532-4" },
  "external_id": "order-8842",
  "tipo_dte": 33,
  "folio": 412,
  "issue_date": "2026-08-14",
  "status": "accepted",
  "receptor": { "rut": "76543212-K", "legal_name": "Comercial Andina Ltda." },
  "items": [ { "description": "Licencia plataforma — plan Enterprise", "quantity": 12, "unit_price": 180000, "amount": 2052000 } ],
  "totals": { "net": 2352000, "iva": 446880, "exempt": 300000, "other_taxes": 0, "total": 3098880 },
  "references": [],
  "pdf_url": "https://api.facturia.cl/v1/documents/doc_01K2R7Q4XW9M3B8ZC5YHTVJD6N/pdf",
  "xml_url": "https://api.facturia.cl/v1/documents/doc_01K2R7Q4XW9M3B8ZC5YHTVJD6N/xml",
  "pdf_public_url": "https://ver.facturia.cl/d/8f2c1a9e4b",
  "xml_public_url": "https://ver.facturia.cl/d/8f2c1a9e4b.xml",
  "sii": {
    "environment": "produccion",
    "track_id": "0252083112",
    "estado": "DOK",
    "glosa": "Documento Recibido por el SII, datos coinciden",
    "err_code": "0",
    "num_atencion": "8812394",
    "received_at": "2026-08-14T13:06:55Z",
    "last_checked_at": "2026-08-14T13:07:02Z"
  },
  "rejection_reasons": [],
  "metadata": { "crm_deal": "D-1182" },
  "created_at": "2026-08-14T13:04:11Z",
  "accepted_at": "2026-08-14T13:06:55Z"
}

Leer documentos

# Listar, del más nuevo al más antiguo, con filtros
curl -G https://api.facturia.cl/v1/documents \
  -H "Authorization: Bearer $FACTURIA_KEY" -H "Facturia-Empresa: $EMPRESA" \
  -d status=accepted -d tipo_dte=33 \
  -d "issue_date[gte]=2026-08-01" -d "issue_date[lte]=2026-08-31" \
  -d limit=50

# Un documento
curl https://api.facturia.cl/v1/documents/doc_01K2R7Q4XW9M3B8ZC5YHTVJD6N \
  -H "Authorization: Bearer $FACTURIA_KEY" -H "Facturia-Empresa: $EMPRESA"

# Por folio (los folios son únicos por empresa+tipo, así que es una búsqueda legítima)
curl -G https://api.facturia.cl/v1/documents \
  -H "Authorization: Bearer $FACTURIA_KEY" -H "Facturia-Empresa: $EMPRESA" \
  -d tipo_dte=33 -d folio=412

Filtros: status, tipo_dte, folio, receptor_rut, external_id, issue_date[gte|lte], created_at[gte|lte]. El mode es implícito de la llave.

Un status no reconocido devuelve 400 invalid_field nombrando los siete valores válidos — una página vacía se leería como «no tienes ninguno de esos», que es una respuesta distinta y mucho más confusa.

Cada filtro, status incluido, se aplica en la consulta. Una página filtrada es una página completa, y has_more / next_cursor significan lo que dicen: pagina hasta que has_more sea false y tienes el conjunto entero.

Expansión

Los documentos devuelven pdf_url y xml_url por defecto. Para evitar una segunda vuelta:

curl "https://api.facturia.cl/v1/documents/doc_01K2R7Q4XW9M3B8ZC5YHTVJD6N?expand=xml,pdf_base64,events" \
  -H "Authorization: Bearer $FACTURIA_KEY" -H "Facturia-Empresa: $EMPRESA"

expand acepta una lista separada por comas: xml (string en línea), pdf_base64, events, references, received_document (en documentos emitidos en respuesta a uno recibido).

En esta página