Saltar a contenido

Emitir documentos electrónicos

Cómo emitir boletas, facturas, guías de despacho y notas de crédito o débito por API con POST /documento/procesar/json: la API arma y firma el XML del SII, lo guarda y, si corresponde, lo envía al SII automáticamente.

Prerrequisitos: Primeros pasos (credenciales de acceso, sucursal creada y folios CAF cargados).

El flujo en 3 pasos

1. POST /documento/procesar/json      → emite; devuelve folio + token del documento
2. GET  /documento/pdf/{token}        → PDF listo para entregar al cliente
3. GET  /documento/estado/dte/{token} → estado de aceptación en el SII

Folio y terminal: las dos formas de emitir

Todo DTE lleva un folio timbrado por el SII (CAF). Hay dos formas de indicarlo y se elige una por documento:

Folio propio Folio asignado por la API
Qué envías Venta.Folio mayor que 0 Venta.Folio en 0 (u omitido) y CodigoTerminal con el código de una caja
Qué folio se usa El que envías, tal cual El siguiente disponible del rango de folios asignado a esa caja para el tipo de DTE
CodigoTerminal Se ignora: puede ir vacío u omitirse Obligatorio
Venta.CodigoSucursal Obligatorio Se deduce de la caja: puede omitirse
Requisito El folio debe pertenecer a un CAF cargado en OpenTPV y no estar usado La caja debe tener un rango de folios asignado y CAF vigente
Si el folio ya existe Error; no se reintenta con otro La API salta al siguiente folio libre

Usa folio asignado por la API salvo que tu sistema ya administre la numeración. Con folio propio, llevar la secuencia sin saltos ni repetidos es responsabilidad del integrador.

Sin folio y sin terminal la API responde 400 con Debe incluir Folio y/o Codigo de Terminal.

Los ejemplos de esta página usan folio propio. Para que la API asigne el folio cambia dos campos y quita CodigoSucursal:

{
  "TipoDte": 39,
  "CodigoTerminal": "TERM-01",
  "Venta": { "Folio": 0, "...": "resto igual, sin CodigoSucursal" }
}

Estructura del request

Bloque Contenido
TipoDte 33, 34, 39, 41, 52, 56 o 61.
CodigoTerminal Código de la caja, solo cuando la API asigna el folio.
Venta Cabecera: folio, fechas, receptor, montos, pago y sucursal.
DatosVenta Líneas del documento. Al menos una.
Referencias Documentos referenciados. Obligatoria en notas de crédito y débito.
ListaLote Lotes de los productos con control de lote. Opcional.
PagosVenta Medios de pago, para la caja. Opcional.
TransactionId UUID generado por tu sistema. Si reintentas tras un timeout con el mismo valor, la API devuelve la respuesta original en vez de emitir otro folio. Opcional y recomendado.

Campos de Venta, en el orden de los ejemplos:

Grupo Campos Notas
Identificación Folio, FechaEmision, FechaVencimiento FechaEmision es la fecha que lleva el DTE. Envía la fecha real de la operación; si se omite se usa la del servidor.
Receptor IdCliente, Rut, Digito, RazonSocial, Giro, Direccion, Comuna, Ciudad Obligatorio completo en todos los tipos salvo boletas. Rut va sin puntos ni dígito verificador. Ver "Receptor".
Montos SubTotal, Descuento, Neto, TotalExento, PorcentajeIva, Iva, Total Siempre desglosados, en pesos sin decimales.
Pago EstadoPago, Fe_FmaPago, IdCondicionVenta, CondicionVenta, TotalPagado, TotalPendiente Ver "Forma de pago".
Emisor EstadoDocumento, CodigoSucursal, Caja CodigoSucursal es el código que el SII asigna a la sucursal, y la sucursal debe existir en OpenTPV.

Montos de línea: neto o bruto según el tipo

Campo de DatosVenta Factura, guía y notas (33, 34, 52, 56, 61) Boleta (39, 41)
ValorVenta (precio unitario) Neto, sin IVA Bruto, IVA incluido
TotalLinea (monto de la línea) Neto, sin IVA Bruto, IVA incluido

El error clásico es enviar una factura con TotalLinea bruto: la API emite, pero el SII rechaza el documento por descuadre contra el neto. Los totales de la cabecera van desglosados en ambos casos.

