Boletas 39 y 41
Emite boletas electrónicas afectas 39 y exentas 41 en E-Boleta del SII por REST, MCP o SDK, paso a paso, y encuentra la boleta emitida en el SII.
Connect emite boletas en E-Boleta, el sistema gratuito de boletas del SII, a nombre de la empresa de una conexión. Admite la boleta afecta 39 y la exenta 41, con una línea, cantidad uno y un total entero en pesos. Tu software o tu agente prepara la boleta, revisa la vista previa y la emite: la respuesta trae el folio.
No hay ambiente de prueba
E-Boleta no tiene ambiente de certificación: toda boleta que emites es real, consume folio y le llega al SII. Connect todavía no anula boletas. Revisa la vista previa antes de emitir.
Los datos de los ejemplos son ficticios. No los envíes.
Qué necesitas
- Las boletas habilitadas para tu organización. Las activa el equipo de Emisso, por organización: pídeselo por soporte.
- La empresa con E-Boleta habilitado en el SII para el tipo que vas a emitir (39, 41 o ambos). Si la empresa no puede emitir ese tipo en eboleta.sii.cl, Connect tampoco.
- Una conexión SII de representante. En Conexiones, al conectar la empresa elige Entro como representante: el RUT y la clave tributaria de una persona que la representa, más el RUT de la empresa. Una conexión creada con la clave de la empresa no emite boletas.
- Las boletas activas en esa conexión. Al conectar, marca Emitir documentos en el SII: esa
casilla autoriza también las boletas, sin un segundo interruptor. Si no ves la casilla, o la conexión ya
existe, pide a soporte que encienda las boletas en esa conexión y entrégale su identificador (
conn_…). - Una clave de API con el permiso
sii:boletas:write, o un agente conectado por MCP con ese permiso.sii:writeno lo sustituye. Las claves no se editan: si la tuya no lo tiene, crea otra en API keys.
E-Boleta no pide la clave del certificado digital: Connect entra con la clave tributaria de la conexión, la resuelve en el servidor y nunca la pone en tus llamadas, en los resultados ni en los logs. No se la entregues a tu agente.
La boleta siempre sale a nombre de la empresa de la conexión, aunque la persona represente a varias. El selector de empresa de eboleta.sii.cl es solo del navegador y no cambia lo que emite Connect: para emitir por otra empresa, conéctala aparte.
1. Previsualiza la boleta
sii.boleta.previsualizar entra a E-Boleta con la credencial de la conexión, comprueba la boleta contra la
configuración de la empresa y devuelve un previewRef, sin emitir nada:
curl -X POST https://connect.emisso.ai/api/v1/tools/sii.boleta.previsualizar/execute \
-H "Authorization: Bearer connect_sk_…" \
-H "X-Connect-Connection: conn_9tKfR2mQx4Vb" \
-H "Content-Type: application/json" \
-d '{
"input": {
"candidato": {
"tipoDte": "39",
"montoTotal": 25000,
"detalle": "Mantención de jardín - Av. Los Aromos 1234",
"medioPagoCodigo": "TRANSFERENCIA"
}
}
}'Salida esperada (200, campo data):
{
"candidato": {
"tipoDte": "39",
"montoTotal": 25000,
"detalle": "Mantención de jardín - Av. Los Aromos 1234",
"medioPagoCodigo": "TRANSFERENCIA"
},
"totales": { "total": 25000 },
"advertencias": ["receptor_no_informado"],
"previewRef": "<referencia opaca>"
}La vista previa no escribe en el SII. El previewRef vence en 15 minutos y solo lo emite la misma clave de
API (o la misma persona) en la misma conexión. Si cambias algún dato, previsualiza de nuevo.
La primera vista previa de una conexión guarda la sucursal de la empresa cuando E-Boleta muestra una sola.
Si la empresa tiene varias, la vista previa falla con sii_eboleta_sucursal_ambigua y soporte te ayuda a
elegir.
2. Emite la boleta
Genera una clave de idempotencia (UUID v4), guárdala junto a la boleta en tu sistema antes de llamar y
envía el previewRef a sii.boleta.emitir:
curl -X POST https://connect.emisso.ai/api/v1/tools/sii.boleta.emitir/execute \
-H "Authorization: Bearer connect_sk_…" \
-H "X-Connect-Connection: conn_9tKfR2mQx4Vb" \
-H "Idempotency-Key: 7c1e4b9a-2f6d-4e8b-a3c5-0d9f1b2e6a47" \
-H "Content-Type: application/json" \
-d '{"input": {"previewRef": "<referencia opaca>"}}'Salida esperada (200, recortada):
{
"data": {
"resultado": {
"estado": "emitida",
"tipoDte": "39",
"folio": "1287",
"puedeReintentar": false
}
},
"meta": {
"tool_id": "sii.boleta.emitir",
"request_id": "b52d8e10-4c3a-4f7e-9a61-2e8c0f5d7b93",
"operation_request_id": "b52d8e10-4c3a-4f7e-9a61-2e8c0f5d7b93"
}
}Guarda folio y meta.operation_request_id, el identificador que Connect le asigna a la emisión y que
no cambia al repetir la llamada.
Nadie confirma boleta por boleta: quien preparó la boleta la confirma al emitirla, y la autorización se dio al activar las boletas en la conexión. La llamada tarda algunos segundos, porque Connect vuelve a entrar a E-Boleta, comprueba que la boleta sigue siendo la que previsualizaste y espera el folio. No la cortes con un timeout corto; si se corta, repítela con la misma clave.
Por MCP
Un agente conectado al servidor MCP hace las mismas dos llamadas. La vista previa no
escribe, así que va por execute, y params lleva lo mismo que el input de REST:
{
"tool": "sii.boleta.previsualizar",
"connectionId": "conn_9tKfR2mQx4Vb",
"params": {
"candidato": {
"tipoDte": "39",
"montoTotal": 25000,
"detalle": "Mantención de jardín - Av. Los Aromos 1234",
"medioPagoCodigo": "TRANSFERENCIA"
}
}
}La emisión escribe, así que va por execute_write, con la clave de idempotencia como argumento, fuera de
params:
{
"tool": "sii.boleta.emitir",
"connectionId": "conn_9tKfR2mQx4Vb",
"idempotencyKey": "7c1e4b9a-2f6d-4e8b-a3c5-0d9f1b2e6a47",
"params": { "previewRef": "<referencia opaca>" }
}La UUID del ejemplo solo ilustra el formato: genera una propia por boleta.
Por SDK
import { createClient } from "@emisso/connect";
const connect = createClient({ apiKey: process.env.EMISSO_CONNECT_API_KEY! });
const connectionId = "conn_9tKfR2mQx4Vb";
const vista = await connect.tools.sii.boleta.previsualizar(
{ candidato: { tipoDte: "39", montoTotal: 25000, detalle: "Mantención de jardín" } },
{ connectionId },
);
// Guarda la clave junto a la boleta ANTES de emitir: es lo que permite consultar sin reenviar.
const idempotencyKey = crypto.randomUUID();
const { data, meta } = await connect.tools.sii.boleta.emitir.withResponse(
{ previewRef: vista.previewRef },
{ connectionId, idempotencyKey },
);
// Conserva data.resultado.folio y meta?.operation_request_id.La versión 0.1.0 publicada en npm no incluye sii.boleta ni idempotencyKey. Revisa
qué versión tienes; con la 0.1.0, emite por REST.
El candidato, campo por campo
| Campo | Qué va |
|---|---|
tipoDte | "39" para la boleta afecta o "41" para la exenta. |
montoTotal | El total de la boleta en pesos, entero y positivo. En la 39 incluye el IVA. |
detalle | Opcional: la descripción de la única línea, hasta 80 caracteres. Sin ella, la línea dice «Monto Total». |
medioPagoCodigo | Opcional: EFECTIVO, PAGO_ELECTRONICO, TRANSFERENCIA, CHEQUE u OTRO. |
receptor | Opcional. Ver abajo. |
No envíes neto ni IVA: en la 39, E-Boleta los calcula a partir del total. Una boleta de $25.000 queda con $21.008 de neto y $3.992 de IVA. La 41 es exenta y no lleva IVA. La vista previa devuelve solo el total.
Los medios de pago son los que muestra hoy el catálogo de E-Boleta, y Connect contrasta el código con ese
catálogo en cada vista previa. Sin medioPagoCodigo, la vista previa advierte medio_pago_no_informado.
La boleta no lleva fecha, folio, varias líneas, cantidades, referencias ni descuentos: la fecha y el folio los pone E-Boleta al emitir.
Receptor
Sin receptor, la boleta va al consumidor final genérico del SII y la vista previa advierte
receptor_no_informado. Para identificar a quien compra:
| Campo | Qué va |
|---|---|
receptor.rut | RUT sin puntos, con guion y dígito verificador válido. |
receptor.razonSocial | Nombre o razón social, hasta 100 caracteres. |
receptor.direccion | Hasta 200 caracteres. |
receptor.correo | Opcional. |
receptor.telefono | Opcional: dígitos y espacios, con + inicial si quieres. |
{
"tipoDte": "39",
"montoTotal": 25000,
"detalle": "Mantención de jardín",
"receptor": {
"rut": "77123456-9",
"razonSocial": "Comercial Los Aromos SpA",
"direccion": "Av. Providencia 1234, Providencia",
"correo": "pagos@ejemplo.cl"
}
}Cada empresa tiene reglas propias en E-Boleta: sobre cierto monto o con cierto medio de pago puede exigir detalle, medio de pago o receptor completo (con correo y teléfono). Connect las lee en cada vista previa y rechaza la boleta antes de enviarla si falta algo.
Resultados
sii.boleta.emitir devuelve un resultado con uno de tres estados. puedeReintentar siempre es false:
nunca autoriza a preparar otra boleta para lo mismo.
| Estado | Qué significa | Qué hacer |
|---|---|---|
emitida | E-Boleta devolvió el folio, o la reconciliación lo confirmó. Trae folio. | Guarda folio y operation_request_id. |
rechazada | La boleta no se emitió, de forma concluyente, y no consumió folio. | Corrige la causa y prepara una vista previa nueva. |
resultado_desconocido | La boleta pudo salir hacia E-Boleta, pero Connect todavía no puede afirmar si se emitió. | No prepares otra. Repite la misma llamada, como se explica abajo. |
Resultado desconocido
Connect guarda la operación antes de un único envío a E-Boleta. Si la respuesta se pierde (un corte, un
timeout), recibes resultado_desconocido con siguientePaso: "reconciliacion_automatica_o_soporte".
Mientras tanto, la reconciliación automática busca la boleta en los reportes de E-Boleta de la empresa.
- No crees otra clave de idempotencia ni otra vista previa. Una clave nueva puede emitir una segunda boleta.
- Repite la misma llamada con la misma clave. No reenvía nada: devuelve el estado guardado de la
operación, con
meta.idempotencyenreplayed. Funciona aunque elpreviewRefya haya vencido. - Si sigue desconocido, entrega a soporte el
operation_request_id.
No compartas con soporte cuerpos completos, credenciales ni el previewRef.
Errores frecuentes
Estos errores llegan antes de que la boleta salga hacia E-Boleta: la boleta no se envió. Cuando el código
es upstream_unexpected_response, el campo message del error dice cuál es el caso y suggested_fix, qué
corregir.
Código o message | Cuándo | Qué hacer |
|---|---|---|
scope_not_granted | La clave de API no tiene sii:boletas:write. | Crea una clave con ese permiso. |
connection_scope_not_enabled | Las boletas no están encendidas en esa conexión. | Pide a soporte que las encienda. Cambiar la clave de API no lo resuelve. |
connector_onboarding_required | La conexión tiene las boletas encendidas, pero la organización no está habilitada o la conexión no es de representante. | Revisa qué necesitas y escribe a soporte. |
sii_eboleta_tipo_no_habilitado | La empresa no tiene ese tipo de boleta habilitado en E-Boleta con este acceso. | Habilítalo en el SII o emite el otro tipo. |
sii_eboleta_sucursal_ambigua | La empresa tiene más de una sucursal en E-Boleta. | Escribe a soporte con el identificador de la conexión. |
sii_eboleta_medio_pago_invalido | El medioPagoCodigo no está en el catálogo de E-Boleta. | Usa uno de los códigos de la tabla del candidato. |
sii_eboleta_detalle_requerido, sii_eboleta_medio_pago_requerido o sii_eboleta_receptor_completo_requerido | Las reglas de la empresa en E-Boleta exigen ese dato para ese monto o medio de pago. | Agrega el dato y previsualiza de nuevo. |
sii_eboleta_monto_supera_limite_beta | El total alcanza el máximo que E-Boleta admite para una boleta. | Revisa el monto. |
sii_eboleta_reference_expired | Pasaron más de 15 minutos desde la vista previa. | Previsualiza de nuevo. |
sii_eboleta_reference_invalid | El previewRef ya se usó, es de otra conexión o lo emite otro actor. | Previsualiza de nuevo con la misma clave de API con la que vas a emitir. |
sii_eboleta_preparacion_cambio | Al emitir, los datos o las reglas de E-Boleta ya no coinciden con la vista previa. | Revisa una vista previa nueva antes de emitir. |
connection_busy | Hay otra operación en curso en la misma conexión. | Espera unos segundos y reintenta con la misma clave de idempotencia. |
idempotency_in_progress | Otro intento con esa misma clave sigue corriendo. | Espera y repite con la misma clave. |
idempotency_conflict | Usaste la misma clave con otro previewRef. | Cada boleta lleva su propia clave. |
El catálogo completo está en la referencia de errores.
Ver la boleta emitida
- En Connect: en Conexiones, abre la conexión y entra a Datos → Emisión: las boletas emitidas desde esa conexión aparecen en su propia sección. Cada llamada queda además en la bitácora de la organización.
- En el SII: entra a eboleta.sii.cl con la clave tributaria de la persona, elige la empresa en el selector, abre Reportes, busca la boleta por su folio y usa Ver PDF. Connect no devuelve el PDF.
Desactivar
Soporte apaga las boletas de una conexión o la emisión de boletas de toda la organización. Eliminar la conexión también impide boletas nuevas. Nada de eso borra la auditoría: una operación ya iniciada conserva su identidad y se sigue consultando con su misma clave.
La referencia completa del contrato está en
sii.boleta.previsualizar y
sii.boleta.emitir.
Facturas 33 y 34
Emite una factura afecta 33 o exenta 34 ante el SII con una a diez líneas y hasta tres referencias, por REST, MCP o SDK, paso a paso.
Anular una factura
Anula una factura afecta 33 emitida con el Facturador Gratuito del SII emitiendo su nota de crédito 61 de anulación, por REST, MCP o SDK. El SII arma la nota completa.