Factura, guía o nota con precios brutos. Si tu sistema trabaja las líneas con IVA incluido, agrega "Fe_MntBruto": 1 en Venta. El documento sale con el indicador de montos brutos del SII y las líneas se leen con IVA incluido:

"Venta": { "Fe_MntBruto": 1, "Neto": 10000, "Iva": 1900, "Total": 11900, "...": "resto igual" },
"DatosVenta": [ { "Cantidad": 1, "ValorVenta": 11900, "TotalLinea": 11900, "...": "resto igual" } ]

Tres cosas a tener en cuenta:

  • Lo declara el integrador en cada documento. La API no mira cómo está configurada la empresa en el ERP: sin Fe_MntBruto, las líneas se leen netas.
  • Si lo que declaras no coincide con la configuración de la empresa, el documento se emite igual, como lo enviaste, y la respuesta lo avisa en warning. Si tus precios venían como los declaraste, no hay nada que corregir: el aviso existe para detectar el caso en que se mandaron precios brutos sin declararlo, o al revés.
  • La cabecera no cambia: Neto, Iva y Total van desglosados igual.
  • No sirve en documentos con impuestos adicionales (por ejemplo, alcoholes o bebidas azucaradas): el SII no admite el indicador ahí. Esos documentos deben ir con líneas netas.

Cómo trabaja cada empresa. En el ERP, cada empresa define si digita sus documentos con valores netos o con IVA incluido, tipo por tipo. Puedes consultar esa configuración para guiarte:

curl https://api.opentpv.cl/api/OpcionesGenerales/iva \
  -H "Authorization: Bearer eyJhbGciOi..."
{
  "porcentajeIva": 19,
  "notaVentaConIva": true,
  "boletaConIva": true,
  "guiaConIva": true,
  "facturaConIva": false,
  "notaCreditoConIva": true,
  "notaDebitoConIva": true
}

true significa que la empresa trabaja ese documento con IVA incluido; false, en neto. En el ejemplo, las facturas van en neto y las guías con IVA incluido. Es una referencia, no una obligación: por API puedes emitir en el modo que use tu sistema, siempre que lo declares.

Receptor

Hay dos formas de informar al receptor, y se pueden combinar:

  • Datos en el JSON: Rut, Digito, RazonSocial, Giro, Direccion, Comuna y Ciudad. Lo que envías es lo que sale en el documento.
  • Cliente ya registrado en OpenTPV: envía IdCliente (el código del cliente) o solo su Rut, y la API completa desde la ficha los datos que dejaste vacíos.

Un mismo RUT puede tener varias fichas en OpenTPV (por ejemplo, las sucursales de un cliente, cada una con su domicilio). En ese caso la búsqueda por Rut no completa nada, porque no hay cómo saber cuál corresponde: envía IdCliente o los datos completos.

La ficha nunca reemplaza un dato que venga en el JSON: solo rellena los que faltan. Si el JSON trae un Rut distinto al de la ficha de IdCliente, no se completa nada y el documento sale con los datos enviados.

"Venta": { "Folio": 100, "IdCliente": 8021, "...": "fechas, montos y pago" }

Montos descuadrados

La API no recalcula ni corrige los montos de la cabecera: el documento sale con los que envías. Si neto + exento + IVA + impuestos adicionales no suma el total, se emite igual y la respuesta trae en warning el detalle de la diferencia:

"warning": "Los montos informados no cuadran: neto 10000 + exento 0 + IVA 1900 + impuestos adicionales 0 = 11900, y el total informado es 11950 (diferencia 50). El documento se emitió con esos montos, sin corregir."

Así tu sistema, OpenTPV y el SII quedan con los mismos valores, y se puede emitir el caso legítimo de una nota de crédito que anula un documento que salió descuadrado. Un DTE descuadrado puede ser reparado o rechazado por el SII, así que revisa warning en cada respuesta y trátalo como una incidencia a corregir en el cálculo.

La única excepción es el redondeo: si envías montos con decimales que cuadran antes de redondear, el peso de diferencia que deja el redondeo a pesos enteros se absorbe en el IVA.

Forma de pago

Venta.Fe_FmaPago es la forma de pago del DTE: 1 contado, 2 crédito, 3 sin costo. Si se omite se deriva de EstadoPago: "PENDIENTE" emite crédito y cualquier otro valor, contado. Las boletas no llevan este dato; si lo envías, la respuesta lo avisa en warning.

Un ejemplo por tipo de documento

Factura electrónica (33)

Receptor completo y líneas en neto.

{
  "TipoDte": 33,
  "CodigoTerminal": "",
  "Venta": {
    "Folio": 100,
    "FechaEmision": "2026-08-19T00:00:00",
    "FechaVencimiento": "2026-08-19T00:00:00",
    "Rut": "22222222",
    "Digito": "2",
    "RazonSocial": "Cliente Ejemplo SPA",
    "Giro": "Comercio",
    "Direccion": "Av. Ejemplo 123",
    "Comuna": "Santiago",
    "Ciudad": "Santiago",
    "SubTotal": 10000,
    "Descuento": 0,
    "Neto": 10000,
    "TotalExento": 0,
    "PorcentajeIva": 19,
    "Iva": 1900,
    "Total": 11900,
    "EstadoPago": "PAGADO",
    "Fe_FmaPago": 1,
    "IdCondicionVenta": 1,
    "CondicionVenta": "CONTADO",
    "TotalPagado": 11900,
    "TotalPendiente": 0,
    "EstadoDocumento": "EMITIDA",
    "CodigoSucursal": 81234567,
    "Caja": 1
  },
  "DatosVenta": [
    {
      "Codigo": "PROD001",
      "Descripcion": "Producto de ejemplo",
      "UnidadMedida": "UN",
      "Cantidad": 1,
      "ValorVenta": 10000,
      "Exento": false,
      "NetoLinea": 10000,
      "SubTotalLinea": 10000,
      "TotalLinea": 10000,
      "Bodega": 1,
      "ListaPrecio": 1,
      "Usuario": "API"
    }
  ],
  "Referencias": [],
  "ListaLote": []
}

Factura exenta electrónica (34)

Como la factura, con Neto, PorcentajeIva e Iva en 0, TotalExento igual al total y las líneas con Exento: true.

{
  "TipoDte": 34,
  "CodigoTerminal": "",
  "Venta": {
    "Folio": 100,
    "FechaEmision": "2026-08-19T00:00:00",
    "FechaVencimiento": "2026-08-19T00:00:00",
    "Rut": "22222222",
    "Digito": "2",
    "RazonSocial": "Cliente Ejemplo SPA",
    "Giro": "Comercio",
    "Direccion": "Av. Ejemplo 123",
    "Comuna": "Santiago",
    "Ciudad": "Santiago",
    "SubTotal": 10000,
    "Descuento": 0,
    "Neto": 0,
    "TotalExento": 10000,
    "PorcentajeIva": 0,
    "Iva": 0,
    "Total": 10000,
    "EstadoPago": "PAGADO",
    "Fe_FmaPago": 1,
    "IdCondicionVenta": 1,
    "CondicionVenta": "CONTADO",
    "TotalPagado": 10000,
    "TotalPendiente": 0,
    "EstadoDocumento": "EMITIDA",
    "CodigoSucursal": 81234567,
    "Caja": 1
  },
  "DatosVenta": [
    {
      "Codigo": "PROD001",
      "Descripcion": "Producto de ejemplo",
      "UnidadMedida": "UN",
      "Cantidad": 1,
      "ValorVenta": 10000,
      "Exento": true,
      "NetoLinea": 10000,
      "SubTotalLinea": 10000,
      "TotalLinea": 10000,
      "Bodega": 1,
      "ListaPrecio": 1,
      "Usuario": "API"
    }
  ],
  "Referencias": [],
  "ListaLote": []
}

Boleta electrónica (39)

Líneas en bruto. No lleva Giro ni Fe_FmaPago, y el receptor es opcional: sin receptor la boleta sale a consumidor final.

{
  "TipoDte": 39,
  "CodigoTerminal": "",
  "Venta": {
    "Folio": 500,
    "FechaEmision": "2026-08-19T00:00:00",
    "FechaVencimiento": "2026-08-19T00:00:00",
    "Rut": "22222222",
    "Digito": "2",
    "RazonSocial": "Cliente Ejemplo SPA",
    "Direccion": "Av. Ejemplo 123",
    "Comuna": "Santiago",
    "Ciudad": "Santiago",
    "SubTotal": 11900,
    "Descuento": 0,
    "Neto": 10000,
    "TotalExento": 0,
    "PorcentajeIva": 19,
    "Iva": 1900,
    "Total": 11900,
    "EstadoPago": "PAGADO",
    "IdCondicionVenta": 1,
    "CondicionVenta": "CONTADO",
    "TotalPagado": 11900,
    "TotalPendiente": 0,
    "EstadoDocumento": "EMITIDA",
    "CodigoSucursal": 81234567,
    "Caja": 1
  },
  "DatosVenta": [
    {
      "Codigo": "PROD001",
      "Descripcion": "Producto de ejemplo",
      "UnidadMedida": "UN",
      "Cantidad": 1,
      "ValorVenta": 11900,
      "Exento": false,
      "SubTotalLinea": 11900,
      "TotalLinea": 11900,
      "Bodega": 1,
      "ListaPrecio": 1,
      "Usuario": "API"
    }
  ],
  "Referencias": [],
  "ListaLote": []
}

La misma boleta con folio asignado por la API:

JSON de la boleta con terminal
{
  "TipoDte": 39,
  "CodigoTerminal": "TERM-01",
  "Venta": {
    "Folio": 0,
    "FechaEmision": "2026-08-19T00:00:00",
    "FechaVencimiento": "2026-08-19T00:00:00",
    "Rut": "22222222",
    "Digito": "2",
    "RazonSocial": "Cliente Ejemplo SPA",
    "Direccion": "Av. Ejemplo 123",
    "Comuna": "Santiago",
    "Ciudad": "Santiago",
    "SubTotal": 11900,
    "Descuento": 0,
    "Neto": 10000,
    "TotalExento": 0,
    "PorcentajeIva": 19,
    "Iva": 1900,
    "Total": 11900,
    "EstadoPago": "PAGADO",
    "IdCondicionVenta": 1,
    "CondicionVenta": "CONTADO",
    "TotalPagado": 11900,
    "TotalPendiente": 0,
    "EstadoDocumento": "EMITIDA",
    "Caja": 1
  },
  "DatosVenta": [
    {
      "Codigo": "PROD001",
      "Descripcion": "Producto de ejemplo",
      "UnidadMedida": "UN",
      "Cantidad": 1,
      "ValorVenta": 11900,
      "Exento": false,
      "SubTotalLinea": 11900,
      "TotalLinea": 11900,
      "Bodega": 1,
      "ListaPrecio": 1,
      "Usuario": "API"
    }
  ],
  "Referencias": [],
  "ListaLote": []
}

Boleta exenta electrónica (41)

Como la boleta, con todo el monto en TotalExento.

{
  "TipoDte": 41,
  "CodigoTerminal": "",
  "Venta": {
    "Folio": 500,
    "FechaEmision": "2026-08-19T00:00:00",
    "FechaVencimiento": "2026-08-19T00:00:00",
    "Rut": "22222222",
    "Digito": "2",
    "RazonSocial": "Cliente Ejemplo SPA",
    "Direccion": "Av. Ejemplo 123",
    "Comuna": "Santiago",
    "Ciudad": "Santiago",
    "SubTotal": 10000,
    "Descuento": 0,
    "Neto": 0,
    "TotalExento": 10000,
    "PorcentajeIva": 0,
    "Iva": 0,
    "Total": 10000,
    "EstadoPago": "PAGADO",
    "IdCondicionVenta": 1,
    "CondicionVenta": "CONTADO",
    "TotalPagado": 10000,
    "TotalPendiente": 0,
    "EstadoDocumento": "EMITIDA",
    "CodigoSucursal": 81234567,
    "Caja": 1
  },
  "DatosVenta": [
    {
      "Codigo": "PROD001",
      "Descripcion": "Producto de ejemplo",
      "UnidadMedida": "UN",
      "Cantidad": 1,
      "ValorVenta": 10000,
      "Exento": true,
      "SubTotalLinea": 10000,
      "TotalLinea": 10000,
      "Bodega": 1,
      "ListaPrecio": 1,
      "Usuario": "API"
    }
  ],
  "Referencias": [],
  "ListaLote": []
}

Guía de despacho electrónica (52)

Receptor completo, líneas en neto y los datos del traslado dentro de Venta:

{
  "TipoDte": 52,
  "CodigoTerminal": "",
  "Venta": {
    "Folio": 100,
    "FechaEmision": "2026-08-19T00:00:00",
    "FechaVencimiento": "2026-08-19T00:00:00",
    "Rut": "22222222",
    "Digito": "2",
    "RazonSocial": "Cliente Ejemplo SPA",
    "Giro": "Comercio",
    "Direccion": "Av. Ejemplo 123",
    "Comuna": "Santiago",
    "Ciudad": "Santiago",
    "SubTotal": 10000,
    "Descuento": 0,
    "Neto": 10000,
    "TotalExento": 0,
    "PorcentajeIva": 19,
    "Iva": 1900,
    "Total": 11900,
    "EstadoPago": "PENDIENTE",
    "IdCondicionVenta": 2,
    "CondicionVenta": "CREDITO",
    "TotalPagado": 0,
    "TotalPendiente": 11900,
    "FE_codigoTipoGuia": 1,
    "FE_codigoTrasladadaPor": 2,
    "DireccionDestino": "Camino Ejemplo 456, Bodega 2",
    "ComunaDestino": "Quilicura",
    "CiudadDestino": "Santiago",
    "FechaSalida": "2026-08-19",
    "HoraSalida": "10:30",
    "Patente": "ABCD12",
    "RutTransportista": "77111222-3",
    "RutChofer": "11111111-1",
    "NombreChofer": "Juan Perez",
    "Observaciones": "Inicio de traslado: 2026-08-19 10:30",
    "EstadoDocumento": "EMITIDA",
    "CodigoSucursal": 81234567,
    "Caja": 1
  },
  "DatosVenta": [
    {
      "Codigo": "PROD001",
      "Descripcion": "Producto de ejemplo",
      "UnidadMedida": "UN",
      "Cantidad": 1,
      "ValorVenta": 10000,
      "Exento": false,
      "NetoLinea": 10000,
      "SubTotalLinea": 10000,
      "TotalLinea": 10000,
      "Bodega": 1,
      "ListaPrecio": 1,
      "Usuario": "API"
    }
  ],
  "Referencias": [],
  "ListaLote": []
}
Campo Contenido
FE_codigoTipoGuia Tipo de traslado, de 1 a 8 (1 operación constituye venta, 5 traslado interno, 6 otros traslados no venta...). Por defecto 1.
FE_codigoTrasladadaPor Quién traslada: 1 el receptor, 2 el emisor a instalaciones del cliente, 3 el emisor a otras instalaciones. Por defecto 2.
DireccionDestino, ComunaDestino, CiudadDestino Destino efectivo del traslado.
FechaSalida, HoraSalida, FechaLlegada Inicio y término del traslado (yyyy-MM-dd y HH:mm). Sin FechaLlegada se asume el mismo día de la salida.
Patente, PatenteCarro Vehículo, cuando se conoce.
RutTransportista Con guion y dígito verificador, cuando se conoce.
RutChofer, NombreChofer Siempre juntos. El nombre admite 30 caracteres.
Observaciones La constancia de la hora de inicio del traslado, mientras el SII habilita el campo.

Destino, inicio del traslado y datos de transporte son exigencias de la Res. Ex. SII N°154/2025. En esta ruta la API solo pone por defecto el tipo de traslado y quién traslada: el resto debe informarlo el integrador.

Si la guía nace de un pedido (e-commerce, venta B2B), el flujo recomendado es crear primero la nota de venta y documentarla: el pedido queda trazable, admite un receptor distinto para multi-razón-social y la API completa el destino y las leyendas por defecto. Ver Pedidos con nota de venta.

Nota de crédito electrónica (61)

Las boletas y facturas no se anulan: se revierten con una nota de crédito que referencia al documento original. Lleva el mismo receptor del documento referenciado, las líneas que se revierten y la referencia:

{
  "TipoDte": 61,
  "CodigoTerminal": "",
  "Venta": {
    "Folio": 100,
    "FechaEmision": "2026-08-19T00:00:00",
    "FechaVencimiento": "2026-08-19T00:00:00",
    "Rut": "22222222",
    "Digito": "2",
    "RazonSocial": "Cliente Ejemplo SPA",
    "Giro": "Comercio",
    "Direccion": "Av. Ejemplo 123",
    "Comuna": "Santiago",
    "Ciudad": "Santiago",
    "SubTotal": 10000,
    "Descuento": 0,
    "Neto": 10000,
    "TotalExento": 0,
    "PorcentajeIva": 19,
    "Iva": 1900,
    "Total": 11900,
    "EstadoPago": "PAGADO",
    "Fe_FmaPago": 1,
    "IdCondicionVenta": 1,
    "CondicionVenta": "CONTADO",
    "TotalPagado": 11900,
    "TotalPendiente": 0,
    "EstadoDocumento": "EMITIDA",
    "CodigoSucursal": 81234567,
    "Caja": 1
  },
  "DatosVenta": [
    {
      "Codigo": "PROD001",
      "Descripcion": "Producto de ejemplo",
      "UnidadMedida": "UN",
      "Cantidad": 1,
      "ValorVenta": 10000,
      "Exento": false,
      "NetoLinea": 10000,
      "SubTotalLinea": 10000,
      "TotalLinea": 10000,
      "Bodega": 1,
      "ListaPrecio": 1,
      "Usuario": "API"
    }
  ],
  "Referencias": [
    {
      "TipoDocumento": "33",
      "FolioDocumentoReferencia": "100",
      "FechaDocumentoReferencia": "2026-08-19T00:00:00",
      "TipoAccion": 1,
      "RazonReferencia": "Anula factura 100"
    }
  ],
  "ListaLote": []
}
Campo de Referencias Contenido
TipoDocumento Código del documento referenciado, como texto: "33", "34", "39", "52"...
FolioDocumentoReferencia Folio del documento referenciado, como texto.
FechaDocumentoReferencia Fecha de emisión del documento referenciado.
TipoAccion 1 anula el documento completo, 2 corrige texto, 3 corrige montos.
RazonReferencia Glosa libre que explica la nota.

La nota de crédito repone el stock que el documento referenciado descontó. Hereda su comportamiento: si el original se emitió sin descontar inventario, la nota no repone nada.

Una nota de crédito a una boleta se arma igual, con "TipoDocumento": "39". A diferencia de la boleta, la nota exige el receptor completo y sus líneas van en neto.

Nota de débito electrónica (56)

Como la nota de crédito. Lo habitual es TipoAccion 3 con una línea por el cargo adicional, o TipoAccion 1 para dejar sin efecto una nota de crédito.

{
  "TipoDte": 56,
  "CodigoTerminal": "",
  "Venta": {
    "Folio": 100,
    "FechaEmision": "2026-08-19T00:00:00",
    "FechaVencimiento": "2026-08-19T00:00:00",
    "Rut": "22222222",
    "Digito": "2",
    "RazonSocial": "Cliente Ejemplo SPA",
    "Giro": "Comercio",
    "Direccion": "Av. Ejemplo 123",
    "Comuna": "Santiago",
    "Ciudad": "Santiago",
    "SubTotal": 1000,
    "Descuento": 0,
    "Neto": 1000,
    "TotalExento": 0,
    "PorcentajeIva": 19,
    "Iva": 190,
    "Total": 1190,
    "EstadoPago": "PENDIENTE",
    "IdCondicionVenta": 2,
    "CondicionVenta": "CREDITO",
    "TotalPagado": 0,
    "TotalPendiente": 1190,
    "EstadoDocumento": "EMITIDA",
    "CodigoSucursal": 81234567,
    "Caja": 1
  },
  "DatosVenta": [
    {
      "Codigo": "PROD001",
      "Descripcion": "Intereses por mora",
      "UnidadMedida": "UN",
      "Cantidad": 1,
      "ValorVenta": 1000,
      "Exento": false,
      "NetoLinea": 1000,
      "SubTotalLinea": 1000,
      "TotalLinea": 1000,
      "Bodega": 1,
      "ListaPrecio": 1,
      "Usuario": "API"
    }
  ],
  "Referencias": [
    {
      "TipoDocumento": "33",
      "FolioDocumentoReferencia": "100",
      "FechaDocumentoReferencia": "2026-08-19T00:00:00",
      "TipoAccion": 3,
      "RazonReferencia": "Cobro de intereses factura 100"
    }
  ],
  "ListaLote": []
}

Qué respeta la API y qué resuelve por su cuenta

La regla general es que el documento sale con lo que envía el integrador: folio, fecha de emisión, receptor, montos, líneas y referencias se usan tal cual, sin recalcular. Las excepciones son estas:

Dato Qué hace la API
Emisor (razón social, giro, actividad económica, dirección de origen) Sale siempre de la configuración de la empresa y de la sucursal. Los bloques Emisor y Sucursal del JSON se ignoran.
Venta.CodigoSucursal Con folio asignado por la API se reemplaza por la sucursal de la caja.
Datos del receptor que no vienen Se completan desde la ficha del cliente, ubicada por IdCliente o por Rut (solo si ese RUT tiene una única ficha). Los que sí vienen se respetan.
Montos con decimales Se redondean a pesos enteros. Si cuadraban antes de redondear, el peso de diferencia que deja el redondeo se absorbe en el IVA. Los montos que no cuadran de origen no se corrigen (ver "Montos descuadrados").
EstadoPago, TotalPagado, TotalPendiente Si el request trae PagosVenta, se recalculan con la suma de los pagos.
DatosVenta[].DescuentaInventario Se ignora. Si la emisión mueve stock lo decide la configuración de la empresa (ver Primeros pasos).
DatosVenta[].Bodega Si falta o no es válida se usa la primera bodega válida del documento y, si ninguna línea la trae, la 1.
Venta.Fe_FmaPago en boletas Se ignora: la boleta no lleva forma de pago. La respuesta lo avisa en warning.
Receptor de una boleta sin datos Sale a consumidor final (RUT 66666666-6) con textos genéricos.
Textos largos Se cortan al largo que admite el SII: razón social 99 caracteres, giro 39, nombre del chofer 30.

Respuesta

{
  "success": true,
  "message": "Venta JSON procesada exitosamente. DTE 33 folio 100",
  "data": {
    "folio": 100,
    "token": "a1b2c3d4...",
    "xml":    "https://api.opentpv.cl/documento/xml/a1b2c3d4...",
    "pdf":    "https://api.opentpv.cl/documento/pdf/a1b2c3d4...",
    "timbre": "https://api.opentpv.cl/documento/timbre/a1b2c3d4...",
    "logo":   "https://api.opentpv.cl/documento/logo/a1b2c3d4...",
    "warning": ""
  }
}

Guarda data.token: es la llave para PDF, XML, timbre y estado del documento. data.folio es el folio emitido, útil sobre todo cuando lo asignó la API.

Un error llega con success en false, el título en message y el detalle en errors:

{
  "success": false,
  "message": "Sin FOLIOS",
  "errors": ["No hay folios asignados, debe asignar folios a la caja."]
}

La emisión es todo o nada: si algo falla antes de firmar, el documento se revierte completo y el folio queda disponible para el reintento.

Obtener el PDF y verificar el estado

# PDF carta                          # PDF 80mm (impresora térmica)
GET /documento/pdf/{token}           GET /documento/pdf/80/{token}
# PDF cedible (para factoring)       # XML firmado
GET /documento/pdf/cedible/{token}   GET /documento/xml/{token}

# Estado del DTE ante el SII (aceptado / reparo / rechazo)
GET /documento/estado/dte/{token}

# Reenviar al SII si el envío automático está apagado o falló
POST /documento/enviar/sii/{token}

El envío automático al SII depende de la configuración del documento en la empresa (ERP → Opciones → Documentos, fila E-FACTURA: "Envío automático SII").

Errores típicos

Error Qué significa
Debe incluir Folio y/o Codigo de Terminal El request no trae folio ni terminal.
Sin FOLIOS La caja indicada no tiene un rango de folios asignado para ese tipo de DTE.
Sin CAF No hay CAF cargado que cubra el folio siguiente: hay que solicitar folios al SII y cargarlos.
CAF Vencido El CAF de facturas y notas vence a los 6 meses de autorizado.
Folio ya utilizado Con folio propio, el folio ya fue usado en otro documento del mismo tipo.
No se encuentra el archivo CAF del folio N Con folio propio, el folio no pertenece a ningún CAF cargado.
No se encuentra la sucursal del emisor CodigoSucursal no corresponde a una sucursal creada en OpenTPV.
No se encuentra el giro (la dirección, la comuna...) del cliente Falta un dato del receptor en un documento que lo exige completo.
Forma de pago inválida Fe_FmaPago distinto de 1, 2 o 3.
Venta en proceso (409) Ya hay una emisión en curso con el mismo TransactionId.
Documento emitido pero rechazado por el SII Revisar estado/dte/{token}; lo más común es una factura con líneas en bruto. Se corrige con nota de crédito.