Facturador Pulsando — API de Facturación Electrónica SII (1.5.0)

Download OpenAPI specification:

Contacto Facturador Pulsando: contacto@pulsandotech.cl License: Propietario

API REST para emitir y consultar Documentos Tributarios Electrónicos (DTE) chilenos a través del SII: facturas, boletas, notas de crédito/débito y guías de despacho. Está pensada para integradores: tu ERP o sistema llama esta API y nosotros nos encargamos de folios (CAF), firma XMLDSig, timbre, envío al SII y la representación impresa (PDF).

Base URL: https://{host}/api/public/v1 (canal API Key). Antes de integrar, revisa la sección Guía de la barra lateral —empieza por Onboarding y requisitos del emisor y Autenticación—; la Referencia de la API documenta cada endpoint.

Onboarding y requisitos del emisor

Antes de emitir, cada centro debe estar habilitado como emisor electrónico ante el SII. Es un trámite del contribuyente (no del software) y depende de su situación tributaria:

  • Inicio de actividades vigente en el SII (primera categoría, afecto a IVA).
  • Certificado digital propio (.p12) del representante legal — con él se firman sus DTE. Es obligatorio e intransferible entre empresas.
  • Habilitación como emisor de DTE ante el SII, con los usuarios autorizados para firmar y enviar documentos.

Según el historial del centro:

Situación del centro Qué corresponde
Nunca emitió DTE Postular, obtener la verificación de actividades y aprobar el set de pruebas de certificación (ambiente maullin) antes de pasar a producción.
Ya emite con otro proveedor Solo migra: carga su certificado y solicita CAF nuevos. No recertifica.
Usa el sistema gratuito del SII (tipo 890) Primero debe desvincularse de ese sistema ante el SII.

La carga del certificado y de los CAF (folios) se realiza una sola vez por centro desde el portal web (no por esta API). Esta API es para emitir y consultar: una vez que el centro está habilitado y cuenta con folios, tu integración puede emitir y consultar sin restricciones.

Puesta en marcha asistida (servicio Pulsando). Dejamos a cada centro listo para emitir —acompañamiento en la postulación/certificación ante el SII y carga inicial de certificado y folios— como un servicio de onboarding. Escríbenos a contacto@pulsandotech.cl para coordinarlo.

Dar de alta una empresa

Crea la cuenta de una empresa y devuelve su primera API Key de pruebas. No requiere autenticación: es por donde se empieza.

Existía desde el principio pero no estaba documentado, así que la única vía conocida era el formulario del portal. Con esto un partner o un ERP puede dar de alta a su cliente sin que nadie abra un navegador.

La api_key de la respuesta se muestra UNA sola vez. En la base queda solo su hash: si no la guardas en ese momento, no hay forma de recuperarla y hay que emitir otra desde el portal.

Es la llave de certificación de esta empresa (sk_test_…; el ambiente lo confirma cada respuesta en ambiente y livemode, no el prefijo). Sirve para emitir ante el ambiente de certificación del SII cuando la empresa activa su plan Profesional o superior, pagado: la prueba no cuenta, y sin eso no hay folios de certificación (la emisión responde 422 con codigo: puerta_sii_cerrada). Lo que le falta lo dice GET /que-me-falta. Mientras, el contenido se valida sin llave con POST /sandbox/dte. La llave del ambiente de desarrollo (documentos simulados, sin certificado ni folios) es otra: llega por correo cuando la persona confirma su cuenta. Lo que le falta a la empresa lo dicen los proximos_pasos de esta misma llamada.

Lo mínimo para crear la cuenta (desde el 11-oct-2026): RUT y DV, el administrador (admin_name, admin_email, admin_password), el contacto (telefono, direccion, comuna, ciudad) y los tres consentimientos. Lo demás es opcional y se completa después desde el panel:

  • razon_social: si no la mandas, se toma del SII (la consulta de validar-rut o el STC público). Si el SII no la da, responde 422 con errors.razon_social.
  • giro: sale del SII. Si el SII no lo da, la empresa se crea igual pero no puede emitir hasta completarlo (422 con codigo: datos_emisor_incompletos en POST /dte).
  • email (correo de contacto de la empresa): por defecto, admin_email.
  • plan_id: sin él la empresa empieza en el plan gratuito (nunca en uno de pago) y la respuesta trae plan_por_elegir: true.
  • tipo_onboarding: se toma del SII.

De dónde viene tu cliente (tipo_onboarding) cambia el trámite. Son cuatro casos —nueva, migracion, en_certificacion y portal_gratuito—. Si no lo mandas, manda lo que diga el SII; si el SII todavía no contestó, queda nueva por defecto (no como declarado) y se corrige solo cuando el SII contesta. Si lo mandas, se guarda como declarado al lado de lo que verifique el SII, y para el trámite manda lo verificado.

Para saberlo antes, llama a POST /registro/validar-rut. Es asíncrona (el SII tarda) y nunca bloquea el alta: puedes registrar igual sin esperarla.

Los folios del que migra (migracion) son de su RUT, no de su proveedor: con el plan pagado y su autorización (mandato) traemos desde el SII los que sigan vigentes y seguimos su numeración desde el último que usó, que leemos en el SII. Los de factura afecta, factura de compra, liquidación-factura y notas de crédito y débito vencen a los 6 meses de autorizados (Res. Ex. SII N° 58 de 2017). No se piden CAF nuevos de entrada: mientras tenga folios suficientes sin usar, el SII no autoriza timbraje.

Límite: 20 registros por hora por IP.

Request Body schema: application/json
required
rut
required
string <= 12 characters

Cuerpo del RUT SIN el dígito verificador. Solo números; se aceptan puntos. Es inmutable: no se puede corregir después, porque la base de datos de la empresa se nombra a partir de él.

dv
required
string <= 1 characters

Dígito verificador. Se valida por módulo 11 contra el RUT.

razon_social
string <= 200 characters

Opcional: si la omites se toma del SII. Si el SII no la da, responde 422 con errors.razon_social.

nombre_fantasia
string <= 200 characters
giro
string <= 200 characters

Opcional: sale del SII. Sin giro la empresa se crea, pero no emite hasta completarlo (codigo: datos_emisor_incompletos).

direccion
required
string <= 300 characters
comuna
required
string <= 100 characters
ciudad
required
string <= 100 characters
telefono
required
string <= 20 characters

Obligatorio — es por donde se avisa si algo se traba en el alta.

email
string <email>

Correo de contacto de la EMPRESA (facturación y cobro). Opcional: si lo omites, se usa admin_email. Usa el real: se valida con la pasarela de pago al suscribirse. Su dominio pasa por la misma comprobación que admin_email (422 con errors.email).

admin_name
required
string <= 100 characters
admin_email
required
string <email>

Correo de quien administra la cuenta. Único en toda la plataforma: no se puede repetir en dos empresas, porque el inicio de sesión no sabría a cuál entrar. Si tu cliente administra varias empresas, eso se resuelve con una cuenta de organización, no registrándose dos veces. Su DOMINIO tiene que existir (desde el 3-nov-2026): si el DNS responde que no hay nada en él —ni MX, ni dirección—, la llamada devuelve 422 con errors.admin_email y el dominio nombrado en el mensaje. Es el correo con que el usuario entra, confirma la cuenta y recupera la contraseña: con una errata en el dominio queda encerrado fuera de su propia cuenta, y el RUT ya tomado. Se comprueba el dominio, nunca el buzón; si el DNS no contesta, el alta sigue (nunca se rechaza lo que no se pudo comprobar).

admin_password
required
string <password> >= 8 characters
admin_password_confirmation
string <password>

Opcional. Si la mandas, tiene que coincidir con admin_password.

plan_id
integer

Plan a contratar. Los ids salen de GET /planes (sólo los que se venden hoy). Si lo omites, la empresa parte en el plan Gratis (nunca en uno de pago) y la respuesta trae plan_por_elegir: true. Un plan que ya no se vende —no aparece en GET /planes, como el Básico o el de folios— responde 422 con errors.plan_id, aunque exista. Quien ya lo tenía lo conserva.

tipo_onboarding
string
Enum: "nueva" "migracion" "en_certificacion" "portal_gratuito"

Opcional: si lo omites, manda lo que diga el SII (y nueva por defecto mientras el SII no conteste). De dónde viene tu cliente. Son CUATRO casos y cada uno tiene otro trámite: nueva = nunca emitió y no está inscrito ante el SII: lo inscribimos y certificamos nosotros, con su plan pagado y su autorización (mandato). migracion = ya emite con otro proveedor (software de mercado): NO recertifica. en_certificacion = ya está inscrito y su certificación está en curso: no hay que inscribirlo de nuevo. portal_gratuito = hoy emite con el sistema gratuito del SII (Portal MiPyme). Para las facturas se presenta una petición administrativa para salir de la facturación gratuita y se certifica; las boletas son opcionales, van aparte y recién ahí se renuncia al sistema gratuito de boletas (código 890). Esos trámites los hacemos nosotros, con su plan pagado y su autorización. Si no lo sabes con certeza, mándalo igual: nosotros verificamos el RUT ante el SII y guardamos las dos cosas por separado (lo declarado y lo verificado). Para el trámite manda lo verificado.

proveedor_actual
string <= 100 characters

Solo si tipo_onboarding es migracion.

documentos_emitir
Array of integers

Opcional, pero conviene mandarlo. Tipos de DTE que tu cliente va a emitir (33, 34, 39, 41, 46, 52, 56, 61, 110, 111, 112). Dos cosas dependen de esto: la reposición automática de folios sólo vigila los tipos declarados, y el set de pruebas del SII se pide POR TIPO y es de UN SOLO USO.

emite_dte
boolean or null
Default: true

Opcional. Si tu cliente va a emitir documentos tributarios. Sin el campo, con null o vacío ("") es un emisor (lo normal). Sólo un false explícito (false, 0 o "0") crea una empresa solo-sueldos: entra por remuneraciones y Previred, no se le pide certificado ni folios y la respuesta trae "emite_dte": false y próximos pasos de remuneraciones. El texto "false" no es un booleano válido y responde 422.

volumen_estimado
string <= 50 characters

Opcional. Cuántos documentos al mes espera emitir tu cliente ("0-50", "50-500", "500+"). Sirve para dimensionar sus folios.

sistema_actual
string <= 100 characters

Opcional. Qué sistema usa hoy ("Odoo", "planilla", "ninguno").

acepta_contacto_comercial
boolean
Default: false

Opcional y separado de los otros consentimientos a propósito. Es la casilla de novedades y ofertas: sin este true no se le envían boletines, anuncios de funciones ni ofertas, tampoco después de la prueba, aunque haya dejado teléfono (Ley 21.719). No gobierna los avisos de la cuenta (vencimiento de la prueba, cómo contratar, alta sin usar, inactividad), que llevan un enlace para dejar de recibirlos (Ley 19.496, art. 28 B). Para que el true valga hay que mandar también acepta_contacto_version.

acepta_contacto_version
string <= 60 characters

Opcional. La versión del texto de la casilla que se le mostró a la persona (hoy novedades-v1-2026-10-16). Se guarda con el SHA-256 de ese texto como prueba del consentimiento. Un true sin versión conocida queda anotado pero no habilita boletines ni ofertas.

acepta_terminos
required
boolean

Debe ser true. Consentimiento exigido por la Ley 21.719; queda registrado con fecha, IP y versión del documento.

acepta_privacidad
required
boolean

Debe ser true.

acepta_dpa
required
boolean

Debe ser true. Acuerdo de tratamiento de datos.

Responses

Request samples

Content type
application/json
{
  • "rut": "76354771",
  • "dv": "K",
  • "razon_social": "Mi Empresa SpA",
  • "giro": "Servicios de informática",
  • "direccion": "Av. Providencia 1234, of. 501",
  • "comuna": "Providencia",
  • "ciudad": "Santiago",
  • "telefono": "+56912345678",
  • "email": "contacto@miempresa.cl",
  • "admin_name": "Ana Pérez",
  • "admin_email": "ana@miempresa.cl",
  • "admin_password": "una-clave-larga-y-propia",
  • "tipo_onboarding": "migracion",
  • "proveedor_actual": "OpenFactura",
  • "acepta_terminos": true,
  • "acepta_privacidad": true,
  • "acepta_dpa": true
}

Response samples

Content type
application/json
{
  • "message": "¡Empresa registrada exitosamente!",
  • "tenant_id": 42,
  • "rut": "76.354.771-K",
  • "razon_social": "Mi Empresa SpA",
  • "plan": "profesional",
  • "plan_por_elegir": false,
  • "tipo_onboarding": "migracion",
  • "emite_dte": true,
  • "proximos_pasos": {
    },
  • "api_key": "sk_test_8ea441f654413dc99893674ae3ca8353",
  • "api_key_aviso": "string"
}

Dar de alta una organización (estudio contable, holding o partner)

Crea la cuenta de una organización —un estudio contable, un holding o un partner— y su administrador. No requiere autenticación.

Es lo que hay que usar cuando quien se registra va a facturar por VARIAS empresas, en vez de POST /register una vez por RUT. Las empresas se agregan después desde el panel: cada una con su base aislada, su certificado digital y sus folios, bajo una sola cuenta y una sola factura.

El administrador que se crea acá no cuelga de ninguna empresa: es de la cartera entera, y es quien da de alta al resto.

El tipo elige el plan, y eso cambia lo que se cobra:

tipo Para quién Plan Cupo de DTE
estudio Estudio contable Estudio 300 por empresa, en pool compartido
holding Varias sociedades del mismo dueño Estudio 300 por empresa, en pool compartido
reseller Plataforma, POS o partner que factura por sus clientes Plataforma Sin pool: emisión ilimitada por RUT

Elegir mal no es un detalle estadístico: una plataforma cuyos clientes emiten miles de boletas al mes se queda sin cupo el primer mes si entra como estudio.

El precio va por empresa de la cartera, no por documento, y la primera vale lo mismo que el plan individual equivalente. Se cobra por las empresas que tengas, desde que las agregas: nadie declara por adelantado cuántas va a tener.

Después de esto: entra con el correo y la contraseña que elegiste, agrega tu primera empresa y carga su certificado digital.

Request Body schema: application/json
required
razon_social
required
string <= 200 characters
rut
required
string <= 12 characters

Cuerpo del RUT de la ORGANIZACIÓN, sin dígito verificador. No es el de ninguna de las empresas de la cartera.

dv
required
string <= 1 characters
tipo
required
string
Enum: "estudio" "holding" "reseller"

Determina el plan y el cupo. Ver la tabla de arriba.

nombre
required
string <= 100 characters

Nombre de la persona que administra la cartera.

email
required
string <email>

Correo del administrador. Único en toda la plataforma: es con el que inicia sesión.

telefono
required
string <= 20 characters
password
required
string <password> >= 8 characters
password_confirmation
required
string <password>
acepta_terminos
required
boolean
acepta_privacidad
required
boolean
acepta_dpa
required
boolean

Responses

Request samples

Content type
application/json
{
  • "razon_social": "Finaxa SpA",
  • "rut": "76900000",
  • "dv": "1",
  • "tipo": "estudio",
  • "nombre": "Laura Ortiz",
  • "email": "laura@finaxa.cl",
  • "telefono": "+56912345678",
  • "password": "pa$$word",
  • "password_confirmation": "pa$$word",
  • "acepta_terminos": true,
  • "acepta_privacidad": true,
  • "acepta_dpa": true
}

Response samples

Content type
application/json
{
  • "message": "string",
  • "organizacion": {
    },
  • "email": "user@example.com",
  • "siguiente_paso": "string"
}

Verificar un RUT ante el SII antes de darlo de alta

Le pregunta al SII de dónde viene ese contribuyente: si ya es emisor electrónico con software de mercado, si está a mitad de su certificación, si todavía no se inscribió, o si está emitiendo con el sistema gratuito del SII. Con eso sabes qué tipo_onboarding mandar en POST /register.

No requiere autenticación ni el certificado de tu cliente. La pantalla que se consulta —"Consultar Empresas Autorizadas"— es una consulta abierta entre contribuyentes: entramos con el nuestro.

Es asíncrona, y eso no es un detalle de implementación. Entrar al portal del SII toma unos 40 segundos y el SII bloquea por "máximo de sesiones", así que la consulta se hace en segundo plano. Esta llamada responde 202 al instante; el resultado se pregunta con GET /registro/validar-rut/{rut} cada ~5 segundos.

Nunca bloquea el alta. Si el SII no contesta, registra igual con lo que tu cliente declare: guardamos por separado lo declarado y lo verificado, y se puede revalidar después.

La respuesta se cachea 24 horas por RUT (lo que se lee sólo cambia por trámites ante el SII, que se mueven de un día para otro) y hay un solo trabajo en vuelo por RUT: repetir la llamada no abre más sesiones.

Request Body schema: application/json
required
rut
required
string <= 12 characters

Cuerpo del RUT SIN dígito verificador.

dv
required
string <= 1 characters

Dígito verificador. Se valida antes de salir al SII.

Responses

Request samples

Content type
application/json
{
  • "rut": "77123456",
  • "dv": "5"
}

Response samples

Content type
application/json
{
  • "rut": "20141906-9",
  • "estado": "pendiente",
  • "origen": "nueva",
  • "confianza": "verificado",
  • "motivo": "El SII lo tiene dentro del sistema gratuito de boletas electrónicas (código 890, autorizado el 18-08-2026 y sin desautorizar).",
  • "razon_social": "string",
  • "documentos_sugeridos": [
    ],
  • "situacion_tributaria": {
    },
  • "evidencia": {
    },
  • "mensaje": "string",
  • "consultar_en": "string",
  • "reintentar_en_segundos": 5,
  • "desde_cache": true,
  • "opciones": [
    ]
}

Estado de la verificación de un RUT

El resultado de POST /registro/validar-rut. Nunca falla: si nadie consultó ese RUT devuelve estado: desconocido, y si la consulta al SII se cayó devuelve estado: error con las cuatro opciones para que se lo preguntes tú a tu cliente.

path Parameters
rut
required
string
Example: 77123456-5

RUT con dígito verificador y sin puntos.

Responses

Response samples

Content type
application/json
{
  • "rut": "20141906-9",
  • "estado": "pendiente",
  • "origen": "nueva",
  • "confianza": "verificado",
  • "motivo": "El SII lo tiene dentro del sistema gratuito de boletas electrónicas (código 890, autorizado el 18-08-2026 y sin desautorizar).",
  • "razon_social": "string",
  • "documentos_sugeridos": [
    ],
  • "situacion_tributaria": {
    },
  • "evidencia": {
    },
  • "mensaje": "string",
  • "consultar_en": "string",
  • "reintentar_en_segundos": 5,
  • "desde_cache": true,
  • "opciones": [
    ]
}

Ciclo del cliente: leer la decisión pendiente del sistema gratuito del SII

Cuando el SII tiene a la empresa en su sistema gratuito (Resolución 99 para facturas y/o código 890 para boletas), el ciclo de vida del cliente se detiene en PORTAL_GRATUITO_DECIDE y le manda el correo «Estás en el sistema gratuito del SII: elige» con un enlace firmado (7 días).

Sin login ni API Key. La autenticación es la firma de la URL (tenant, expires, signature), que llega en el correo apuntando a la página del front /ciclo/decision?tenant=…&expires=…&signature=…. La página reenvía esos tres parámetros tal cual a este endpoint, en el GET y en el POST (comparten URI a propósito: una sola firma vale para leer y para decidir). Una firma inválida o vencida responde 403.

Devuelve el estado del ciclo, si la decisión sigue pendiente, qué dijo el SII (nro_resol, con_890_vigente) y, por cada opción de tipos, los trámites que haremos en nombre del cliente con el texto literal de cada declaración que tiene que aceptar (tramites). desafiliacion_facturas es siempre false: la Res. 99 se certifica sin desafiliarse; sólo el 890 (boletas) se renuncia, y sólo si elige certificarlas.

query Parameters
tenant
required
integer

Id de la empresa (viene en el enlace).

expires
required
integer

Vencimiento de la firma (viene en el enlace).

signature
required
string

Firma HMAC del enlace (viene en el enlace).

Responses

Response samples

Content type
application/json
{
  • "tenant": {
    },
  • "estado": "PORTAL_GRATUITO_DECIDE",
  • "estado_etiqueta": "string",
  • "decision_pendiente": true,
  • "decision": { },
  • "nro_resol": 99,
  • "con_890_vigente": true,
  • "opciones": [
    ],
  • "tipos": [
    ],
  • "tramites_por_tipos": {
    },
  • "tramites": {
    },
  • "renuncia_890_aplica": true,
  • "desafiliacion_facturas": false
}

Ciclo del cliente: decidir (quedarme en el sistema gratuito o certificar)

Misma URL y misma firma que el GET.

  • quedarme → el ciclo pasa a SII_FREE (terminal abierto): cero trámites ante el SII, cero folios, cero certificación; se apagan los recordatorios de certificado y de fin de prueba. Sale el correo «Seguimos contigo en el sistema gratuito».
  • certificar con tipos (facturas | boletas | ambas) → se registran los consentimientos de cada trámite requerido (tramites_por_tipos del GET), se declaran los documentos a emitir, se inicia el motor de certificación y el ciclo pasa a EN_CERTIFICACION. Con boletas o ambas y el 890 vigente, incluye renunciar_boleta_gratuita, que se ensaya en seco de inmediato y sólo se ejecuta por el motor con ese consentimiento (regla de oro: ningún trámite irreversible sin consentimiento + ensayo).

declaraciones tiene que traer todas las claves de todos los trámites de la opción elegida (el texto literal viene en el GET). Si falta alguna, 422 con faltan. Si la empresa ya decidió, 409.

query Parameters
tenant
required
integer
expires
required
integer
signature
required
string
Request Body schema: application/json
required
decision
required
string
Enum: "quedarme" "certificar"
tipos
string
Enum: "facturas" "boletas" "ambas"

Obligatorio con certificar.

declaraciones
Array of strings

Claves aceptadas (p. ej. entiendo_que_declara_ante_el_sii). Obligatorio con certificar.

nombre
string <= 120 characters

Quién decide (queda en el consentimiento).

correo
string <email>

Responses

Request samples

Content type
application/json
{
  • "decision": "quedarme",
  • "tipos": "facturas",
  • "declaraciones": [
    ],
  • "nombre": "string",
  • "correo": "user@example.com"
}

Response samples

Content type
application/json
{
  • "message": "string",
  • "estado": "SII_FREE",
  • "certificacion_id": 0,
  • "tramites_consentidos": [
    ],
  • "renuncia_890": { }
}

Qué le falta a la empresa para que actuemos ante el SII por ella

«¿Qué me falta?» antes de chocar (desde el 28-oct-2026). Devuelve lo mismo que la puerta del SII —lo que exige actuar ante el SII con el certificado de la empresa: certificarla, pedir sus folios, hacer sus trámites— y la lista del panel («Para empezar tu certificación te falta…»), ítem por ítem.

Las cuatro condiciones de la puerta: plan Profesional o superior pagado (la prueba de 14 días y el plan gratis no cuentan), certificado digital vigente, la autorización para trámites ante el SII (mandato) y los datos de la empresa (giro, dirección, comuna, ciudad, correo y teléfono).

  • abierta: las cuatro están. Mientras sea false, no certificamos, no pedimos folios y no hacemos trámites por esta empresa.
  • puede_pedir_folios: lo que de verdad decide la reposición de folios en su ambiente. En una empresa de desarrollo (mock) no hay SII y es true; quien ya emite en producción y paga conserva sus folios aunque le falte el mandato.
  • faltan: un objeto por condición que falta (FaltaDeLaPuerta), con que, como, donde (ruta del portal) y donde_url (absoluta). Es la forma del 402 puerta_sii_cerrada del portal, no la del 422 de POST /dte, que trae faltan como lista de claves y donde/donde_url como mapas.
  • ambiente y livemode: los de la llave, como en el resto de la API (una sk_test_ de una empresa en producción pregunta por certificación).
  • En una empresa de desarrollo (ambiente: mock, la llave que llega por correo) no hay SII: faltan va vacío, abierta y puede_pedir_folios son true, y no viene la lista del panel (es de la empresa real: pregúntalo con su llave).
  • Con una llave de organización hay que elegir la empresa con X-Empresa-RUT: sin él responde 400; con un RUT que no está en su cartera, 403.
  • para_emitir (o para_liquidar, en una empresa sólo de remuneraciones): la lista del panel, con href y href_url.

Sólo lectura: no consulta al SII ni escribe nada. Scope dte:read. En el MCP: que_me_falta.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "empresa": {
    },
  • "ambiente": "certificacion",
  • "abierta": false,
  • "puede_pedir_folios": false,
  • "faltan": [
    ],
  • "mensaje": "Todavía no podemos actuar ante el SII por ti (certificar, pedir folios ni hacer trámites). Falta un plan Profesional o superior pagado: la prueba y el plan gratis no cuentan. Falta que autorices los trámites ante el SII en tu nombre (mandato)."
}

Ambientes (desarrollo, certificación y producción)

Hay tres ambientes. Dos de ellos hablan con el SII; el de desarrollo no.

Ambiente Valor de ambiente Habla con el SII Validez tributaria
Desarrollo mock No No — el PDF lleva el sello SIN VALIDEZ TRIBUTARIA
Certificación certificacion Sí (maullin) No
Producción produccion Sí (palena) Sí

En certificación y producción, el ambiente lo determina tu API Key:

  • sk_test_… → certificación (maullin) — documentos de prueba, sin validez tributaria.
  • sk_live_… → producción (palena) — documentos reales con validez tributaria.

Puedes usar una key sk_test_ aunque tu empresa ya esté en producción, para probar sin emitir documentos reales. Los listados y reportes quedan acotados al ambiente de la key (los documentos de prueba nunca se mezclan con los reales).

Ambiente de desarrollo

Al registrarte se crea automáticamente una empresa gemela en ambiente de desarrollo, que copia la identidad de tu empresa (razón social, giro, dirección, tipos de documento habilitados) sobre un RUT de prueba del rango 88.8xx.xxx, para no chocar con el RUT real de ningún contribuyente. La API Key sk_test_ de esa empresa llega por correo al email de contacto del registro.

Qué hace y qué no:

  • Emite de verdad: asigna folio, firma el XML (XMLDSig), genera el TED y el PDF417, y produce el PDF. El flujo que ejercitas es el mismo código de producción.
  • No envía nada al SII. No hay TrackID real ni respuesta del SII.
  • Folios sintéticos para los 12 tipos soportados (33, 34, 39, 41, 43, 46, 52, 56, 61, 110, 111, 112), así que no necesitas CAF ni certificado digital para probar.
  • El PDF lleva el sello SIN VALIDEZ TRIBUTARIA.

La empresa de desarrollo es dominante: aunque uses una key sk_live_ contra ella, el ambiente sigue siendo mock. Un documento de desarrollo no puede convertirse en uno real por equivocación.

Cuota y vigencia. El ambiente admite 200 documentos; superado el tope, la emisión responde 429 con el conteo (cuota.usados / cuota.limite) y un contacto para ampliarlo o pasar a producción. Un ambiente sin uso durante 30 días se da de baja, con aviso por correo a los 23 días.

Webhooks. Se disparan igual que en producción, con la misma firma HMAC. Distínguelos por el cuerpo del evento: livemode es false y ambiente vale mock (ver el esquema WebhookEvent). livemode es true solo en producción.

Probar el rechazo. La aceptación del SII es asíncrona y en desarrollo no hay SII, así que ningún documento se rechaza solo. Para ejercitar esa rama usa POST /dte/{id}/simular-estado, que fuerza el estado final y dispara los mismos webhooks y notificaciones. Solo existe en desarrollo: en certificación y producción responde 403.

Autenticación

Toda petición al canal de integradores va con tu API Key en el header X-Api-Key:

X-Api-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • sk_live_… → producción (palena) · sk_test_… → certificación (maullin). El prefijo decide el ambiente del DTE (ver Ambientes).

Antes de tener certificado y folios: el ambiente de desarrollo. Al registrarte recibes por correo una key sk_test_ de una empresa gemela en ambiente de desarrollo, que emite, firma y genera PDF sin tocar el SII y sin exigirte certificado digital ni CAF. Se usa igual que cualquier otra key, en el mismo header. Ver Ambientes.

Dos alcances de clave. Una API Key puede pertenecer a una empresa o a una organización (estudio contable, holding, partner) que administra varios RUT emisores:

Alcance RUT emisor Header X-Empresa-RUT
Empresa El de la clave — no se puede cambiar desde el request No se envía
Organización El que indiques en cada llamada Obligatorio

Si tu clave administra varias empresas, lee Varias empresas (estudios contables y holdings).

Gestión de keys. Se crean desde el portal web (Configuración → API Keys) y se muestran una sola vez al crearlas — guárdalas de forma segura. Cada key puede tener uno o varios de estos permisos (scopes):

Scope Permite
dte:create Emitir DTE (POST /dte)
dte:read Leer/listar DTE emitidos, resumen, autocompletar receptor
recepcion:read Leer DTE recibidos (intercambio)
recepcion:write Aceptar/reclamar DTE recibidos, subir XML manual
rcv:read Leer el Registro de Compras y Ventas
rcv:write Reclamar/marcar en el RCV (muta en el SII)
caf:read Ver estado de folios (CAF) disponibles
caf:write Solicitar nuevos folios al SII (vía RPA con tu certificado)
webhook:manage Registrar y administrar webhooks salientes
organizacion:read Sólo claves de organización. Leer la administración de la organización: resumen y cobro, salud y actividad de la cartera, ventas consolidadas (GET /organizacion/*; las ventas exigen además dte:read). No viene en ninguna clave existente, ni en una «con todos los permisos»: se elige al crear la clave. No depende del ambiente: una sk_test_ con este permiso lee el cobro, la salud y la actividad reales de la organización
sii:credenciales Conectar, consultar y desconectar la clave tributaria de la empresa ante el SII (GET/PUT/DELETE /sii/credenciales). Permiso explícito: NO viene en ninguna clave existente ni en una «con todos los permisos»; se elige al crear la clave. Sólo claves sk_live_: la clave tributaria es la clave real de la empresa en sii.cl y no tiene versión de prueba (con sk_test_ responde 409). La clave se entrega una sola vez, se valida contra el SII, se cifra y NUNCA se devuelve (el GET da sólo su estado)
previred:credenciales Conectar, consultar y desconectar la credencial de Previred de la empresa (GET/PUT/DELETE /previred/credenciales), y ver, buscar en Previred y elegir las empresas que administra esa credencial (/previred/credenciales/empresas). Permiso explícito: NO viene en ninguna clave existente ni en una «con todos los permisos»; se elige al crear la clave. Para entregar la credencial (PUT) sólo claves sk_live_ (con sk_test_ responde 409). La clave se entrega una sola vez, se cifra y NUNCA se devuelve (el GET da sólo su estado)
previred:mandato Ver, firmar y revocar el mandato legal de Previred de la empresa (GET/POST/DELETE /previred/mandato): la autorización expresa, versionada y revocable para operar su cuenta de Previred. Permiso explícito: NO viene en ninguna clave existente ni en una «con todos los permisos»; se elige al crear la clave (un integrador pide el mandato a su cliente). El mandato NO es un secreto (se firma por POST), pero autoriza operar la cuenta real: para firmar o revocar sólo claves sk_live_ (con sk_test_ responde 409)
previred:nomina Validar y generar el archivo de nómina de Previred (POST /previred/nomina/validar y /previred/nomina/archivo) y LEER el estado de la sincronización con Previred (GET /previred/nomina/sincronizaciones/{periodo}). El ensayo en seco no toca la credencial, no habla con Previred y no guarda nada; la sincronización se DISPARA desde el portal (opera la cuenta del cliente), acá sólo se lee. Funciona igual con sk_test_ y sk_live_
nomina:gestionar Gestionar la corrida de nómina mensual de la empresa (/nomina/corridas/*): abrir, calcular las liquidaciones, generar y validar el archivo de Previred, y leer su avance. Permiso explícito: NO viene en ninguna clave existente ni en una «con todos los permisos»; se elige al crear la clave. Funciona igual con sk_test_ y sk_live_ salvo la subida REAL a Previred (POST /nomina/corridas/{periodo}/subir con dry_run: false), que exige sk_live_, una empresa real y que la plataforma la tenga habilitada (hoy viene apagada: responde 409 subida_previred_real_apagada; la prueba en seco sí funciona). No cobra

⚠️ Nunca pongas una API Key en el frontend, apps móviles ni en repositorios. Úsala solo desde tu backend. Si se filtra, revócala desde el portal y crea otra.

Las rutas de acceso por token para el receptor (/api/portal/…) son la única excepción: no usan API Key (ver Enlace para el receptor).

Varias empresas (estudios contables y holdings)

Sí: una sola cuenta puede emitir DTE para varios RUT emisores. Es el caso de un estudio contable que factura por sus empresas cliente, de un holding con varias sociedades, o de un SaaS que revende emisión.

Ese conjunto de RUT se llama cartera, y pertenece a una organización.

Las dos formas de indicar la empresa

1. Una clave por empresa (recomendada para emitir)

Creas una sk_live para cada RUT. La clave es la empresa: no envías ningún header extra. Si una se filtra, el daño se limita a esa empresa.

X-Api-Key: sk_live_...clave_de_la_panaderia...
POST /dte     → emite por la Panadería

2. Una clave de organización (necesaria para el MCP / agentes de IA)

Una sola clave para toda la cartera. En cada llamada indicas por qué empresa operas, con el header X-Empresa-RUT:

X-Api-Key: sk_live_...clave_del_estudio...
X-Empresa-RUT: 76354771-K
POST /dte     → emite por la Panadería

X-Empresa-RUT: 78211386-0
POST /dte     → emite por la Ferretería, con la MISMA clave

El RUT se acepta con o sin puntos y con o sin dígito verificador (76354771, 76354771-K y 76.354.771-K son equivalentes).

Elige con criterio. Una clave de organización es cómoda, pero si se filtra expone toda la cartera, no una empresa. Para emitir desde tu ERP, preferimos claves por empresa. Reserva la de organización para orquestación y para el MCP, que necesita poder elegir la empresa en cada instrucción.

¿Qué empresas administra mi clave?

GET /empresas responde la cartera sin exigir haber elegido empresa (sería circular: es la llamada con la que la descubres). Sirve para los dos tipos de clave, con la misma forma de respuesta. Las lecturas de administración (GET /organizacion/*, abajo) tampoco llevan X-Empresa-RUT: son de toda la cartera.

Administrar la cartera por API (sólo lectura)

Con una clave de organización que tenga el permiso organizacion:read, tu ERP o tu agente de IA lee lo mismo que el socio ve en el panel del estudio, sin X-Empresa-RUT (si lo envías, se ignora):

Operación Responde
GET /organizacion Plan, cobro mensual neto y con IVA, cupo de DTE de la cartera
GET /organizacion/salud Puntaje y pendientes de cada empresa
GET /organizacion/actividad Llamadas a la API de la cartera, desde hasta 90 días atrás
GET /organizacion/ventas Ventas válidas por empresa y el total, en un rango de hasta 366 días. Exige además dte:read

Ojo con el ambiente: el resumen, la salud y la actividad son los reales de la organización con cualquier clave, también con una sk_test_ (no hay cobro ni actividad «de prueba»). Sólo las ventas cambian con el ambiente de la clave. Si le das organizacion:read a una clave de pruebas, esa clave ve lo que paga el estudio.

Agregar o quitar empresas, usuarios, la suscripción y las claves NO se hace por API: se hace en el portal, con la cuenta del administrador. Una clave es una credencial de máquina que puede filtrarse, y no puede tocar ni el cobro ni la cartera. Una clave de empresa recibe 403 con codigo: "requiere_llave_de_organizacion".

El emisor NUNCA se toma del cuerpo

El header selecciona la empresa; no la inventa. El RUT emisor, la razón social, el giro y el código de actividad del DTE se leen siempre del registro de esa empresa. Si mandas un bloque emisor en el cuerpo, se ignora. Así, una clave nunca puede facturar a nombre de un RUT que no le pertenece.

Errores propios del multi-empresa

Código Cuándo Qué hacer
400 Clave de organización sin X-Empresa-RUT Indica la empresa. GET /empresas te dice cuáles
403 El RUT no está en tu cartera (o está suspendido/retirado) Revisa la cartera en el portal
403 con codigo: "organizacion_suspendida" La organización no está vigente. Lo reciben todas sus claves y también las claves de empresa de su cartera (salvo la empresa que paga su propia suscripción) El estudio regulariza su cuenta; no se arregla reintentando
409 Reusaste una Idempotency-Key de otra empresa Usa claves de idempotencia distintas por empresa

Idempotencia por empresa. Si tu ERP numera las facturas por empresa, vas a repetir F-1001 en dos de ellas. Está previsto: la clave de idempotencia es por empresa emisora. Ante una colisión entre empresas respondemos 409 antes que devolverte el documento equivocado.

Cuotas

El plan de organización trae un cupo de DTE compartido por toda la cartera (no un tope por empresa): las que facturan poco le prestan cupo a las que facturan mucho. Al agotarse, la emisión responde 429 con pool_dte y emitidos_este_mes para todas las empresas de la cartera, y no se reintenta hasta cambiar de plan o hasta el mes siguiente. El límite de peticiones por minuto, en cambio, se cuenta por llave y empresa: el peak de una no le consume la cuota a las demás.

Emisión asíncrona y estados

Emitir un DTE es asíncrono: POST /dte responde 201 con el documento en estado pendiente y lo encola para envío al SII. El estado final llega después; consúltalo con GET /dte/{id} o suscríbete a webhooks.

Boletas y facturas se emiten sin esperar la validación del SII: ya son válidas con su folio y timbre (TED), y la aceptación del SII es posterior. La única excepción son las notas de crédito/débito, cuyo envío depende de que su documento referenciado exista en el SII (ver Notas de crédito y débito).

estado_local — el estado normalizado (úsalo para tu lógica)

estado_local ¿Final? Significado
pendiente No (en curso) Creado, aún no enviado al SII.
enviando No (en curso) Envío en marcha.
enviado No (en curso) En el SII, esperando el acuse del sobre.
error_envio No, pero puede avanzar solo unos días No logró llegar al SII, o la plataforma dejó de esperar el veredicto de un sobre que sí salió (el documento trae track_id). Los reintentos del envío ocurren antes de marcarlo. Después la plataforma lo sigue trabajando sola por unos días: con track_id vuelve a consultar el sobre; sin track_id (facturas, notas y guías de producción; no boletas 39/41) le pregunta al SII por el folio y, si el SII ya lo tiene, el documento pasa a su veredicto (dte.aceptado u otro); si no lo tiene, lo reenvía con el mismo folio. Como mucho 3 reenvíos, separados por 6 horas, dentro de los 3 días siguientes a la emisión, y sólo si la empresa podría reintentarlo a mano (suscripción al día); cada intento queda en detalle_sii.recuperacion_envio. Si no se resuelve así, se sale con POST /dte/{id}/reintentar. No se reemite: el folio ya está tomado y otro documento declararía dos veces la misma venta. Única excepción: si glosa_sii dice «no valida XSD» o «viola reglas de negocio», el XML nunca llegó al SII, reintentar responde 409 causa: contenido_invalido, y se corrige emitiendo uno nuevo.
aceptado Sí Aceptado por el SII. Documento válido.
aceptado_con_reparos Sí Aceptado y VÁLIDO, con observaciones (SII RPR). NO es un rechazo.
rechazado Sí Rechazado por el SII (validación). Corregir y re-emitir.
rechazado_sobre Sí El sobre completo fue rechazado.
anulado Sí Anulado (p. ej. por una NC que lo reversa).

Los estados en curso suelen durar segundos. Si el SII está caído, la plataforma reintenta el envío por su cuenta y un documento puede quedar horas en pendiente o enviando antes de llegar a un estado final o a error_envio: eso no indica un problema de tu lado. Para decidir en caja, aceptado y aceptado_con_reparos son ambos documento válido.

estado_sii — el código crudo del SII (trazabilidad)

Aparte va estado_sii, el código tal cual lo entrega el SII (no es una lista cerrada nuestra). Los que verás en producción: EPR (envío procesado), DOK (documento aceptado), RPR (reparo → aceptado_con_reparos) y RCT/RCH/RFR (rechazos). Para tu lógica usa estado_local; estado_sii es para trazabilidad.

Errores operativos de emisión (HTTP)

Distinguibles por código HTTP, para avisar claro en caja —no un "falló" genérico:

HTTP Cuándo Body Qué hacer
402 Suscripción impaga / trial vencido subscription_required: true y, desde el 28-oct-2026, estado_suscripcion: morosa (un cobro falló), prueba_vencida, suscripcion_terminada (pagó y su período venció), dado_de_baja, fuera_de_cartera u organizacion_impaga "Regulariza el pago para seguir emitiendo." Sin reintentos en bucle. El message ya dice cuál de las seis es.
503 Sin folios de ese tipo en ese ambiente codigo: "folios_agotados", tipo_dte, ambiente, reintentar_en_segundos y el header Retry-After (30–300 s) "Sin folios; la reposición ya se pidió." Reintenta pasado Retry-After con la misma Idempotency-Key. Un 503 sin codigo es otra cosa: escálalo.
422 Datos del documento inválidos message (y errors si viene) Corregir el documento (no quema folio).
422 Precondición de la empresa codigo: datos_emisor_incompletos, acteco_ausente, resolucion_produccion_ausente, tipo_no_autorizado_sii, certificado_no_utilizable o puerta_sii_cerrada Corregir la ficha de la empresa o el certificado: reenviar el mismo payload no lo arregla. Ver la tabla del 422 en POST /dte.
429 Límite de peticiones por minuto message, codigo: "demasiadas_solicitudes", retry_after (segundos) y el header Retry-After Backoff respetando Retry-After.
429 Cupo mensual del plan (emitidos_este_mes) o de la cartera (pool_dte) agotado message, emitidos_este_mes y, en una cartera, pool_dte No se reintenta: detén la emisión y avisa hasta cambiar de plan o hasta el mes siguiente.
429 Cuota del ambiente de desarrollo agotada message y cuota: {usados, limite} No se reintenta: pide ampliar la cuota o pasa a producción.
409 Idempotency-Key en curso o reusada entre empresas message (en curso, además reintentar_en_segundos y Retry-After) En curso: espera y reintenta con la misma clave. Entre empresas: usa claves distintas por empresa.

Errores del borde HTTP (cualquier endpoint)

Todo error es JSON con message en español y, en estos casos, un codigo estable para programar contra él. Ningún mensaje trae nombres de clases, rutas de archivo ni SQL.

HTTP codigo Cuándo Qué hacer
400 json_invalido El cuerpo no es JSON válido, o es JSON pero llegó sin Content-Type: application/json (por ejemplo curl -d sin cabecera). Antes se descartaba en silencio y la respuesta era «falta el campo tipo_dte». Corrige el JSON o agrega la cabecera.
401 no_autenticado Falta la credencial en rutas con sesión. En la API pública, sin X-Api-Key responde 401 con su propio mensaje. Envía la credencial.
404 no_encontrado La ruta no existe, el recurso no existe o no es de tu empresa, o el identificador no es un número entero (por ejemplo /dte/abc o /dte/99999999999999999999). El mensaje es genérico: no dice qué tabla ni qué id. Revisa la URL y el identificador.
405 metodo_no_permitido El método HTTP no existe para esa ruta. Trae el header Allow. Usa uno de los métodos de Allow.
413 cuerpo_demasiado_grande El cuerpo supera 20 MB. Divide el envío.
422 parametro_invalido Un parámetro de query llegó como arreglo (?origen[]=api). Las listas van separadas por comas: ?origen=api,mcp. Envía un valor simple o una lista con comas.
429 demasiadas_solicitudes Límite de peticiones (ver «Límites de peticiones»). Trae retry_after y el header Retry-After. Espera Retry-After y reintenta.
500 error_interno Falla nuestra; queda registrada con su causa. Reintenta más tarde; si persiste, escribe a soporte.

Filtros con valores que no existen se ignoran. GET /dte?origen=xyz o ?tipo_dte=abc no responden 422: el filtro inválido no se aplica y la lista sale sin él. Es deliberado, para no romper integraciones que ya mandan valores de más; valida tus filtros de tu lado.

Certificado vencido, no cargado o ilegible: la emisión responde 422 con codigo: "certificado_no_utilizable" y no consume folio. Se corrige subiendo un .p12 vigente en Empresa → Certificado.

Límites de peticiones

Límite Alcance
120 peticiones por minuto Por API Key y empresa emisora, sobre toda la API
30 POST por minuto sobre rutas de /dte Por API Key y empresa: cuentan emitir, reintentar, portal-link, simular-estado y las acciones sobre documentos recibidos
30 peticiones por minuto POST /sandbox/dte, por IP
10 peticiones por minuto GET /organizacion/ventas, por organización: todas sus claves suman

Emite desde una cola con concurrencia acotada, no en ráfagas. Superar un límite responde 429 con el header Retry-After, codigo: "demasiadas_solicitudes" y retry_after en segundos.

El límite por llave cuenta por llave y empresa, no por IP: dos integraciones que salen por la misma IP (por ejemplo, todos los clientes del MCP hospedado) no comparten cupo, y una llave inválida no gasta el de nadie (responde 401 sin contar). Los límites por IP (sandbox, registro) usan la IP real del cliente; la cabecera X-Forwarded-For que envía el cliente no la cambia.

Tamaño del documento

Lista Máximo Fuente
items en boletas (39, 41) 1.000 EnvioBOLETA_v11.xsd, Detalle maxOccurs=1000
items en el resto de los tipos 60 DTE_v10.xsd, Detalle maxOccurs=60
referencias 40 Referencia maxOccurs=40 en ambos esquemas
totales.impuestos_adicionales 20 ImptoReten maxOccurs=20
Cuerpo de la solicitud 20 MB 413 cuerpo_demasiado_grande

Son los topes del esquema del SII: un documento con más filas lo rechazaría el SII. Superarlos responde 422 con el error en la lista (errors.items) y no consume folio. Si una venta tiene más líneas, divídela en más de un documento.

<code>estado_local</code> — el estado normalizado (úsalo para tu lógica)

<code>estado_sii</code> — el código crudo del SII (trazabilidad)

Emitir un DTE es asíncrono: POST /dte responde 201 con el documento en estado pendiente y lo encola para envío al SII. El estado final llega después; consúltalo con GET /dte/{id} o suscríbete a webhooks.

Boletas y facturas se emiten sin esperar la validación del SII: ya son válidas con su folio y timbre (TED), y la aceptación del SII es posterior. La única excepción son las notas de crédito/débito, cuyo envío depende de que su documento referenciado exista en el SII (ver Notas de crédito y débito).

estado_local — el estado normalizado (úsalo para tu lógica)

estado_local ¿Final? Significado
pendiente No (en curso) Creado, aún no enviado al SII.
enviando No (en curso) Envío en marcha.
enviado No (en curso) En el SII, esperando el acuse del sobre.
error_envio No, pero puede avanzar solo unos días No logró llegar al SII, o la plataforma dejó de esperar el veredicto de un sobre que sí salió (el documento trae track_id). Los reintentos del envío ocurren antes de marcarlo. Después la plataforma lo sigue trabajando sola por unos días: con track_id vuelve a consultar el sobre; sin track_id (facturas, notas y guías de producción; no boletas 39/41) le pregunta al SII por el folio y, si el SII ya lo tiene, el documento pasa a su veredicto (dte.aceptado u otro); si no lo tiene, lo reenvía con el mismo folio. Como mucho 3 reenvíos, separados por 6 horas, dentro de los 3 días siguientes a la emisión, y sólo si la empresa podría reintentarlo a mano (suscripción al día); cada intento queda en detalle_sii.recuperacion_envio. Si no se resuelve así, se sale con POST /dte/{id}/reintentar. No se reemite: el folio ya está tomado y otro documento declararía dos veces la misma venta. Única excepción: si glosa_sii dice «no valida XSD» o «viola reglas de negocio», el XML nunca llegó al SII, reintentar responde 409 causa: contenido_invalido, y se corrige emitiendo uno nuevo.
aceptado Sí Aceptado por el SII. Documento válido.
aceptado_con_reparos Sí Aceptado y VÁLIDO, con observaciones (SII RPR). NO es un rechazo.
rechazado Sí Rechazado por el SII (validación). Corregir y re-emitir.
rechazado_sobre Sí El sobre completo fue rechazado.
anulado Sí Anulado (p. ej. por una NC que lo reversa).

Los estados en curso suelen durar segundos. Si el SII está caído, la plataforma reintenta el envío por su cuenta y un documento puede quedar horas en pendiente o enviando antes de llegar a un estado final o a error_envio: eso no indica un problema de tu lado. Para decidir en caja, aceptado y aceptado_con_reparos son ambos documento válido.

estado_sii — el código crudo del SII (trazabilidad)

Aparte va estado_sii, el código tal cual lo entrega el SII (no es una lista cerrada nuestra). Los que verás en producción: EPR (envío procesado), DOK (documento aceptado), RPR (reparo → aceptado_con_reparos) y RCT/RCH/RFR (rechazos). Para tu lógica usa estado_local; estado_sii es para trazabilidad.

Errores operativos de emisión (HTTP)

Distinguibles por código HTTP, para avisar claro en caja —no un "falló" genérico:

HTTP Cuándo Body Qué hacer
402 Suscripción impaga / trial vencido subscription_required: true y, desde el 28-oct-2026, estado_suscripcion: morosa (un cobro falló), prueba_vencida, suscripcion_terminada (pagó y su período venció), dado_de_baja, fuera_de_cartera u organizacion_impaga "Regulariza el pago para seguir emitiendo." Sin reintentos en bucle. El message ya dice cuál de las seis es.
503 Sin folios de ese tipo en ese ambiente codigo: "folios_agotados", tipo_dte, ambiente, reintentar_en_segundos y el header Retry-After (30–300 s) "Sin folios; la reposición ya se pidió." Reintenta pasado Retry-After con la misma Idempotency-Key. Un 503 sin codigo es otra cosa: escálalo.
422 Datos del documento inválidos message (y errors si viene) Corregir el documento (no quema folio).
422 Precondición de la empresa codigo: datos_emisor_incompletos, acteco_ausente, resolucion_produccion_ausente, tipo_no_autorizado_sii, certificado_no_utilizable o puerta_sii_cerrada Corregir la ficha de la empresa o el certificado: reenviar el mismo payload no lo arregla. Ver la tabla del 422 en POST /dte.
429 Límite de peticiones por minuto message, codigo: "demasiadas_solicitudes", retry_after (segundos) y el header Retry-After Backoff respetando Retry-After.
429 Cupo mensual del plan (emitidos_este_mes) o de la cartera (pool_dte) agotado message, emitidos_este_mes y, en una cartera, pool_dte No se reintenta: detén la emisión y avisa hasta cambiar de plan o hasta el mes siguiente.
429 Cuota del ambiente de desarrollo agotada message y cuota: {usados, limite} No se reintenta: pide ampliar la cuota o pasa a producción.
409 Idempotency-Key en curso o reusada entre empresas message (en curso, además reintentar_en_segundos y Retry-After) En curso: espera y reintenta con la misma clave. Entre empresas: usa claves distintas por empresa.

Errores del borde HTTP (cualquier endpoint)

Todo error es JSON con message en español y, en estos casos, un codigo estable para programar contra él. Ningún mensaje trae nombres de clases, rutas de archivo ni SQL.

HTTP codigo Cuándo Qué hacer
400 json_invalido El cuerpo no es JSON válido, o es JSON pero llegó sin Content-Type: application/json (por ejemplo curl -d sin cabecera). Antes se descartaba en silencio y la respuesta era «falta el campo tipo_dte». Corrige el JSON o agrega la cabecera.
401 no_autenticado Falta la credencial en rutas con sesión. En la API pública, sin X-Api-Key responde 401 con su propio mensaje. Envía la credencial.
404 no_encontrado La ruta no existe, el recurso no existe o no es de tu empresa, o el identificador no es un número entero (por ejemplo /dte/abc o /dte/99999999999999999999). El mensaje es genérico: no dice qué tabla ni qué id. Revisa la URL y el identificador.
405 metodo_no_permitido El método HTTP no existe para esa ruta. Trae el header Allow. Usa uno de los métodos de Allow.
413 cuerpo_demasiado_grande El cuerpo supera 20 MB. Divide el envío.
422 parametro_invalido Un parámetro de query llegó como arreglo (?origen[]=api). Las listas van separadas por comas: ?origen=api,mcp. Envía un valor simple o una lista con comas.
429 demasiadas_solicitudes Límite de peticiones (ver «Límites de peticiones»). Trae retry_after y el header Retry-After. Espera Retry-After y reintenta.
500 error_interno Falla nuestra; queda registrada con su causa. Reintenta más tarde; si persiste, escribe a soporte.

Filtros con valores que no existen se ignoran. GET /dte?origen=xyz o ?tipo_dte=abc no responden 422: el filtro inválido no se aplica y la lista sale sin él. Es deliberado, para no romper integraciones que ya mandan valores de más; valida tus filtros de tu lado.

Certificado vencido, no cargado o ilegible: la emisión responde 422 con codigo: "certificado_no_utilizable" y no consume folio. Se corrige subiendo un .p12 vigente en Empresa → Certificado.

Límites de peticiones

Límite Alcance
120 peticiones por minuto Por API Key y empresa emisora, sobre toda la API
30 POST por minuto sobre rutas de /dte Por API Key y empresa: cuentan emitir, reintentar, portal-link, simular-estado y las acciones sobre documentos recibidos
30 peticiones por minuto POST /sandbox/dte, por IP
10 peticiones por minuto GET /organizacion/ventas, por organización: todas sus claves suman

Emite desde una cola con concurrencia acotada, no en ráfagas. Superar un límite responde 429 con el header Retry-After, codigo: "demasiadas_solicitudes" y retry_after en segundos.

El límite por llave cuenta por llave y empresa, no por IP: dos integraciones que salen por la misma IP (por ejemplo, todos los clientes del MCP hospedado) no comparten cupo, y una llave inválida no gasta el de nadie (responde 401 sin contar). Los límites por IP (sandbox, registro) usan la IP real del cliente; la cabecera X-Forwarded-For que envía el cliente no la cambia.

Tamaño del documento

Lista Máximo Fuente
items en boletas (39, 41) 1.000 EnvioBOLETA_v11.xsd, Detalle maxOccurs=1000
items en el resto de los tipos 60 DTE_v10.xsd, Detalle maxOccurs=60
referencias 40 Referencia maxOccurs=40 en ambos esquemas
totales.impuestos_adicionales 20 ImptoReten maxOccurs=20
Cuerpo de la solicitud 20 MB 413 cuerpo_demasiado_grande

Son los topes del esquema del SII: un documento con más filas lo rechazaría el SII. Superarlos responde 422 con el error en la lista (errors.items) y no consume folio. Si una venta tiene más líneas, divídela en más de un documento.

Tiempos de respuesta y demoras

Qué esperar de cada llamada, y qué pasa cuando el SII se demora (27-oct-2026).

Dos clases de llamada

Llamada Qué hace Cuánto esperar
Consultas (GET) de la API y herramientas de lectura del MCP Leen lo que ya tenemos guardado: no esperan al SII. Lo que tarde nuestra base; no depende del SII.
POST /dte Valida, firma, timbra y encola el envío. No espera la respuesta del SII (ver Emisión asíncrona y estados). Lo que tarde la firma; la aceptación del SII llega después, por webhook o GET /dte/{id}.
POST /caf/solicitar (síncrono) Entra al portal del SII con tu certificado y pide los folios. Sí espera al SII. Medido el 27-oct-2026: una descarga completa, con su ingreso al SII, tardó en promedio 33 s y como máximo 78 s (31 corridas). El tope de la llamada es 300 s.
POST /caf/solicitar con Prefer: respond-async Responde 202 al instante y el trámite sigue en segundo plano. GET /caf/solicitudes/{id} trae plazo_esperado con el p50/p95 medido de los últimos 7 días.

El MCP llama a estas mismas rutas: sus tiempos son los de la API más la red entre tu cliente MCP y nosotros. El portal usa las mismas operaciones internas. Medimos cada respuesta por canal (API, MCP y portal) y cada trámite con el SII, y los plazos que te damos salen de esa medición, no de un número fijo.

Cuando el SII se demora

Los trámites con el SII —pedir folios, consultar el techo de timbraje, verificar una solicitud— dependen de su portal. Si se demora o no responde:

  • Los reintentos son nuestros: no repitas una solicitud que está en_cola, procesando o incierto (pedir de nuevo puede gastar un segundo rango en el SII).
  • plazo_esperado.con_demoras viene en true, y la página pública /estado muestra «demoras en trámites con el SII».
  • Respeta Retry-After y usa Idempotency-Key (ver POST /caf/solicitar).

Qué decirle a la persona: cinco situaciones

GET /caf/solicitudes/{id} y errores_cliente[] de GET /caf/actividad traen situacion, un titulo listo para mostrar y, cuando corresponde, la accion:

situacion Qué mostrar
en_proceso «En proceso: te avisamos cuando esté», con el plazo.
listo Terminó. Si el SII entregó menos folios de los pedidos, mensaje_cliente lo dice.
lo_resolvemos «Lo estamos resolviendo nosotros: no tienes que hacer nada».
accion_cliente «Necesitamos algo de ti», con accion.texto y, si aplica, accion.enlace o accion.reintentar_despues_de.
soporte «Escríbenos a soporte», con el solicitud_id o el código de referencia.

mensaje_cliente nunca cita la página del SII ni trae detalle técnico: ese detalle está en codigo, mensaje y error, para tu diagnóstico.

Representación impresa (PDF)

Todo DTE tiene una representación impresa generada on-demand desde el XML firmado (no se almacena), con el timbre electrónico (TED) impreso como código PDF417:

  • Boletas (39/41) → formato ticket 80mm (impresora de caja).
  • Resto (factura, NC/ND, guía) → formato carta.

Dos formas de obtenerla:

  • GET /dte/{id}/pdf → devuelve el PDF binario (application/pdf).
  • POST /dte?incluir=pdf → el 201 de la emisión incluye pdf_base64 (sin segunda llamada).

Enlace para el receptor

POST /dte/{id}/portal-link genera un enlace de acceso directo mediante un token único que el receptor abre sin inicio de sesión ni API Key para ver y descargar el documento. No es un recurso abierto ni indexable: el acceso se controla por el token, que es opaco y no enumerable (64 caracteres aleatorios, nunca expone IDs secuenciales). El enlace lleva X-Robots-Tag: noindex y su vigencia está atada a la retención legal del XML del documento (6 años). Llamadas repetidas reutilizan el token vigente.

Notas de crédito y débito

Antes de enviar al SII, validamos las referencias de una NC (61) o ND (56) a un documento propio ya emitido, para evitar rechazos del SII:

  • Mismo receptor. Una NC/ND debe ir al mismo receptor que el documento que corrige. Si el RUT difiere, la emisión se rechaza con 422 antes de enviar al SII (previene el código SII REF-3-751).
  • Timing automático. Si la NC/ND referencia un documento propio que el SII aún no ha recibido, el envío se retrasa automáticamente hasta que el SII lo registre (previene REF-3-750). Emites y el sistema gestiona el orden; no tienes que esperar.

Errores del SII

Cuando el SII rechaza o repara un DTE, la respuesta de GET /dte/{id} (y GET /dte) trae el objeto detalle_sii con la causa traducida a lenguaje de negocio (codigo, glosa, causa, solucion). Códigos frecuentes:

Código Significado
REF-3-750 Documento referenciado aún no recibido por el SII (NC/ND).
REF-3-751 RUT receptor distinto al del documento referenciado (NC/ND).
HED-2-210 Monto neto no cuadra con el detalle (ítems deben ir netos).
HED-2-260 Monto total no cuadra con los parciales (boletas: ítems con IVA).
TED-2-510 Error en el timbre electrónico (TED/CAF).
CRT-3-18 RUT receptor de la carátula inválido (boletas: 60803000-K).

Rechazos del SOBRE (distintos de los de arriba). Antes de mirar el contenido de un documento, el SII valida el envío que lo transporta. Si falla ahí, estado_sii trae uno de estos tres códigos y detalle_sii.codigo queda en null — el SII no emite un código granular para el sobre:

estado_sii Significado (manual SII) Qué revisar
RSC Rechazado por Error en Schema El XML no cumple el XSD. Es un problema nuestro: repórtalo a soporte.
RFR Rechazado por Error en Firma Certificado digital vencido, revocado o no reconocido por el SII.
RCT Rechazado por Error en Carátula Ver detalle_sii.caratula_enviada: normalmente fecha_resol no coincide con la que el SII registró para tu RUT, o quien firma no está autorizado a enviar DTE por la empresa.

Los estados SOK, CRT, FOK y PDR no son rechazos: son etapas intermedias de un envío que va bien (CRT es "Carátula OK"). El cierre exitoso del sobre es EPR.

Integración con IA (MCP)

Esta API es AI-native: puedes conectar un agente de IA (Claude, Cursor, etc.) directamente a tu facturación mediante nuestro servidor MCP (Model Context Protocol), y darle contexto a cualquier LLM con llms.txt.

1) Servidor MCP — local (npx):

{
  "mcpServers": {
    "facturador-pulsando": {
      "command": "npx",
      "args": ["-y", "@facturador-mcp-sii.cl/mcp"],
      "env": { "PULSANDO_API_KEY": "sk_test_..." }
    }
  }
}

2) Servidor MCP — remoto (OAuth 2.1): agrega un conector remoto apuntando a https://mcp.facturador.pulsandotech.cl/mcp; el cliente descubre el OAuth y el usuario autoriza con su API Key.

Herramientas expuestas (29): listar_empresas, listar_sucursales, emitir_dte, consultar_dte, consultar_estado_sii, reintentar_dte, listar_dtes, consultar_contribuyente, estado_folios, estado_solicitud_folios, tipos_habilitados, tipos_autorizados, documentos_recibidos, detalle_recibido, xml_recibido, sincronizar_rcv, listar_rcv, resumen_rcv, acciones_rcv, historial_rcv, propuesta_f29_sii, reporte_ventas, top_receptores, mi_suscripcion, mis_facturas, resumen_organizacion, salud_cartera, actividad_cartera y ventas_cartera. Las cuatro últimas son de la administración de la organización: están siempre registradas, pero sólo responden con una clave de organización con organizacion:read (ventas_cartera, además, con dte:read); con otra clave responden 403. El agente actúa con los permisos (scopes) de la API Key, así que los scopes por empresa se respetan.

El canal de IA corresponde a los planes Profesional, Empresa, Estudio contable y Plataforma; con otro plan puede responder 403 con upgrade_required: true.

Varias empresas (estudios contables). Si la clave es de una organización, el agente puede operar toda la cartera: cada herramienta acepta un parámetro empresa con el RUT emisor, y listar_empresas le dice cuáles administra. Así funciona "emite la factura de este mes para la Panadería" sin que el agente tenga que adivinar el RUT.

→ listar_empresas
← Panadería Don Pedro (76354771-K) · Ferretería La Clave (78211386-0)

→ emitir_dte  empresa="76354771-K"  tipo_dte=33 …
← Folio 1042, estado pendiente — emitido por la Panadería

Requiere el paquete @facturador-mcp-sii.cl/mcp 0.3.0 o superior.

3) llms.txt: resumen de la API para LLMs en https://www.facturador.pulsandotech.cl/llms.txt. Pégalo como contexto o úsalo con herramientas que lo carguen automáticamente.

4) Prompt de integración listo para copiar en tu asistente: ver PROMPT-MAESTRO-INTEGRACION.md en el repositorio de la documentación (reemplaza al prompt anterior de AI-INTEGRATION.md).

Seguridad y datos personales (Ley 21.719)

Esta API procesa datos personales (RUT, razón social, direcciones, correos). Consulta la sección "Seguridad y cumplimiento" del README para tus obligaciones como responsable de datos y las medidas que aplicamos.

Sandbox (probar sin cuenta)

Prueba tu integración sin registrarte y sin API Key. Valida el payload con las mismas reglas que la emisión real, pero no crea nada ni envía al SII.

Validar/simular una emisión sin cuenta

Prueba sin registrarte ni usar API Key. Envía el mismo cuerpo que a POST /dte: no se crea ningún documento, no se consumen folios y no se envía al SII. El emisor lo inyecta el sandbox (no lo envíes). Rate limit: 30 req/min por IP.

QUÉ COMPRUEBA (ampliado el 23-08-2026). Además de las reglas de campo, el sandbox ahora construye el XML del documento con el mismo constructor de la emisión real y le corre las mismas validaciones de coherencia. Eso incluye la identidad de totales:

MntTotal = MntNeto + MntExe + IVA + impuestos adicionales − retenciones

Antes de este cambio un descuadre pasaba el sandbox y lo rechazaba (o lo reparaba el SII) la emisión de verdad. Eso ya no ocurre con los totales.

VALIDA IGUAL QUE LA EMISIÓN REAL (desde el 17-09-2026), CON EL MISMO CÓDIGO. Además de lo anterior corre las mismas compuertas de contenido que POST /dte aplica antes de tomar folio: dígito verificador y rango del RUT del receptor, RUT marcador (66666666-6) en una factura, factura de compra (46) sin dirección o comuna del proveedor o con IVA en cero, retención parcial, transportista, tipo de cambio de exportación y traducción de los códigos de Aduana. El RUT se normaliza igual (76354771-K en un solo campo funciona en los dos). Y el 422 tiene la misma forma en los dos: message, errors y, en los de contenido, advertencias.

Y el esquema XSD oficial del SII, sobre el XML sin firmar. Desde el 8-oct-2026 la emisión real lo valida igual y ANTES de tomar folio: un documento que el esquema rechaza responde 422 en los dos canales, sin consumir folio (antes, en POST /dte, tomaba folio y quedaba en error_envio).

QUÉ NO PUEDE COMPROBAR, porque depende de tu cuenta: folios disponibles, certificado vigente, resolución y autorización del SII, habilitación del tipo en tu plan, el directorio de clientes (la emisión real completa la dirección de un receptor conocido), referencias a documentos tuyos (en una nota de crédito que referencia un documento emitido en la plataforma, el cod_ref se reemplaza al emitir por el que corresponda al monto) y si un local_id existe (se avisa en advertencias). estado_sii_simulado: "aceptado" es un literal fijo, no una predicción: el sandbox nunca le pregunta nada al SII.

Para una prueba fiel —documento completo, firmado, timbrado y validado contra el XSD— pide una empresa de pruebas: emite igual que la real y no consume folios ni toca al SII.

Request Body schema: application/json
required
tipo_dte
required
integer
Enum: 33 34 39 41 43 46 52 56 61 110 111 112

33 factura afecta · 34 factura exenta · 39 boleta · 41 boleta exenta · 43 liquidación · 46 factura de compra · 52 guía de despacho · 56 nota de débito · 61 nota de crédito · 110/111/112 exportación

fecha_emision
required
string <date>

Fecha de emisión (YYYY-MM-DD) en hora de Chile. No puede ser futura: una fecha mayor a hoy (hora Chile) devuelve 422, porque el SII rechaza el DTE (RCT).

ind_traslado
integer [ 1 .. 9 ]

Obligatorio para guía (52). 1=venta, 2=ventas por efectuar, 3=consignación, 4=entrega gratuita, 5=traslado interno, 6=otros, 7=devolución de mercaderías, 8=traslado exportación, 9=venta exportación

tipo_despacho
integer [ 1 .. 3 ]

Guía (52) y, desde el 6-oct-2026, facturas 33, 34 y 46 que amparan un traslado (va como ; en otro tipo no se escribe). 1=por cuenta del receptor, 2=por cuenta del emisor a instalaciones del cliente, 3=por cuenta del emisor a otras instalaciones.

forma_pago
integer
Enum: 1 2 3

1=contado, 2=crédito, 3=sin costo

ind_servicio
integer
Enum: 1 2 3 4 5 6

Indicador de servicio. Facturas y notas nacionales: 1=servicios periódicos domiciliarios, 2=otros servicios periódicos, 3=factura de servicio. Boletas (39/41) admiten además 4=espectáculo por cuenta de terceros. Exportación (110/111/112) usa OTRO catálogo (rama de exportación del XSD): 3=servicios, 4=servicios de hotelería (p. ej. alojamiento de un turista extranjero), 5=servicio de transporte terrestre internacional, 6=servicios calificados como exportación por el Servicio Nacional de Aduanas (con su resolución como referencia 812); ahí 1 y 2 no existen. Con 3, 4 o 5 no se exigen modalidad, cláusula ni vía. Un valor fuera del catálogo del tipo devuelve 422.

fecha_vencimiento
string <date>
ambiente
string
Enum: "certificacion" "produccion"

Para el portal, donde una empresa que ya está en producción puede emitir un documento de prueba en certificación. Con API Key se ignora: el documento sale en el ambiente de la llave (sk_test_ = certificacion, sk_live_ = produccion) y, si lo pedido era otro, la respuesta lo avisa en advertencias.

local_id
integer or null >= 1

Local desde el que se emite, para una empresa con varios negocios bajo el MISMO RUT (por ejemplo una botillería y una ferretería, con distinto giro y a veces distinta sucursal ante el SII).

El giro, el código de actividad, la dirección y el código de sucursal del SII salen del local, no de esta petición: acá va sólo el id. Da de alta tus locales en POST /locales y lístalos en GET /locales.

Si se omite, el documento se emite con los datos de la ficha de tu empresa, exactamente como antes de que existiera este campo.

Un local_id que no existe, o que está desactivado, devuelve 422 y no consume folio.

object (Receptor)

Opcional para boletas y NC/ND de boleta; obligatorio para el resto. En factura de compra (46) el receptor es el proveedor y direccion + comuna son estrictamente obligatorias: si faltan, el SII RECHAZA (HED-3-845 / HED-3-846) y el folio se pierde.

required
Array of objects (Item) [ 1 .. 1000 ] items

Máximo 60 ítems (DTE_v10.xsd) salvo en boletas 39/41, que admiten 1.000 (EnvioBOLETA_v11.xsd). Superarlo responde 422 en errors.items.

required
object (Totales)

Montos enteros, en pesos.

  • Facturas y notas (33, 34, 56, 61…): ítems netos; Σ items[].monto_item = monto_neto + monto_exento (salvo con descuento o recargo global) y monto_total = monto_neto + monto_exento + monto_iva (+ impuestos adicionales − retenciones). Una NC/ND de boleta también va con ítems netos.
  • Boletas (39/41): ítems con IVA incluido y Σ items[].monto_item = monto_total, sin los no facturables (ind_exe: 2), que van fuera del total, en <MontoNF>, sin IVA. Basta monto_total: con ítems exentos (ind_exe: 1) el monto_exento se deduce de los ítems marcados; si lo mandas, se usa el tuyo (si no cuadra con los ítems, advertencias lo dice). Si mandas el desglose, tiene que ser monto_neto = round((monto_total − monto_exento) / 1,19) y monto_iva = monto_total − monto_exento − monto_neto; un neto o un IVA que difiera en más de un peso responde 422.
Array of objects (Referencia) <= 40 items
object

Arriendo de inmuebles amoblados — rebaja del 11% del avalúo fiscal (Art. 17 del DL 825). Sólo en boleta 39 y factura 33.

El IVA se calcula sobre la renta menos el 11% anual del avalúo fiscal, prorrateado al período. Es obligatorio desde el 01-03-2020: la Ley 21.210 reemplazó "podrá" por "deberá", y el Oficio 3000/2016 ya había dicho que no es una facultad del arrendador. No rebajar no es ser conservador: es declarar IVA en exceso y recargarle al arrendatario un impuesto mayor al legal.

Tú mandas el avalúo; la rebaja, el IVA y la base los deriva el backend. No hay forma de mandar el monto de la rebaja ni el IVA, y es a propósito: un monto copiado del payload es un monto que se puede mandar mal, y un DTE no se corrige — se anula con nota de crédito.

🔴 El documento sale con el IVA distinto del 19% del neto, y está bien. Los Oficios 1183/2022 y 2356/2025 lo anuncian: "podría generarse alguna descuadratura o desajuste en los montos de los documentos emitidos, los que son aceptados por el Servicio... fue aceptado con reparos, circunstancia que no tiene efectos para el contribuyente". El SII avisa ese reparo por correo al emisor.

La rebaja NO es una exención: no va en monto_exento ni marcada con ind_exe. Cuatro oficios convergentes (783/2007, 1536/2020, 1183/2022, 2356/2025) dicen que "no constituye una liberación del impuesto... su única finalidad es determinar el monto sobre el cual se aplicará el tributo". Declararla como exenta obliga además a proporcionalizar el crédito fiscal (Art. 23 N°3) y le reduce al cliente lo que recupera.

Las dos convenciones, según el documento:

Documento Los montos van El IVA sale de
Boleta 39 BRUTOS (con IVA) (total − rebaja) × 19/119
Factura 33 NETOS (neto − rebaja) × 19%

Si la rebaja supera la renta del período, el IVA es 0 y nunca negativo (la operación sigue gravada: el Oficio 1536/2020 aclara que tampoco corresponde emitir una factura exenta por eso).

La deducción queda escrita en la glosa del documento (DscItem), que es lo que los oficios exigen informar.

Requiere que tu cuenta tenga habilitada la función: escríbenos.

object (Transportista)

Va al bloque del documento en la guía de despacho (52) y, desde el 6-oct-2026, en las facturas 33, 34 y 46 que amparan un traslado de bienes (el mismo bloque, sin ind_traslado). En cualquier otro tipo se descarta y la respuesta lo dice en advertencias. dir_dest y cmna_dest son obligatorios para 52. Desde el 1-nov-2026 la Res. Ex. SII N°154/2025 exige además chofer (rut_chofer, dv_chofer, nombre_chofer), patente_carro, fecha_salida, hora_salida y fecha_llegada. El SII no rechaza la guía si faltan (su ausencia se sanciona en fiscalización), así que la API tampoco: sólo valida el formato, y el 201 (y el sandbox) avisan en advertencias lo que falta (desde el 14-oct-2026). Patente, transportista y chofer se dan por declarados con sin_informacion: true; las fechas y la hora, no. La patente del carro sola no genera el aviso.

object (OrigenDespacho)

Desde dónde salen los bienes (formato DTE v2.5, campo 44 DirOrigen: «dirección desde donde se despachan bienes»; Res. Ex. SII 154: origen efectivo del traslado). Por defecto, la dirección de la empresa (o del local_id que emite), como siempre. Úsalo cuando el despacho sale de una bodega o sucursal distinta.

Una de dos formas, no las dos: local_id (un local tuyo de GET /locales: se toman sólo su dirección, comuna y ciudad) o direccion + comuna (ciudad opcional; sin ella el documento sale sin CiudadOrigen).

Va en origen_despacho, no en origen: en la respuesta de un DTE origen es el canal por el que se emitió (portal, api o mcp).

Cambia sólo DirOrigen, CmnaOrigen y CiudadOrigen: nunca el RUT, la razón social, el giro ni el código de sucursal (CdgSIISucur es de la sucursal que EMITE: eso lo dice local_id).

Se escribe en la guía de despacho (52) y en las facturas 33, 34 y 46 que amparan un traslado (con transportista). En otro documento se descarta y la respuesta lo dice en advertencias. Un local_id que no existe, está desactivado o no tiene dirección y comuna responde 422 sin consumir folio.

object (Impresion)

Datos que se imprimen en el documento pero NO viajan al SII: su esquema no los tiene. Se guardan junto al documento y aparecen en el ticket. Todo opcional.

Pensado para retail: identificar quién atendió, en qué local y con qué medio pagó el cliente.

medio_pago NO es forma_pago. forma_pago es el FmaPago del SII (1=Contado, 2=Crédito, 3=Sin costo) y describe la condición de venta: "Efectivo", "Débito" y "Transferencia" son los tres forma_pago: 1. Son dos cosas distintas y usar una por la otra declararía mal la condición de venta ante el SII.

Para el código de caja y de vendedor —que sí viajan al SII— usa referencias[].cod_caja y referencias[].cod_vendedor, disponibles solo en boletas.

object (Exportacion)

Obligatorio en los tipos 110/111/112 (factura, nota de débito y nota de crédito de exportación), con tipo_moneda y tipo_cambio adentro.

Montos: los de items y totales van en la moneda de tipo_moneda y admiten hasta 4 decimales (23.1, 35978.29). Con tipo_cambio el backend arma la sección en pesos chilenos (<OtraMoneda>) que el SII exige aunque su esquema la dé por opcional (rechazo HED-3-834).

Códigos de Aduana (Anexo 51): el SII exige el código NUMÉRICO en cláusula, modalidad, vía de transporte, puertos, bulto, países y forma de pago. Puedes mandar el número (5, 906, 225) o el texto ("FOB", "SAN ANTONIO", "US", "España") y el backend lo traduce con la tabla oficial de Aduana. Si un texto no se puede traducir sin ambigüedad (por ejemplo "CONTENEDOR NO REFRIGERADO", que puede ser de 20 o de 40 pies) responde 422 antes de tomar folio con los valores válidos: el esquema del SII rechazaría ese documento igual. Un código numérico que no esté en nuestra tabla se deja pasar (Aduana agrega códigos).

Lo que el SII exija según la operación y falte (por ejemplo país de destino en una exportación de bienes) no lo bloqueamos: se descubre en el estado asíncrono (estado_local, glosa_sii).

Dos escenarios típicos:

  • Exportación de mercadería: via_transporte, pais_receptor, pais_destino y normalmente clausula/tot_clausula (Incoterm).
  • Exportación de servicios (sin embarque físico): basta tipo_moneda + tipo_cambio.
Array of objects <= 20 items

Sólo exportación (110/111/112). Descuentos (D) y recargos (R) GLOBALES del documento (<DscRcgGlobal>), en porcentaje (%) o en monto ($, en tipo_moneda, con decimales). El caso típico lo pide el propio SII en su set de pruebas: el flete y el seguro van en exportacion.flete/exportacion.seguro y además como dos recargos globales en monto, con glosa FLETE y SEGURO, y suman a totales.monto_exento/monto_total. Una comisión en el extranjero calculada sobre la cláusula también va como recargo en monto. En otros tipos la clave no existe y se avisa en advertencias.

Array of objects <= 20 items

Sólo liquidación-factura (43). Comisiones y otros cargos que el mandatario le cobra al mandante; RESTAN del total (ver totales.monto_total). Opcional: el SII no las exige en todos los casos. Ver el ejemplo liquidacion43.

permitir_duplicado
boolean
Default: false

Escotilla del freno de reemisión por contenido: true significa "sí, ya hay un documento idéntico reciente, es otra venta, emite igual".

Equivale al header X-Permitir-Duplicado: true. No viaja al SII y no forma parte del contenido del documento (no cambia la huella de tu Idempotency-Key).

Responses

Request samples

Content type
application/json
{
  • "tipo_dte": 33,
  • "fecha_emision": "2019-08-24",
  • "ind_traslado": 1,
  • "tipo_despacho": 1,
  • "forma_pago": 1,
  • "ind_servicio": 1,
  • "fecha_vencimiento": "2019-08-24",
  • "ambiente": "certificacion",
  • "local_id": 3,
  • "receptor": {
    },
  • "items": [
    ],
  • "totales": {
    },
  • "referencias": [
    ],
  • "rebaja_arriendo": {
    },
  • "transportista": {
    },
  • "origen_despacho": {
    },
  • "impresion": {
    },
  • "exportacion": {
    },
  • "descuentos_globales": [
    ],
  • "comisiones": [
    ],
  • "permitir_duplicado": false
}

Response samples

Content type
application/json
{
  • "sandbox": true,
  • "message": "string",
  • "simulacion": {
    },
  • "advertencias": [
    ],
  • "entrega_receptor": {
    }
}

Empresas (multi-RUT)

Qué empresas emisoras administra tu API Key. Punto de partida para las claves de organización (estudios contables, holdings): responde la cartera sin exigir que hayas elegido una empresa.

Empresas que administra tu API Key

Responde por qué RUT emisores puede operar esta clave.

No exige haber seleccionado empresa: pedirte el RUT que justamente vienes a averiguar sería circular (las lecturas de /organizacion/* tampoco lo exigen, porque son de toda la cartera). Por eso es el punto de partida de cualquier integración de estudio contable — y lo que llama la herramienta listar_empresas del MCP.

Con una clave de una organización suspendida responde 403 con codigo: "organizacion_suspendida" y no lista la cartera.

Responde con la misma forma para los dos tipos de clave; mira requiere_seleccion para saber cómo seguir:

  • false → clave de una empresa. No envíes X-Empresa-RUT.
  • true → clave de organización. Envía X-Empresa-RUT en cada llamada.

El campo ambiente de cada empresa importa: mock es el ambiente de desarrollo (no habla con el SII); certificacion emite contra maullin con folios de prueba; produccion factura de verdad en palena. Es el ambiente de la empresa, no el de la llave: una sk_test_ sobre una empresa en producción emite en certificación. El ambiente real de cada documento viene en GET /dte/{id} → ambiente.

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/json
Example
{
  • "alcance": "organizacion",
  • "organizacion": {
    },
  • "requiere_seleccion": true,
  • "como_seleccionar": "Envía el header X-Empresa-RUT con el RUT de la empresa emisora en cada llamada.",
  • "data": [
    ]
}

Administración de la organización

Lecturas de administración de un estudio contable u holding: resumen y cobro, salud y actividad de la cartera, y el consolidado de ventas. Sólo lectura: agregar o quitar empresas, usuarios, la suscripción y las claves se hace en el portal.

Requieren una clave de organización vigente con el permiso organizacion:read, que se elige al crear la clave (ninguna clave existente lo trae). GET /organizacion/ventas exige además dte:read: son documentos de cada empresa, y es el mismo permiso que GET /reportes/ventas. No llevan X-Empresa-RUT: la consulta es de toda la cartera vigente; las empresas retiradas de la cartera no aparecen.

No dependen del ambiente de la clave (salvo las ventas): una sk_test_ con organizacion:read lee el cobro, la salud y la actividad reales de la organización. Dale el permiso sólo a claves que puedan verlo.

403 con… Significa Qué hacer
codigo: "requiere_llave_de_organizacion" La clave es de una empresa Crea en el portal una clave de organización con organizacion:read
codigo: "organizacion_suspendida" La organización no está vigente Revisa la suscripción del estudio en el portal
«no tiene el permiso requerido: organizacion:read» Clave de organización sin el permiso Crea una clave nueva con el permiso (las claves no se editan)
«no tiene el permiso requerido: dte:read» (sólo en /organizacion/ventas) La clave tiene organizacion:read pero no dte:read Crea una clave nueva con los dos permisos

GET /organizacion/ventas tiene además su propio límite: 10 peticiones por minuto por organización, sumando todas sus claves. Al pasarlo responde 429 con codigo: "demasiadas_solicitudes", retry_after y el header Retry-After.

Resumen de la organización, su cobro y su cupo

La organización dueña de la clave, su plan, lo que paga por mes y el cupo de DTE de toda la cartera. Es lo mismo que el socio ve en el panel del estudio.

Montos: precio_por_rut_neto, mensual_neto y anual_neto son NETOS (los precios se publican «+ IVA»). mensual_con_iva y anual_con_iva son lo que se cobra de verdad; no recalcules el IVA de tu lado. El anual son 10 meses.

Se cobra por cada empresa activa de la cartera, esté en certificación o en producción (cobro.empresas_facturables); empresas_en_cartera incluye además las suspendidas sin retirar. pool.cupo = 0 significa sin tope, y entonces pool.disponible es null.

Nada de medios de pago, tokens de la pasarela ni correos de usuarios. Requiere clave de organización con organizacion:read.

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "organizacion": {
    },
  • "plan": {
    },
  • "empresas_en_cartera": 2,
  • "cobro": {
    },
  • "pool": {
    }
}

Salud de cada empresa de la cartera

El puntaje (0–100) y la banda de cada empresa de la cartera vigente, con lo que le falta hacer, desde la foto diaria del centro de mando. Ordenadas de la peor a la mejor; una empresa sin foto viene con banda: "sin_foto" y score: null.

pendientes[].quien dice de quién es la tarea: empresa (la tiene que hacer la empresa o el estudio) o pulsando (la resolvemos nosotros). Las tareas internas de la plataforma no se muestran. Requiere clave de organización con organizacion:read.

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "por_banda": {
    },
  • "foto_at": "string"
}

Actividad de la API en la cartera

Las llamadas a la API de las empresas de la cartera vigente desde desde: total, cuántas fallaron (status ≥ 400), por origen (api, mcp, portal), por empresa y las 50 más recientes. Sin IP, sin user-agent, sin cuerpos ni mensajes de error internos.

En ultimas[].path las partes variables de la ruta vienen enmascaradas: un RUT (con o sin puntos y dígito verificador) sale como {rut}, un número como {id} y un UUID o token largo como {token}. Por ejemplo, api/public/v1/contribuyentes/{rut} o api/public/v1/dte/{id}/pdf.

desde es opcional (por defecto, los últimos 7 días) y puede ir hasta 90 días atrás; una fecha anterior o futura responde 422. Ojo: los registros se conservan retencion_dias días, así que pedir más atrás no trae nada más viejo que eso. Requiere clave de organización con organizacion:read.

Authorizations:
ApiKeyAuth
query Parameters
desde
string <date>

Fecha YYYY-MM-DD, entre hoy y 90 días atrás (hora de Chile). Por defecto, hace 7 días.

Responses

Response samples

Content type
application/json
{
  • "periodo": {
    },
  • "retencion_dias": 0,
  • "total": 0,
  • "errores": 0,
  • "por_origen": {
    },
  • "por_empresa": [
    ],
  • "ultimas": [
    ]
}

Ventas consolidadas de la cartera

Las ventas válidas de cada empresa de la cartera vigente en el rango, y la suma. Por cada empresa, los campos son los mismos que daría GET /reportes/ventas de esa empresa sumado en el mismo rango (misma fórmula: ver GET /reportes/ventas), y totales los suma. totales.suma_total es la suma de las ventas válidas, no de total_bruto_emitido.

  • Ambiente: el de la llave, igual que en /reportes/ventas: sk_test_ suma documentos de certificación y sk_live_ los de producción, en todas las empresas. Cada fila dice en ambiente qué documentos sumó (una empresa de desarrollo se queda en mock).
  • Rango: desde y hasta en YYYY-MM-DD; por defecto, desde el día 1 del mes en curso hasta hoy (hora de Chile). Hasta 366 días contando los dos extremos; hasta anterior a desde o un rango más largo responde 422.
  • Las pruebas que emitió Facturador Pulsando con el RUT de la empresa (marca_operativa) no se suman.
  • Una empresa que no se puede leer no bota el resto: va a errores[] con su codigo y las demás se suman. empresa_suspendida y upgrade_required (el plan de esa empresa no trae la función ERP) son los mismos cortes que tendría su propio /reportes/ventas; empresa_no_disponible es un problema transitorio: reintenta.

Cuesta dos consultas agregadas por empresa: con carteras grandes, pide períodos acotados. Límite propio: 10 peticiones por minuto por organización (todas sus claves suman); al pasarlo, 429 con Retry-After. Requiere clave de organización con organizacion:read y dte:read.

Authorizations:
ApiKeyAuth
query Parameters
desde
string <date>

Fecha YYYY-MM-DD. Por defecto, el día 1 del mes en curso.

hasta
string <date>

Fecha YYYY-MM-DD, igual o posterior a desde. Por defecto, hoy.

Responses

Response samples

Content type
application/json
{
  • "periodo": {
    },
  • "empresas": [
    ],
  • "totales": {
    },
  • "errores": [
    ]
}

Emisión y consulta de DTE

Emisión y consulta de documentos tributarios electrónicos

Emitir un DTE

Crea y encola un DTE para envío al SII. El bloque emisor se toma automáticamente de tu empresa ("Mi empresa"); no lo envíes.

Reglas por tipo de documento:

  • Boletas (39/41): receptor es opcional (consumidor final).
  • NC/ND (56/61) de una boleta: receptor opcional (hereda consumidor final).
  • Guía de despacho (52): ind_traslado obligatorio y destino (transportista.dir_dest + transportista.cmna_dest) obligatorio.
  • Datos del traslado (Res. Ex. SII N°154/2025, exigible desde el 1-nov-2026; aviso, nunca 422): una guía 52 —o una factura 33, 34 o 46 que trae transportista— sin transportista.fecha_salida, hora_salida o fecha_llegada, o sin patente, RUT del transportista o chofer (RUT y nombre) y sin transportista.sin_informacion: true, se emite igual y el 201 (y el sandbox) lo dicen en una línea de advertencias que empieza con «Res. Ex. SII N°154/2025, exigible desde el 1-nov-2026» y nombra lo que falta. El SII no la rechaza; la falta es sancionable. La patente del carro sola no genera el aviso (un vehículo sin remolque no la tiene).
  • NC/ND (56/61): si el documento referenciado lo emitió la plataforma en el mismo ambiente, el motivo (cod_ref) se deriva del monto (total → anula, 0 → corrige texto, parcial → corrige montos) y reemplaza al que envíes. Si lo emitiste en otro sistema, manda cod_ref explícito (1 anula, 2 corrige texto, 3 corrige montos): sin él se declara ante el SII como anulación (1), y el 201 lo advierte con una línea en advertencias por referencia (el sandbox, también).
  • NC/ND de una boleta: los ítems van netos, como en toda nota.
  • Boletas (39/41), totales: los ítems van con IVA incluido y Σ items[].monto_item = monto_total, sin contar los ítems no facturables (ind_exe: 2): van fuera de monto_total, salen en <MontoNF> y no se les calcula IVA. Si los sumas dentro de monto_total se emite igual que antes, con IVA sobre ellos, y advertencias lo dice. Basta con mandar sólo monto_total: la plataforma calcula el desglose y, si hay ítems exentos (ind_exe: 1), el monto_exento se deduce de los ítems marcados (la suma de su monto_item), así que lo exento no paga IVA. Si mandas monto_exento, se usa el tuyo; si no cuadra (±1 peso) con los ítems marcados, advertencias lo dice. Si mandas monto_neto o monto_iva, tienen que ser monto_neto = round((monto_total − monto_exento) / 1,19) y monto_iva = monto_total − monto_exento − monto_neto: un neto o un IVA que difiera en más de un peso responde 422. Se emiten sin deducir el exento, con una línea en advertencias, un neto/IVA declarado sobre el total completo y una 39 con todos los ítems exentos (va en una 41).
  • Plazos de las NC/ND (advertencia, nunca 422): con la fecha del documento referenciado conocida (de esta cuenta, o fecha_ref), se advierte una NC que anula (cod_ref 1) una 33, 34, 46 o una ND —o una ND que anula una NC— más allá del período tributario siguiente al del documento (Res. Ex. SII N°45/2003; fuera de plazo la rebaja del débito se pide con el formulario 2117, art. 126 del Código Tributario), y una NC que corrige montos (cod_ref 3, con monto) sobre una 33, 43 o 46 de hace más de 6 meses (art. 70 del DL 825). La nota se emite igual.
  • Factura de compra (46): el receptor es el proveedor (típicamente extranjero). direccion y comuna son obligatorias — sin ellas el SII RECHAZA (HED-3-845 / HED-3-846) y el folio se pierde. El giro es recomendado (si falta, el SII observa con REPARO HED-1-844, pero el documento es válido). El IVA lo retiene el comprador (retención total).

Validación de notas (NC/ND) que referencian un documento propio:

  • El receptor de la nota debe coincidir con el del documento referenciado. Si difiere, se devuelve 422 (con el mensaje en message) antes de enviar al SII (previene el código SII REF-3-751).
  • Si el documento referenciado aún no fue recibido por el SII, el envío se retrasa automáticamente hasta que el SII lo registre (previene REF-3-750). No es necesario que esperes: el sistema gestiona el orden de envío.

PDF en la misma respuesta (paridad caja, 1 sola llamada): agrega ?incluir=pdf para que el 201 incluya pdf_base64 + pdf_mime con la representación impresa lista para imprimir.

⚠️ Si el PDF falla, el documento IGUAL SE EMITIÓ. Son dos cosas distintas y confundirlas cuesta caro: la respuesta trae emitido: true, el folio ya asignado y pdf.disponible: false. Pide la impresión después con GET /dte/{id}/pdf. No reintentes la emisión: crearías un documento duplicado que hay que anular con nota de crédito.

Freno de reemisión por contenido (automático). Además de la Idempotency-Key, si el mismo emisor manda un documento con el mismo tipo, fecha de emisión, receptor, local, totales, ítems y referencias, desde el tercero dentro de 30 minutos dejamos de emitir folios nuevos y te devolvemos uno que ya existe, con duplicado: true y motivo_duplicado: "contenido" (status 201, más el header X-Dte-Duplicado: contenido). Los dos primeros documentos idénticos se emiten normalmente. Con la configuración por defecto el freno no bloquea boletas 39/41 (en ellas sólo registra lo que habría hecho): ahí tu Idempotency-Key es la única defensa contra el duplicado.

Existe porque la idempotencia por clave sólo protege a quien reusa la clave: un cliente cuyo POS acuñaba una marca de tiempo nueva en cada reintento emitió 52 boletas idénticas en 24 minutos.

Si de verdad es otra venta idéntica (dos clientes compran lo mismo al mismo precio), indícalo explícitamente con el header X-Permitir-Duplicado: true (o el campo permitir_duplicado: true en el cuerpo) y una Idempotency-Key nueva, y se emite un folio nuevo. Con la clave de la petición anterior te vuelve el documento anterior: la idempotencia se resuelve antes que el freno.

Idempotencia (recomendado en producción): envía el header Idempotency-Key con un valor estable por venta: se genera una sola vez cuando nace la venta, se guarda junto a ella y se reusa en todos los reintentos (si usas un UUID, es uno por venta, nunca uno nuevo por intento). Si un reintento de red repite la petición con la MISMA clave, no se emite un segundo DTE ni se consume otro folio: se devuelve la respuesta original con el header Idempotent-Replayed: true. Si el original aún está en curso se responde 409 (reintenta en unos segundos: el cuerpo trae reintentar_en_segundos y viene el header Retry-After); si reutilizas la misma clave con un cuerpo distinto, 422. La clave es única por empresa.

Una clave ESTABLE por venta es lo correcto (por ejemplo {id_de_la_venta}-{hash_del_cuerpo}), no una marca de tiempo nueva por intento: la clave es lo que distingue un reintento de una venta nueva, y si cambia en cada intento la idempotencia no protege nada. Y no quedas atrapado en el 409: una reserva cuyo proceso murió expira sola pasado el plazo, así que la misma clave vuelve a poder emitir.

El emisor no va en el cuerpo: sale de la ficha de la empresa. Razón social, giro, dirección y el código de actividad económica (acteco) se leen de la empresa dueña de la API key. El SII exige acteco en todo documento salvo las boletas (39/41): si la empresa no lo tiene configurado, la emisión responde 422 explicándolo y no consume folio. Se configura una sola vez en el panel (Empresa → «Código de actividad») o con PATCH /api/v1/empresa (acteco, 6 dígitos). Aplica a facturas, notas, guías de despacho (52), liquidaciones (43) y documentos de exportación.

La emisión es asíncrona después del 201. La respuesta confirma que el documento se construyó, se firmó y tomó folio; el envío al SII ocurre en segundos, en segundo plano. El resultado llega por los webhooks dte.enviado → dte.aceptado / dte.rechazado / dte.reparado, y si el documento no logra salir (falla nuestra validación previa, certificado, SII caído) por dte.error_envio. Los webhooks se entregan por separado y con reintentos, así que pueden llegar en otro orden: el estado lo dice GET /dte/{id}, que también sirve si no usas webhooks. Un error_envio lo sigue trabajando la plataforma unos días (vuelve a consultar al SII y, si el SII no tiene el documento, lo reenvía con el mismo folio: ver la tabla de estados); si no se resuelve solo, se sale con POST /dte/{id}/reintentar, nunca reemitiendo (el folio ya está tomado y un documento nuevo declararía dos veces la misma venta).

Lo que falta en la ficha de la empresa se dice ANTES de tomar folio. Acteco, resolución del SII (sólo en producción) y autorización del SII para ese tipo en ese ambiente (sólo en producción, y sólo si el SII ya dijo que no) se comprueban antes de asignar folio: responden 422 con un codigo estable y no consumen folio. Ver la tabla del 422.

Un 422 nunca toca el contador de folios. Las reglas del documento (totales, desglose, referencias, receptor) y el certificado se verifican antes de asignar folio. Si algo falla de nuestro lado después de asignarlo (un 500), el folio no se pierde: vuelve al contador o lo usa la siguiente emisión. Y un 500 no deja tomada la Idempotency-Key: reintentar con la misma clave vuelve a intentar la emisión en vez de responder 409.

Authorizations:
ApiKeyAuth
query Parameters
incluir
string
Value: "pdf"

Si vale pdf, la respuesta 201 adjunta la representación impresa como pdf_base64 (+ pdf_mime). Se acepta también el alias include=pdf.

formato
string
Enum: "carta" "pos80"

Sólo tiene efecto junto a incluir=pdf: elige el formato del pdf_base64. Mismos valores y misma precedencia que en GET /dte/{id}/pdf.

copia
string
Enum: "cedible" "tributaria"

Sólo tiene efecto junto a incluir=pdf. Por defecto cedible.

header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Idempotency-Key
string <= 255 characters

Clave estable por venta (generada una vez, guardada y reusada en cada reintento; nunca una nueva por intento) para hacer la petición idempotente. Un reintento con la misma clave devuelve el mismo DTE (header Idempotent-Replayed: true) sin emitir uno nuevo.

La clave es por empresa emisora. Si tu ERP numera las facturas por empresa y repite F-1001 en dos de ellas, no hay problema. Si una clave colisiona entre empresas distintas respondemos 409 antes que devolverte el documento equivocado.

X-Permitir-Duplicado
boolean

Escotilla del freno de reemisión por contenido: true significa "sí, ya sé que hay un documento idéntico reciente, es otra venta, emite un folio nuevo".

Úsalo sólo cuando el duplicado sea legítimo, y con una Idempotency-Key nueva: con la clave de la petición anterior vuelve el documento anterior. Equivale al campo permitir_duplicado: true del cuerpo (para integraciones que no pueden agregar headers).

Request Body schema: application/json
required
tipo_dte
required
integer
Enum: 33 34 39 41 43 46 52 56 61 110 111 112

33 factura afecta · 34 factura exenta · 39 boleta · 41 boleta exenta · 43 liquidación · 46 factura de compra · 52 guía de despacho · 56 nota de débito · 61 nota de crédito · 110/111/112 exportación

fecha_emision
required
string <date>

Fecha de emisión (YYYY-MM-DD) en hora de Chile. No puede ser futura: una fecha mayor a hoy (hora Chile) devuelve 422, porque el SII rechaza el DTE (RCT).

ind_traslado
integer [ 1 .. 9 ]

Obligatorio para guía (52). 1=venta, 2=ventas por efectuar, 3=consignación, 4=entrega gratuita, 5=traslado interno, 6=otros, 7=devolución de mercaderías, 8=traslado exportación, 9=venta exportación

tipo_despacho
integer [ 1 .. 3 ]

Guía (52) y, desde el 6-oct-2026, facturas 33, 34 y 46 que amparan un traslado (va como ; en otro tipo no se escribe). 1=por cuenta del receptor, 2=por cuenta del emisor a instalaciones del cliente, 3=por cuenta del emisor a otras instalaciones.

forma_pago
integer
Enum: 1 2 3

1=contado, 2=crédito, 3=sin costo

ind_servicio
integer
Enum: 1 2 3 4 5 6

Indicador de servicio. Facturas y notas nacionales: 1=servicios periódicos domiciliarios, 2=otros servicios periódicos, 3=factura de servicio. Boletas (39/41) admiten además 4=espectáculo por cuenta de terceros. Exportación (110/111/112) usa OTRO catálogo (rama de exportación del XSD): 3=servicios, 4=servicios de hotelería (p. ej. alojamiento de un turista extranjero), 5=servicio de transporte terrestre internacional, 6=servicios calificados como exportación por el Servicio Nacional de Aduanas (con su resolución como referencia 812); ahí 1 y 2 no existen. Con 3, 4 o 5 no se exigen modalidad, cláusula ni vía. Un valor fuera del catálogo del tipo devuelve 422.

fecha_vencimiento
string <date>
ambiente
string
Enum: "certificacion" "produccion"

Para el portal, donde una empresa que ya está en producción puede emitir un documento de prueba en certificación. Con API Key se ignora: el documento sale en el ambiente de la llave (sk_test_ = certificacion, sk_live_ = produccion) y, si lo pedido era otro, la respuesta lo avisa en advertencias.

local_id
integer or null >= 1

Local desde el que se emite, para una empresa con varios negocios bajo el MISMO RUT (por ejemplo una botillería y una ferretería, con distinto giro y a veces distinta sucursal ante el SII).

El giro, el código de actividad, la dirección y el código de sucursal del SII salen del local, no de esta petición: acá va sólo el id. Da de alta tus locales en POST /locales y lístalos en GET /locales.

Si se omite, el documento se emite con los datos de la ficha de tu empresa, exactamente como antes de que existiera este campo.

Un local_id que no existe, o que está desactivado, devuelve 422 y no consume folio.

object (Receptor)

Opcional para boletas y NC/ND de boleta; obligatorio para el resto. En factura de compra (46) el receptor es el proveedor y direccion + comuna son estrictamente obligatorias: si faltan, el SII RECHAZA (HED-3-845 / HED-3-846) y el folio se pierde.

required
Array of objects (Item) [ 1 .. 1000 ] items

Máximo 60 ítems (DTE_v10.xsd) salvo en boletas 39/41, que admiten 1.000 (EnvioBOLETA_v11.xsd). Superarlo responde 422 en errors.items.

required
object (Totales)

Montos enteros, en pesos.

  • Facturas y notas (33, 34, 56, 61…): ítems netos; Σ items[].monto_item = monto_neto + monto_exento (salvo con descuento o recargo global) y monto_total = monto_neto + monto_exento + monto_iva (+ impuestos adicionales − retenciones). Una NC/ND de boleta también va con ítems netos.
  • Boletas (39/41): ítems con IVA incluido y Σ items[].monto_item = monto_total, sin los no facturables (ind_exe: 2), que van fuera del total, en <MontoNF>, sin IVA. Basta monto_total: con ítems exentos (ind_exe: 1) el monto_exento se deduce de los ítems marcados; si lo mandas, se usa el tuyo (si no cuadra con los ítems, advertencias lo dice). Si mandas el desglose, tiene que ser monto_neto = round((monto_total − monto_exento) / 1,19) y monto_iva = monto_total − monto_exento − monto_neto; un neto o un IVA que difiera en más de un peso responde 422.
Array of objects (Referencia) <= 40 items
object

Arriendo de inmuebles amoblados — rebaja del 11% del avalúo fiscal (Art. 17 del DL 825). Sólo en boleta 39 y factura 33.

El IVA se calcula sobre la renta menos el 11% anual del avalúo fiscal, prorrateado al período. Es obligatorio desde el 01-03-2020: la Ley 21.210 reemplazó "podrá" por "deberá", y el Oficio 3000/2016 ya había dicho que no es una facultad del arrendador. No rebajar no es ser conservador: es declarar IVA en exceso y recargarle al arrendatario un impuesto mayor al legal.

Tú mandas el avalúo; la rebaja, el IVA y la base los deriva el backend. No hay forma de mandar el monto de la rebaja ni el IVA, y es a propósito: un monto copiado del payload es un monto que se puede mandar mal, y un DTE no se corrige — se anula con nota de crédito.

🔴 El documento sale con el IVA distinto del 19% del neto, y está bien. Los Oficios 1183/2022 y 2356/2025 lo anuncian: "podría generarse alguna descuadratura o desajuste en los montos de los documentos emitidos, los que son aceptados por el Servicio... fue aceptado con reparos, circunstancia que no tiene efectos para el contribuyente". El SII avisa ese reparo por correo al emisor.

La rebaja NO es una exención: no va en monto_exento ni marcada con ind_exe. Cuatro oficios convergentes (783/2007, 1536/2020, 1183/2022, 2356/2025) dicen que "no constituye una liberación del impuesto... su única finalidad es determinar el monto sobre el cual se aplicará el tributo". Declararla como exenta obliga además a proporcionalizar el crédito fiscal (Art. 23 N°3) y le reduce al cliente lo que recupera.

Las dos convenciones, según el documento:

Documento Los montos van El IVA sale de
Boleta 39 BRUTOS (con IVA) (total − rebaja) × 19/119
Factura 33 NETOS (neto − rebaja) × 19%

Si la rebaja supera la renta del período, el IVA es 0 y nunca negativo (la operación sigue gravada: el Oficio 1536/2020 aclara que tampoco corresponde emitir una factura exenta por eso).

La deducción queda escrita en la glosa del documento (DscItem), que es lo que los oficios exigen informar.

Requiere que tu cuenta tenga habilitada la función: escríbenos.

object (Transportista)

Va al bloque del documento en la guía de despacho (52) y, desde el 6-oct-2026, en las facturas 33, 34 y 46 que amparan un traslado de bienes (el mismo bloque, sin ind_traslado). En cualquier otro tipo se descarta y la respuesta lo dice en advertencias. dir_dest y cmna_dest son obligatorios para 52. Desde el 1-nov-2026 la Res. Ex. SII N°154/2025 exige además chofer (rut_chofer, dv_chofer, nombre_chofer), patente_carro, fecha_salida, hora_salida y fecha_llegada. El SII no rechaza la guía si faltan (su ausencia se sanciona en fiscalización), así que la API tampoco: sólo valida el formato, y el 201 (y el sandbox) avisan en advertencias lo que falta (desde el 14-oct-2026). Patente, transportista y chofer se dan por declarados con sin_informacion: true; las fechas y la hora, no. La patente del carro sola no genera el aviso.

object (OrigenDespacho)

Desde dónde salen los bienes (formato DTE v2.5, campo 44 DirOrigen: «dirección desde donde se despachan bienes»; Res. Ex. SII 154: origen efectivo del traslado). Por defecto, la dirección de la empresa (o del local_id que emite), como siempre. Úsalo cuando el despacho sale de una bodega o sucursal distinta.

Una de dos formas, no las dos: local_id (un local tuyo de GET /locales: se toman sólo su dirección, comuna y ciudad) o direccion + comuna (ciudad opcional; sin ella el documento sale sin CiudadOrigen).

Va en origen_despacho, no en origen: en la respuesta de un DTE origen es el canal por el que se emitió (portal, api o mcp).

Cambia sólo DirOrigen, CmnaOrigen y CiudadOrigen: nunca el RUT, la razón social, el giro ni el código de sucursal (CdgSIISucur es de la sucursal que EMITE: eso lo dice local_id).

Se escribe en la guía de despacho (52) y en las facturas 33, 34 y 46 que amparan un traslado (con transportista). En otro documento se descarta y la respuesta lo dice en advertencias. Un local_id que no existe, está desactivado o no tiene dirección y comuna responde 422 sin consumir folio.

object (Impresion)

Datos que se imprimen en el documento pero NO viajan al SII: su esquema no los tiene. Se guardan junto al documento y aparecen en el ticket. Todo opcional.

Pensado para retail: identificar quién atendió, en qué local y con qué medio pagó el cliente.

medio_pago NO es forma_pago. forma_pago es el FmaPago del SII (1=Contado, 2=Crédito, 3=Sin costo) y describe la condición de venta: "Efectivo", "Débito" y "Transferencia" son los tres forma_pago: 1. Son dos cosas distintas y usar una por la otra declararía mal la condición de venta ante el SII.

Para el código de caja y de vendedor —que sí viajan al SII— usa referencias[].cod_caja y referencias[].cod_vendedor, disponibles solo en boletas.

object (Exportacion)

Obligatorio en los tipos 110/111/112 (factura, nota de débito y nota de crédito de exportación), con tipo_moneda y tipo_cambio adentro.

Montos: los de items y totales van en la moneda de tipo_moneda y admiten hasta 4 decimales (23.1, 35978.29). Con tipo_cambio el backend arma la sección en pesos chilenos (<OtraMoneda>) que el SII exige aunque su esquema la dé por opcional (rechazo HED-3-834).

Códigos de Aduana (Anexo 51): el SII exige el código NUMÉRICO en cláusula, modalidad, vía de transporte, puertos, bulto, países y forma de pago. Puedes mandar el número (5, 906, 225) o el texto ("FOB", "SAN ANTONIO", "US", "España") y el backend lo traduce con la tabla oficial de Aduana. Si un texto no se puede traducir sin ambigüedad (por ejemplo "CONTENEDOR NO REFRIGERADO", que puede ser de 20 o de 40 pies) responde 422 antes de tomar folio con los valores válidos: el esquema del SII rechazaría ese documento igual. Un código numérico que no esté en nuestra tabla se deja pasar (Aduana agrega códigos).

Lo que el SII exija según la operación y falte (por ejemplo país de destino en una exportación de bienes) no lo bloqueamos: se descubre en el estado asíncrono (estado_local, glosa_sii).

Dos escenarios típicos:

  • Exportación de mercadería: via_transporte, pais_receptor, pais_destino y normalmente clausula/tot_clausula (Incoterm).
  • Exportación de servicios (sin embarque físico): basta tipo_moneda + tipo_cambio.
Array of objects <= 20 items

Sólo exportación (110/111/112). Descuentos (D) y recargos (R) GLOBALES del documento (<DscRcgGlobal>), en porcentaje (%) o en monto ($, en tipo_moneda, con decimales). El caso típico lo pide el propio SII en su set de pruebas: el flete y el seguro van en exportacion.flete/exportacion.seguro y además como dos recargos globales en monto, con glosa FLETE y SEGURO, y suman a totales.monto_exento/monto_total. Una comisión en el extranjero calculada sobre la cláusula también va como recargo en monto. En otros tipos la clave no existe y se avisa en advertencias.

Array of objects <= 20 items

Sólo liquidación-factura (43). Comisiones y otros cargos que el mandatario le cobra al mandante; RESTAN del total (ver totales.monto_total). Opcional: el SII no las exige en todos los casos. Ver el ejemplo liquidacion43.

permitir_duplicado
boolean
Default: false

Escotilla del freno de reemisión por contenido: true significa "sí, ya hay un documento idéntico reciente, es otra venta, emite igual".

Equivale al header X-Permitir-Duplicado: true. No viaja al SII y no forma parte del contenido del documento (no cambia la huella de tu Idempotency-Key).

Responses

Request samples

Content type
application/json
Example
{
  • "tipo_dte": 33,
  • "fecha_emision": "2026-06-11",
  • "receptor": {
    },
  • "items": [
    ],
  • "totales": {
    }
}

Response samples

Content type
application/json
{
  • "id": 123,
  • "tipo_dte": 33,
  • "folio": 45,
  • "estado_local": "pendiente",
  • "monto_total": 119000,
  • "ambiente": "certificacion",
  • "livemode": false,
  • "entrega_receptor": {
    },
  • "origen": "api",
  • "propina": 1190,
  • "total_a_pagar": 13090,
  • "emitido": true,
  • "duplicado": false,
  • "motivo_duplicado": "idempotency_key",
  • "message": "DTE creado y encolado para envío al SII.",
  • "advertencias": [
    ],
  • "pdf_base64": "string",
  • "pdf_mime": "application/pdf",
  • "pdf_error": "El documento SÍ fue emitido y tiene folio 45. Sólo falló la representación impresa: pídela con GET /dte/123/pdf. NO reintentes la emisión — crearía un documento duplicado que hay que anular con nota de crédito.",
  • "pdf": {
    },
  • "impuestos": [
    ],
  • "monto_imp_adicional": 31500
}

Listar DTEs

Authorizations:
ApiKeyAuth
query Parameters
q
string <= 200 characters

Búsqueda libre por razón social o RUT del receptor

rut_receptor
string <= 20 characters
tipo_dte
string

Un tipo o CSV, ej. "33,34"

grupo
string
Enum: "facturas" "boletas" "todos"
estado_local
string
Enum: "pendiente" "enviando" "enviado" "error_envio" "aceptado" "aceptado_con_reparos" "rechazado" "rechazado_sobre" "anulado"

Estado normalizado. Finales: aceptado, aceptado_con_reparos (ambos VÁLIDOS), rechazado, rechazado_sobre, anulado. En curso: pendiente, enviando, enviado, error_envio.

estado_sii
string

Un estado SII o CSV

origen
string
Example: origen=api,mcp

Filtra por el canal de emisión: portal, api, mcp, o varios separados por coma (origen=api,mcp = "todo lo que no emitió una persona a mano"). Un valor no reconocido se ignora.

desde
string <date>

Filtra por fecha de emisión (no por hora de creación). Rango INCLUSIVO: desde=hasta=2026-07-01 devuelve el día 1 completo.

hasta
string <date>

Inclusivo, ver desde.

monto_min
integer >= 0
monto_max
integer >= 0
incluir_pruebas
boolean
Default: false

Por defecto NO se devuelven los documentos que emitió Facturador Pulsando con tu RUT al poner en marcha el sistema (set de certificación, prueba inicial y sus notas de crédito; llevan marca_operativa). Con 1 se incluyen. Aplica igual al listado, al resumen y a los reportes.

ambiente
string
Enum: "certificacion" "produccion"

Ambiente de los documentos a mirar, desde el portal. Con API Key se ignora: se ven siempre los del ambiente de la llave (sk_test_ = certificacion, sk_live_ = produccion).

sort
string
Enum: "fecha_emision" "monto_total" "folio" "created_at"
dir
string
Enum: "asc" "desc"
per_page
integer [ 1 .. 200 ]
Default: 50
page
integer >= 1
Default: 1
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Resumen agregado de DTEs

Totales y desglose por tipo y estado sobre el conjunto filtrado (mismos filtros que el listado). total_documentos cuenta TODO el conjunto; las facetas por_tipo y por_estado traen el monto EMITIDO de cada grupo.

suma_total son VENTAS VÁLIDAS, no la suma de todo lo emitido (desde el 17-sep-2026; antes sumaba todo, incluso notas de crédito en positivo y rechazados):

suma_total = Σ (33, 34, 39, 41, 43, 56 válidos) − Σ (61 válidas)

  • Válido = estado_local aceptado o aceptado_con_reparos, o anulado por una nota de crédito emitida acá (el original suma y la nota resta: neto 0, sin restar dos veces).
  • suma_neto, suma_iva y suma_exento siguen la misma regla.
  • No entran (van en excluidos.por_motivo): guías de despacho 52 (guia_despacho), facturas de compra 46 (factura_compra), exportación 110/111/112 (exportacion_moneda_extranjera: su monto está en la moneda del documento, no en pesos), rechazados (rechazado), error_envio y anulado sin nota de crédito acá (anulado_sin_nota_credito).
  • Aparte (en_proceso): pendiente, enviando y enviado, sin veredicto del SII todavía. No se suman; súmalos tú si quieres una cifra temprana.
  • total_bruto_emitido es la suma de monto_total de todo el conjunto (la cifra que antes venía en suma_total).
Authorizations:
ApiKeyAuth
query Parameters
desde
string <date>

Inclusivo, igual que en el listado.

hasta
string <date>

Inclusivo, igual que en el listado.

tipo_dte
string

Un tipo o CSV, ej. "33,34"

estado_local
string

Mismos valores que en el listado.

incluir_pruebas
boolean
Default: false

Por defecto NO se devuelven los documentos que emitió Facturador Pulsando con tu RUT al poner en marcha el sistema (set de certificación, prueba inicial y sus notas de crédito; llevan marca_operativa). Con 1 se incluyen. Aplica igual al listado, al resumen y a los reportes.

ambiente
string
Enum: "certificacion" "produccion"

Ambiente de los documentos a mirar, desde el portal. Con API Key se ignora: se ven siempre los del ambiente de la llave (sk_test_ = certificacion, sk_live_ = produccion).

header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "suma_total": 0,
  • "suma_neto": 0,
  • "suma_iva": 0,
  • "suma_exento": 0,
  • "documentos_venta": 0,
  • "total_bruto_emitido": 0,
  • "notas_credito": {
    },
  • "en_proceso": {
    },
  • "excluidos": {
    },
  • "total_documentos": 0,
  • "por_tipo": [
    ],
  • "por_estado": [
    ]
}

Obtener un DTE

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "tipo_dte": 0,
  • "tipo_nombre": "string",
  • "folio": 0,
  • "fecha_emision": "2019-08-24",
  • "rut_receptor": "string",
  • "dv_receptor": "string",
  • "razon_receptor": "string",
  • "giro_receptor": "string",
  • "direccion_receptor": "string",
  • "comuna_receptor": "string",
  • "ciudad_receptor": "string",
  • "email_receptor": "string",
  • "monto_neto": 0,
  • "monto_iva": 0,
  • "monto_exento": 0,
  • "monto_total": 0,
  • "estado_sii": "string",
  • "estado_local": "string",
  • "glosa_sii": "string",
  • "clasificacion": "ok",
  • "puede_reintentar": true,
  • "cierre": {
    },
  • "err_code": "DTE-3-101",
  • "detalle_sii": {
    },
  • "track_id": "string",
  • "ambiente": "mock",
  • "origen": "api",
  • "enviado_at": "2019-08-24T14:15:22Z",
  • "respondido_at": "2019-08-24T14:15:22Z",
  • "anulado_por": {
    },
  • "notas_credito": [
    ],
  • "referencia_a": {
    },
  • "items": [
    ],
  • "impuestos": [
    ],
  • "monto_imp_adicional": 31500,
  • "reclamo": {
    },
  • "acuse": {
    },
  • "respuestas_receptor": [
    ],
  • "entrega_receptor": {
    }
}

Descargar el XML firmado del DTE

El <DTE> firmado del documento (con su Signature y el TED), no el sobre EnvioDTE con que se envió al SII. Content-Disposition: attachment; filename="DTE_{tipo}_{folio}.xml".

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "message": "string",
  • "codigo": "string"
}

Descargar la representación impresa (PDF) del DTE

Devuelve el PDF binario (application/pdf, no JSON), listo para imprimir, con el timbre electrónico (TED) impreso como código PDF417.

Formato por defecto (si no envías formato):

  • Boletas (39/41) → rollo 80mm, ideal para impresora de caja.
  • NC/ND que anulan una boleta → rollo 80mm (mismo formato del original).
  • Resto (factura, NC/ND de factura, guía) → hoja carta.

Con formato=pos80 cualquier documento sale en papel continuo de 80mm (§1.1.7 del Manual de Muestras Impresas del SII, "Formato Papel Continuo, por ejemplo formato POS"). Útil si imprimes todo en la impresora térmica.

También puedes fijarlo una vez por empresa desde el portal (Mi empresa → Formato de impresión), y entonces no hace falta mandar el parámetro en cada llamada. Con API key no hay ruta para cambiar esa preferencia: por la API se elige por llamada, con formato. La precedencia es: formato de la query → preferencia de la empresa → default por tipo.

El formato de impresión no afecta lo que se le envía al SII: al SII viaja el XML, y el PDF se deriva de él. Tampoco cambia el PDF que recibe tu cliente por correo o por el portal del receptor.

El PDF se genera on-demand desde el XML firmado (no se almacena). Se puede pedir apenas emitido (tras el 201 de POST /dte): la boleta ya tiene folio y timbre. El estado del SII (aceptado/rechazado) no es necesario para imprimir. El TED también viaja en el XML (/dte/{id}/xml) si prefieres renderizar tu propia representación.

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer
query Parameters
formato
string
Enum: "carta" "pos80"

pos80 = papel continuo 80mm (impresora térmica / POS). carta = hoja carta. Omitirlo (o mandarlo vacío) usa la preferencia de la empresa, y si no la hay, el default por tipo de documento. Un valor fuera del enum devuelve 422 — nunca un PDF en otro formato.

copia
string
Enum: "cedible" "tributaria"

cedible (por defecto) incluye el cuadro de acuse de recibo de la Ley 19.983 y la leyenda CEDIBLE; tributaria los omite. Sólo aplica a factura (33/34) y guía (52): el Manual de Muestras Impresas prohíbe el acuse y el ejemplar cedible en notas de crédito y débito, así que en 56/61 no aparecen con ningún valor.

header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "message": "string",
  • "codigo": "string"
}

Preguntarle al SII, ahora, el estado de un documento

Consulta síncrona al SII del estado del documento por su track_id: la misma del botón «Consultar estado» del panel. Si el SII tiene un veredicto nuevo, se aplica y se disparan los mismos webhooks que por el camino automático (dte.aceptado, dte.reparado, dte.rechazado, dte.anulado).

Para qué sirve. Un documento ya aceptado no se vuelve a consultar solo. Si después el SII lo informa anulado (FAN «Documento Anulado», ANC/AND «Nota de Crédito/Débito anula el documento») —por ejemplo porque la nota de crédito se emitió fuera de esta plataforma—, la única forma de enterarse es esta consulta: el documento pasa a anulado y sale dte.anulado.

No reenvía nada ni gasta folio. Un documento sin track_id (nunca salió) responde 422. Si el SII todavía no tiene veredicto, procesado: false y el documento queda como estaba.

Enfriamiento: una consulta por documento cada 60 segundos; dentro de la ventana responde 429 con codigo: consulta_en_enfriamiento, reintentar_en_segundos y Retry-After, sin consultar al SII.

Requiere el scope dte:create: sale hacia el SII con el certificado de la empresa, igual que reintentar.

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "estado_local": "anulado",
  • "estado_sii": "FAN",
  • "glosa": "string",
  • "procesado": true,
  • "mensaje": "Estado actualizado desde el SII."
}

Reintentar un documento que quedó sin veredicto del SII

Es la salida de un documento en error_envio (también sirve para uno en pendiente). Es lo que se hace al recibir el webhook dte.error_envio una vez corregida la causa. Mismo comportamiento que el botón «Reintentar» del panel. No reemitas un documento en error_envio: su folio ya está tomado.

Qué hace depende de si el documento alcanzó a salir, y lo dice accion:

  • reenviar — no tenía track_id (nunca llegó al SII: SII caído, timeout, certificado corregido después). Se reencola el envío y estado_local queda en pendiente.
  • consultar_sobre — ya tenía track_id (el sobre salió y la plataforma dejó de esperar el veredicto). No se reenvía, porque declararía dos veces el mismo documento: se vuelve a consultar su estado al SII, y estado_local sigue siendo el real (normalmente error_envio) hasta que el SII conteste.
  • consulta_en_curso — hubo una consulta en los últimos 300 segundos. No se encola otra. Trae reintentar_en_segundos y el header Retry-After.

Con consultar_sobre y consulta_en_curso la respuesta trae el track_id. El resultado llega por webhook o consultando GET /dte/{id}.

No reintenta lo que el SII ya respondió. Un documento aceptado, aceptado_con_reparos, rechazado, rechazado_sobre, anulado o todavía enviado/enviando responde 409 con codigo: "reintento_no_aplica" y la clasificacion que explica por qué: un rechazo del SII se corrige emitiendo un documento nuevo (el mismo XML no se reenvía; el folio rechazado no se reutiliza).

Tampoco reintenta un documento cerrado. Si GET /dte/{id} trae cierre (no es null), el documento ya se revisó y no hay nada que reintentar: responde 409 con causa: "documento_cerrado", la fecha y el motivo.

Tampoco reintenta un XML que no pasó nuestra validación previa al envío. Un error_envio cuyo glosa_sii dice «no valida XSD» o «viola reglas de negocio» nunca llegó al SII, y reenviar el mismo XML firmado falla igual: responde 409 con clasificacion: "permanente" y causa: "contenido_invalido" (y GET /dte lo lista con puede_reintentar: false). Ése es el único error_envio que se resuelve emitiendo un documento nuevo con los datos corregidos: como el SII nunca lo recibió, no hay venta declarada dos veces. Un certificado vencido, la resolución de la carátula o el SII caído siguen siendo reintentables: se corrige la causa y se reintenta.

Requiere el scope dte:create y la suscripción al día, igual que emitir: el reenvío sale hacia el SII con el certificado de la empresa.

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "message": "DTE reencolado para envío al SII.",
  • "id": 1234,
  • "estado_local": "pendiente",
  • "clasificacion": "transitorio",
  • "accion": "reenviar",
  • "track_id": "string",
  • "reintentar_en_segundos": 0
}

Enviarle al receptor un documento ya aceptado (sin volver a emitirlo)

Le envía a tu cliente, por intercambio (EnvioDTE firmado a su casilla de intercambio), un documento que el SII ya aceptó. Es la corrección de entrega_receptor cuando faltaba la casilla del receptor o estaba mal. No emite nada, no gasta folio y no toca el XML firmado.

No vuelvas a emitir el documento para que le llegue: otro folio es la venta declarada dos veces y una nota de crédito para anular la primera.

  • Con email, primero se valida (la misma regla que usa la entrega, hasta 80 caracteres como <CorreoRecep> del SII) y se guarda como correo del receptor del documento (email_receptor); el XML firmado no cambia (<CorreoRecep> es informativo). Sin email, se usa el que ya tiene el documento.
  • Documento aceptado (o aceptado con reparos): responde 202 con codigo: en_curso y el envío sale en segundos; entrega_receptor viene con envio_en_curso: true. Cada envío deja un registro nuevo: el resultado se ve en GET /dte/{id} → entrega_receptor.ultimo_intento. Si lo pides dos veces, sale dos veces.
  • Documento todavía sin veredicto del SII (pendiente, enviando o enviado) y con email: la casilla queda guardada y responde 202 con codigo: programado. No sale nada ahora: se le entrega sola cuando el SII lo acepte. Sirve para corregir la casilla apenas el 201 avisa que faltaba, sin esperar el veredicto.
  • Sólo un documento de producción de una empresa real que vaya por intercambio (33, 34, 43, 46, 52, 56, 61 a un contribuyente). Si se puede enviar ahora lo dice de antemano entrega_receptor.puede_reenviarse.
  • Freno por documento: un envío cada 60 s y 10 por día para el mismo documento (429, codigo: limite_envios). Cada envío es otro correo a tu cliente; un programado no cuenta.
  • Enviárselo no anula un reclamo que el receptor ya haya hecho en el SII.
  • La casilla registrada en el SII manda (aditivo, 6-oct-2026): si se conoce la casilla que tu cliente registró en el SII, el EnvioDTE va ahí (entrega_receptor.origen: sii) aunque mandes otro email; ese correo queda guardado y recibe una copia con el PDF (entrega_receptor.copia_cortesia), y advertencias lo dice.

Requiere los scopes dte:create y dte:read (la respuesta trae la casilla del receptor y el envío le manda el XML y el PDF del documento) y la suscripción al día. En el MCP es la herramienta enviar_dte_al_receptor.

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Request Body schema: application/json
optional
email
string <= 80 characters

Casilla de intercambio del receptor (la que tiene registrada en el SII), hasta 80 caracteres. Opcional: sin él se usa la que ya tiene el documento. Queda guardada en el documento.

Responses

Request samples

Content type
application/json
{
  • "email": "dipresrecepcion@custodium.com"
}

Response samples

Content type
application/json
{
  • "mensaje": "Listo: le estamos enviando el documento a dipresrecepcion@custodium.com por intercambio (EnvioDTE). No se emitió nada nuevo ni se gastó folio.",
  • "codigo": "en_curso",
  • "destino": "dipresrecepcion@custodium.com",
  • "entrega_receptor": {
    },
  • "advertencias": [
    ]
}

Mandar una copia con el PDF a otros correos (después de emitir)

Aditivo (30-oct-2026). Le manda una copia con el PDF de un documento a uno o varios correos —«mándasela también a pagos@»—, después de emitirlo. Cualquier tipo de documento (también boletas). No emite nada, no gasta folio y no toca el XML ni el envío oficial a la casilla (para eso está POST /dte/{id}/enviar-receptor).

  • Los correos quedan en la lista de copias del documento y su estado se ve en GET /dte/{id} → entrega_receptor.copias (origen: reenvio).
  • Documento aceptado (o aceptado con reparos): 202 con codigo: en_curso; salen ahora, aunque a ese correo ya se le hubiera mandado (es un reenvío pedido).
  • Documento todavía sin veredicto del SII: 202 con codigo: programado; quedan guardados y salen solos cuando el SII lo acepte.
  • Hasta 10 correos en copia por documento, contando los que ya tiene (422, codigo: limite_copias). Reenviar a uno que ya está no suma.
  • Un correo de relleno (correo@gmail.com) no se usa: 422, codigo: email_no_utilizable, y no se guarda ni se manda nada.
  • Freno por documento: un pedido cada 60 s y 10 al día (429, codigo: limite_envios). Un programado no cuenta. Además, 200 copias al día por empresa por esta vía (las que van al emitir no cuentan).
  • La casilla que ya recibe el documento no recibe además una copia: se quita de la lista (si era la única, 422).
  • Sólo un documento de producción de una empresa real (409, codigo: no_produccion).

Requiere los scopes dte:create y dte:read (le manda el PDF del documento a quien pidas) y la suscripción al día. En el MCP es la herramienta enviar_copia_dte.

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Request Body schema: application/json
required
correos_copia
required
Array of strings <email> [ 1 .. 10 ] items [ items <email > <= 80 characters ]

A quiénes mandarles la copia, de 1 a 10 correos de hasta 80 caracteres. Se guardan en minúsculas y sin repetir.

Responses

Request samples

Content type
application/json
{
  • "correos_copia": [
    ]
}

Response samples

Content type
application/json
{
  • "mensaje": "Listo: le estamos enviando una copia con el PDF a pagos@cliente.cl. No se emitió nada nuevo ni se gastó folio.",
  • "codigo": "en_curso",
  • "correos_copia": [
    ],
  • "entrega_receptor": {
    },
  • "advertencias": [
    ]
}

Forzar el estado final de un DTE (solo ambiente de desarrollo)

Solo funciona en el ambiente de desarrollo. En certificación y producción el estado lo determina el SII, y este endpoint responde 403.

La emisión es asíncrona: POST /dte devuelve 201 pendiente y el estado final llega después, cuando el SII responde. En desarrollo no hay SII, así que ningún documento se rechaza ni se repara por su cuenta y nunca ves la rama de error de tu código. Este endpoint la dispara.

El estado no se escribe a mano: pasa por el mismo servicio que usa la respuesta real del SII, así que produce los mismos efectos que en producción — webhook firmado con HMAC (dte.aceptado, dte.rechazado o dte.reparado), notificaciones según tu política y asiento contable.

Esto cubre solo lo que el ambiente no puede producir por sí mismo: la respuesta del SII. Los errores de integración (payload mal armado, campo faltante, tipo de dato equivocado) ya salen solos con los mismos 422 que en producción, porque es exactamente el mismo código de validación.

Requiere el scope dte:read.

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Request Body schema: application/json
required
estado
required
string
Enum: "aceptado" "rechazado" "reparado"

Estado final a forzar. Se traduce al estado del SII correspondiente: aceptado → DOK, rechazado → RCH, reparado → RPR. Recuerda que un reparo (RPR) es un documento válido con observaciones, no un rechazo.

codigo
string or null <= 20 characters

Código de error del SII a simular (ver Errores del SII). Si lo envías y está en el catálogo, la glosa del documento queda con el texto real de esa causa, para que puedas probar tu manejo por código. Opcional.

Responses

Request samples

Content type
application/json
Example
{
  • "estado": "rechazado",
  • "codigo": "HED-2-210"
}

Response samples

Content type
application/json
{
  • "message": "string",
  • "id": 0,
  • "estado_local": "string",
  • "estado_sii": "RCH",
  • "glosa_sii": "string",
  • "simulado": true
}

Libro de Guías de Despacho

La Res. Ex. SII N°154/2025 (vigente desde el 1 de noviembre de 2026) exige que el Libro de Guías de Despacho, con las guías vigentes y anuladas, esté «disponible y actualizado» y se envíe al SII sólo cuando lo pida. La Res. Ex. 45/2003 dice cómo: al término de cada mes se guarda firmado con la factura anotada en la línea de cada guía.

Lo hacemos solos: el día 11 de cada mes se firma con tu certificado y se guarda el libro del mes anterior (después del día 10, plazo de la factura de las guías). Por API ves el registro de hoy, bajas el archivo firmado y, si lo necesitas antes, firmas una versión al momento. Nunca se reemplaza un libro firmado: cada cambio es una versión nueva. Si el SII te pide el libro, firmas la versión que se le entrega con el folio de su notificación (folio_notificacion en POST …/cerrar); esa queda como la vigente.

Dos puntos que el SII todavía no aclara y que resolvimos así, a la espera de su respuesta: el esquema del libro (2007) exige un FolioNotificacion, que sin requerimiento del SII lleva el período como número (202611); y su TpoOper no tiene código para las guías de exportación (8 y 9), que van sin él en el detalle y totalizadas con su propio código en el resumen.

El libro de guías de despacho de un mes (registro y versiones firmadas)

Lo que el libro de guías de despacho del mes dice hoy, leído de tus documentos: las guías 52 de producción con fecha de emisión en el mes, vigentes y anuladas, con la factura que ampara cada una (la que referencia a la guía, o la que la propia guía referencia). Las guías rechazadas por el SII no existen como documento y van aparte en excluidas.

Trae además las versiones firmadas que se guardaron (versiones, la más nueva primero), la vigente en libro (la del folio de una notificación del SII si existe; si no, la última guardada), desactualizado (lo guardado ya no dice lo mismo que tus guías: una se anuló después del cierre, o llegó una factura tardía) y sin_cerrar (hay guías y todavía no hay libro firmado).

Esta consulta no lee los XML ya archivados (los de hace más de unos 60 días): si hay, completo es false, observaciones lo dice y desactualizado viene null (no se puede comparar). Al firmar se leen todos.

El libro se cierra solo el día 11 de cada mes por el mes anterior. Si lo necesitas antes, o quedó desactualizado, usa POST /libros/guias/{periodo}/cerrar. Con una llave sk_test_ responde 409 (libro_guias_no_disponible_en_prueba). Scope dte:read.

Authorizations:
ApiKeyAuth
path Parameters
periodo
required
string^\d{4}-\d{2}$
Example: 2026-11

Mes, AAAA-MM.

header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "periodo": "2026-11",
  • "ambiente": "produccion",
  • "totales": {
    },
  • "guias": [
    ],
  • "excluidas": [
    ],
  • "observaciones": [
    ],
  • "libro": {
    },
  • "versiones": [
    ],
  • "completo": true,
  • "desactualizado": true,
  • "sin_cerrar": true
}

Descargar el libro de guías FIRMADO

El archivo LibroGuia firmado con el certificado de tu empresa, en ISO-8859-1 como lo exige el SII, validado contra su esquema (LibroGuia_v10.xsd). Según la Res. Ex. 45/2003 el libro no se envía regularmente: se guarda, y se entrega sólo si el SII lo pide.

Dos clases de versión (header X-Libro-Folio-Provisorio):

  • La que se guarda cada mes (folio_provisorio: true): el campo FolioNotificacion, que el esquema exige, lleva el período como número (202611) porque no hay notificación. Es tu copia de conservación, no la que se le entrega al SII.
  • La que se le entrega al SII (folio_provisorio: false, entregable_al_sii: true): firmada con el folio de SU notificación. Fírmala con POST /libros/guias/{periodo}/cerrar y folio_notificacion.

Por defecto baja la vigente: la del folio del SII si existe (una provisoria firmada después no la desplaza); si no, la última guardada. ?version= baja una puntual. El header X-Libro-Sha256 trae la huella de los bytes entregados.

Si el mes no tiene libro firmado responde 404 con codigo: "libro_sin_cerrar". Con una llave sk_test_ responde 409 con codigo: "libro_guias_no_disponible_en_prueba" (el libro son guías de producción). Scope dte:read.

Authorizations:
ApiKeyAuth
path Parameters
periodo
required
string^\d{4}-\d{2}$
Example: 2026-11
query Parameters
version
integer

Id de una versión (de versiones). Por defecto, la vigente.

header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "message": "string",
  • "codigo": "string"
}

Firmar y guardar ahora una versión del libro de guías

Arma el libro del mes con tus guías de hoy, lo firma con el certificado de tu empresa, lo valida contra el esquema del SII y lo guarda como una versión nueva. Nunca reemplaza una versión anterior. No envía nada al SII.

Si el SII te pidió el libro, manda folio_notificacion (el folio de su notificación): esa es la versión que se le entrega (entregable_al_sii: true) y queda como vigente aunque después se firme una provisoria. Sin él, la versión es la que se guarda cada mes (folio = período).

Si ya hay una versión que dice lo mismo que tus guías (con ese folio, si lo mandas), no firma otra vez: responde 200 con guardado: false y la versión vigente. Si el mes no tiene guías de producción, 200 con guardado: false y libro: null.

Scope dte:create (quien puede emitir las guías puede firmar su libro). En el portal, roles administrador y contador. Con una llave sk_test_ responde 409 (libro_guias_no_disponible_en_prueba).

Authorizations:
ApiKeyAuth
path Parameters
periodo
required
string^\d{4}-\d{2}$
Example: 2026-11
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Request Body schema: application/json
optional
folio_notificacion
integer [ 1 .. 1000000000000000000 ]

Folio de la notificación con que el SII pide el libro. Sin él, la versión provisoria del mes.

Responses

Request samples

Content type
application/json
{
  • "folio_notificacion": 123456789
}

Response samples

Content type
application/json
{
  • "guardado": true,
  • "motivo": "string",
  • "libro": {
    }
}

Contribuyentes

Consulta del padrón público del SII (razón social, giros/actividades) para autocompletar y validar el receptor. Requiere el scope dte:read.

Consultar contribuyente en el SII (padrón)

Consulta la Situación Tributaria de un contribuyente en el padrón público del SII (datos abiertos: razón social, giros/actividades económicas, cumplimiento). Úsalo para autocompletar y validar el receptor antes de emitir un DTE.

Los datos provienen directamente del SII (no de terceros) y una respuesta del padrón se cachea 24h. Si el SII no responde (cola virtual / mantención) o pide captcha, se devuelve 503 o captcha_requerido: true para que hagas fallback a carga manual. Esas fallas NO se cachean: la siguiente consulta del mismo RUT vuelve a preguntarle al SII (hasta el 17-sep-2026 un 503 quedaba pegado 24h para ese RUT). Requiere el scope dte:read.

Authorizations:
ApiKeyAuth
path Parameters
rut
required
string

RUT con o sin puntos y DV, ej. "76354771-K" o "76.354.771-K".

header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "registrado": true,
  • "razon_social": "string",
  • "fecha_inicio": "string",
  • "cumple_obligacion": true,
  • "captcha_requerido": true,
  • "giros": [
    ]
}

Recepción

Documentos que otros contribuyentes te emiten (intercambio). Léelos y acéptalos/recházalos comercialmente por API — la API deja de ser "solo emisión". Lectura con recepcion:read; aceptar/rechazar/ingesta con recepcion:write.

Listar documentos recibidos

Lista los DTE que otros contribuyentes te emitieron (recibidos por intercambio). Paginado. Requiere el scope recepcion:read.

Fechas: fecha_emision sale como fecha-hora UTC (2026-09-16T03:00:00.000000Z): es la medianoche de Chile del día de emisión. El día tributario son los primeros 10 caracteres. Las marcas de tiempo (email_recibido_at, created_at, …) también van en UTC con Z, a diferencia de los DTE emitidos, que usan hora de Chile (-03:00).

Authorizations:
ApiKeyAuth
query Parameters
pendientes
boolean

Solo los sin decisión comercial

estado_comercial
integer

0=aceptado, 2=rechazado

rut_emisor
string

RUT del proveedor, con o sin puntos y con o sin DV: 76.543.210-3, 76543210-3, 765432103 o 76543210. Con guion se busca exacto (cuerpo y DV); sin guion, también por coincidencia parcial de dígitos.

per_page
integer
Default: 50
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{ }

Detalle de un documento recibido

Los atributos del registro (emisor, folio, montos, estado comercial, acuses). El XML del proveedor no viene acá: se descarga con GET /dte/recibidos/{id}/xml.

Trae cesion: null si el documento no fue cedido; si el SII avisó una cesión (factoring), el cesionario, su RUT, el monto cedido y el último vencimiento. A ese cesionario es a quien se le paga.

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "tipo_dte": 0,
  • "folio": 0,
  • "fecha_emision": "2026-09-16T03:00:00.000000Z",
  • "rut_emisor": "string",
  • "dv_emisor": "string",
  • "razon_emisor": "string",
  • "monto_total": 0,
  • "estado_comercial": 0,
  • "email_remitente": "string",
  • "email_recibido_at": "2019-08-24T14:15:22Z",
  • "cesion": {
    }
}

Descargar el XML del proveedor (las líneas de la compra)

El XML del documento tal como lo firmó el proveedor, con sus líneas de detalle. Es la única fuente de ese detalle: el RCV del SII (GET /rcv) sólo entrega totales.

Se devuelve el fragmento <DTE> propio del documento; si el sobre traía varios documentos y sólo quedó el EnvioDTE completo, se devuelve ese.

La firma del proveedor verifica (digest y SignatureValue): el <DTE> sale canonicalizado (C14N) tal como estaba dentro del sobre, con las declaraciones de namespace heredadas escritas en el propio <DTE>. Hasta el 17-sep-2026 salía con un prefijo default: inventado y la firma no verificaba; los documentos guardados antes se corrigen al descargarlos.

Cómo llegar desde el RCV: cada fila de compra de GET /rcv trae dte_recibido_id. Si no es null, ese es el {id} de esta ruta. Si es null, el proveedor no mandó el sobre a tu casilla de intercambio (o lo mandó a otro RUT) y el XML sólo está en el portal del SII.

Charset: application/xml; charset=utf-8 por defecto. Si el XML declara encoding="ISO-8859-1", se responde en ISO-8859-1: cabecera, declaración y bytes coinciden. Requiere el scope recepcion:read, el mismo que el detalle.

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer

El id del listado de recibidos (o dte_recibido_id de una fila del RCV), no un folio.

header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "message": "string",
  • "codigo": "string"
}

Ingresar un sobre EnvioDTE recibido

Persiste un EnvioDTE que recibiste por fuera del intercambio automático. Acepta multipart (envioDte), xml_base64 en JSON, o el XML crudo en el cuerpo. Requiere el scope recepcion:write.

  • 201: el sobre se procesó. dtes_recibidos trae cada documento tuyo del sobre (también los que ya estaban: reenviar no es error), nuevos sólo los que se crearon ahora y omitidos los de otros receptores. Mira estado_recep_dte de cada documento (0 OK, 1 schema, 3 receptor, 4 repetido).
  • Desde el 8-oct-2026 se verifica la firma XMLDSig del proveedor en cada documento. Si NO verifica (el contenido cambió después de firmarse, o la firma no es del certificado que trae), el documento se guarda igual —su glosa_recepcion lo dice— pero va en sospechosos, NO en dtes_recibidos ni en nuevos. alertas lista lo que se le avisó a nuestro equipo de operaciones: firma_invalida, conflicto (ya había un documento con ese RUT, tipo y folio y éste dice otra cosa: se conserva el que estaba) o reemplazado (el guardado tenía la firma rota y éste verifica). Una firma que no se puede verificar (sin certificado legible, algoritmo no soportado) NO se trata como inválida.
  • 422 con codigo: el sobre NO se registró (sobre_invalido: no cumple el schema; sobre_ilegible; sobre_de_otro_receptor; sobre_rechazado). Hasta el 17-sep-2026 estos casos respondían 201 con dtes_recibidos: [].
Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Request Body schema: application/json
required
xml_base64
string
email_remitente
string
email_message_id
string

Responses

Request samples

Content type
application/json
{
  • "xml_base64": "string",
  • "email_remitente": "string",
  • "email_message_id": "string"
}

Response samples

Content type
application/json
{
  • "estado_envio": 0,
  • "glosa_envio": "string",
  • "envio_dte_id": "string",
  • "nombre_archivo": "string",
  • "dtes_recibidos": [
    ],
  • "nuevos": [
    ],
  • "omitidos": 0,
  • "sospechosos": [
    ],
  • "alertas": [
    ]
}

Aceptar comercialmente un documento

Marca el documento como aceptado y genera el ResultadoDTE firmado (base64) para el emisor; si tienes casilla configurada, se le envía. Requiere el scope recepcion:write.

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "message": "string",
  • "estado_comercial": 0,
  • "resultado_xml_b64": "string",
  • "acuse_enviado": true,
  • "aviso": "string"
}

Rechazar comercialmente un documento

Marca el documento como rechazado (requiere motivo) y genera el ResultadoDTE firmado para el emisor. Requiere el scope recepcion:write.

🔴 Esto NO es un reclamo ante el SII y NO detiene la aceptación tácita. Sólo cambia el estado comercial en esta plataforma y prepara la respuesta al emisor. En una factura (33, 34) o liquidación factura (43) el plazo de 8 días corridos desde la recepción (Ley 19.983) sigue corriendo: si nadie reclama ante el SII, queda aceptada y es título ejecutivo. El reclamo que cuenta se registra con POST /rcv/{id}/registrar (accion RCD, RFP o RFT; scope rcv:write, llave sk_live_), dentro de esos 8 días.

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Request Body schema: application/json
required
motivo
required
string <= 256 characters
cod_rch_dsc
integer

Código SII de rechazo (opcional)

Responses

Request samples

Content type
application/json
{
  • "motivo": "string",
  • "cod_rch_dsc": 0
}

Response samples

Content type
application/json
{
  • "message": "string",
  • "estado_comercial": 2,
  • "resultado_xml_b64": "string",
  • "acuse_enviado": true,
  • "aviso": "string"
}

RCV (Registro de Compras y Ventas)

Sincroniza y consulta el Registro de Compras y Ventas que el SII mantiene (para conciliación contable). Scope rcv:read.

Sincronizar el RCV de un periodo desde el SII

Encola la sincronización del Registro de Compras y Ventas del SII para un periodo tributario. Es asíncrono (202): un periodo puede traer muchas filas. Consulta el resultado con GET /rcv. Idempotente: re-sincronizar un periodo no duplica. Requiere el scope rcv:read.

Requiere una API key sk_live_. El RCV son documentos reales del SII y no tiene contraparte de prueba, asi que una key sk_test_ recibe 409.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Request Body schema: application/json
required
periodo
required
string

Periodo tributario YYYYMM

operacion
string
Default: "ambas"
Enum: "compra" "venta" "ambas"

Responses

Request samples

Content type
application/json
{
  • "periodo": "202607",
  • "operacion": "compra"
}

Response samples

Content type
application/json
{
  • "message": "string",
  • "periodo": "string",
  • "operaciones": [
    ]
}

Consultar el RCV ya sincronizado

El Registro de Compras y Ventas tal como lo tiene el SII.

Requiere una API key sk_live_: son documentos reales y no existe una version de prueba de este registro. Una key sk_test_ recibe 409. El motivo no es de permisos — es que actuar sobre estos documentos (aceptar o reclamar) tiene efecto legal bajo la Ley 19.983 y no se deshace.

Ademas del listado, la respuesta puede traer aviso: el motivo por el cual no hay documentos que mostrar (por ejemplo, falta cargar el certificado digital). Es null cuando no hay nada que advertir.

Fechas: en el RCV (como en recibidos y locales) las fechas salen en UTC con Z. fecha_emision llega como fecha-hora (2026-07-05T04:00:00.000000Z, la medianoche de Chile de ese día): el día tributario son los primeros 10 caracteres. Los DTE emitidos (GET /dte) usan otro formato: fecha_emision como fecha pura y las marcas de tiempo en hora de Chile (-03:00/-04:00).

Authorizations:
ApiKeyAuth
query Parameters
periodo
string

YYYYMM

operacion
string
Enum: "compra" "venta"
estado_contable
string
Enum: "REGISTRO" "PENDIENTE" "NO_INCLUIR" "RECLAMADO"

En qué pestaña del registro del SII está la compra. Sin este filtro vienen todas, que suele ser lo que quieres.

Valor Significado
REGISTRO Ya está en el registro del periodo. Es lo que el SII cuenta para su propuesta de F29.
PENDIENTE Recibida, sin aceptar ni reclamar. Está dentro de los 8 días de la Ley 19.983: es la única sobre la que todavía puedes actuar.
NO_INCLUIR La excluiste de tu registro.
RECLAMADO La reclamaste.

Si llevas tu propio libro de compras, filtra por REGISTRO: sumar las PENDIENTE adelanta un crédito fiscal que el SII aún no reconoce (y que igual vas a tener, porque al vencer el plazo migran solas).

tipo_dte
integer
rut_contraparte
string
orden
string
Enum: "fecha" "proveedor" "tipo_dte" "folio" "neto" "iva" "total" "plazo"

Campo por el que ordenar. Omítelo y manda el orden por defecto, que pone arriba lo que está por vencer — que es lo que hace útil esta pantalla. Un valor no reconocido se ignora (vuelve al defecto).

fecha y plazo ordenan por la misma base: la fecha de recepción, y la de emisión sólo cuando el SII no informó recepción. Es el mismo reloj con el que se cuentan los 8 días de la Ley 19.983.

dir
string
Default: "asc"
Enum: "asc" "desc"

Sentido del orden. Sólo aplica si mandas orden.

solo_reclamadas
boolean

Solo los documentos que la contraparte RECLAMO ante el SII.

Combinado con operacion=venta responde "que me rechazaron de lo que emiti". OJO: esto no es el rechazo del SII (ese es el estado del DTE, RCH); es el RECEPTOR reclamando comercialmente un documento que ante el SII es valido. Consecuencia distinta: se cae la aceptacion tacita y la factura deja de ser titulo ejecutivo (Ley 19.983).

El filtro usa fecha_reclamo, no el codigo del evento: el RCV devuelve letras sueltas (A, C, P, null) y no los ACD/RCD/ERM, que son los que se ENVIAN al registrar una accion, no los que se leen.

solo_por_vencer
boolean

Sólo lo que se vence YA: sin reclamo y con 0 a 3 días restantes del plazo de 8 días corridos desde la recepción (Ley 19.983). Es el filtro para actuar sobre las COMPRAS antes de que operen la aceptación tácita.

per_page
integer
Default: 50
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total": 0,
  • "last_page": 0,
  • "aviso": {
    }
}

Resumen del periodo — credito fiscal y facturas por vencer

Lo que un ERP necesita para poner un semaforo, sin tener que recorrer y clasificar 330 documentos por su cuenta.

  • credito_fiscal — el IVA de tus compras: lo que DESCUENTAS en el F29. No lo confundas con el debito fiscal, que es el IVA de tus ventas y es lo que PAGAS. El F29 resta uno del otro.
  • por_vencer — facturas a las que les quedan 3 dias o menos de plazo para reclamar. Pasado el plazo se aceptan solas y se vuelven titulo ejecutivo (Ley 19.983).
  • aceptadas_por_plazo + pendientes + reclamadas suman el total. Las reclamadas NO otorgan credito fiscal.

El plazo de reclamo (por_vencer) corre desde la RECEPCION del documento, no desde su emision (Ley 19.983).

Scope rcv:read. Requiere una API key sk_live_: agrega documentos reales del SII y no existe una version de prueba. Una key sk_test_ recibe 409 (igual que GET /rcv).

Authorizations:
ApiKeyAuth
query Parameters
periodo
string

YYYYMM (default: mes en curso)

header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "periodo": "202607",
  • "documentos": 0,
  • "credito_fiscal": 0,
  • "por_vencer": 0,
  • "monto_por_vencer": 0,
  • "aceptadas_por_plazo": 0,
  • "pendientes": 0,
  • "reclamadas": 0,
  • "dias_de_plazo": 8,
  • "ultima_sincronizacion": {
    }
}

Catalogo de acciones sobre una factura recibida

Las cinco acciones del SII y cual de ellas detiene la aceptacion tacita.

Solo lectura (rcv:read): poder LEER que acciones existen no habilita a ejecutarlas — eso exige rcv:write.

Incluye enlaces_sii, para mandar al contribuyente al portal del SII a ver el documento. Ojo: el RCV entrega el RESUMEN de cada factura, no el documento — ni XML ni PDF, ni el detalle de productos. Para las lineas de la factura hace falta el XML, y ese llega por el intercambio por correo (el emisor esta obligado a enviarlo) o bajandolo a mano del portal del SII. Y el SII no permite enlazar a un documento puntual: el enlace va al modulo.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "acciones": [
    ],
  • "dias_de_plazo": 8,
  • "advertencia": "string",
  • "enlaces_sii": {}
}

Aceptar o RECLAMAR ante el SII una factura que te emitieron

Esta es la unica defensa de tu cliente contra una factura que no corresponde.

Cuando recibes una factura de un proveedor, empieza a correr un plazo de 8 dias corridos desde su recepcion (no desde la emision: el proveedor puede emitir el 1 y el sobre llegar el 18). Si nadie la reclama, opera la aceptacion tacita (Ley 19.983) y la factura se convierte en titulo ejecutivo: el proveedor puede cobrarla judicialmente aunque nunca haya entregado la mercaderia, aunque el monto este malo, aunque sea falsa. No hacer nada tiene consecuencias irreversibles.

No confundir con el acuse comercial de POST /dte/recibidos/{id}/aceptar, que es un correo al proveedor. Un correo no detiene la aceptacion tacita. Esto si.

Acciones (accion):

Codigo Que hace Detiene la aceptacion tacita
ACD Acepta el contenido No — renuncia al reclamo
RCD Reclama el CONTENIDO (monto/detalle malo, no reconozco la compra) Si
RFP Reclama por falta PARCIAL de mercaderias Si
RFT Reclama por falta TOTAL (llego la factura, no la mercaderia) Si
ERM Otorga recibo de mercaderias No — deja el documento cedible y cierra el plazo

Cuidado con ERM: es lo contrario de un reclamo y es irreversible.

Requiere el scope rcv:write (no rcv:read): esto MUTA en el SII. El {id} es el del registro devuelto por GET /rcv.

Requiere una API key sk_live_. Reclamar tiene efecto legal e irreversible (Ley 19.983) sobre documentos reales del SII; una key sk_test_ recibe 409 (igual que GET /rcv), para que un flujo "de prueba" no reclame una factura real creyendola de juguete.

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Request Body schema: application/json
required
accion
required
string
Enum: "ACD" "RCD" "ERM" "RFP" "RFT"

Responses

Request samples

Content type
application/json
Example
{
  • "accion": "RCD"
}

Response samples

Content type
application/json
{
  • "ok": true,
  • "accion": "RCD",
  • "descripcion": "string",
  • "es_reclamo": true,
  • "glosa_sii": "string",
  • "dias_de_plazo_restantes": 0
}

Que se hizo con este documento, segun el SII

Historial de eventos del documento tal como lo tiene el SII — no nuestra base. En un juicio ejecutivo lo que vale es su registro: esto es lo que prueba que el reclamo entro dentro de los 8 dias.

Sirve para COMPRAS (lo que te emitieron) y para VENTAS (lo que emitiste): en una venta muestra quién te reclamó, aceptó o dio recibo, y cuándo. Hasta el 17-sep-2026 una venta se consultaba con el RUT del cliente como emisor y volvía vacía.

Scope rcv:write. Requiere una API key sk_live_: es el historial de un documento real del SII y no existe una version de prueba. Una key sk_test_ recibe 409 (igual que GET /rcv).

En una empresa de desarrollo (ambiente simulado) responde 200 con eventos: []: nunca se registró nada ante el SII.

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "documento": { },
  • "dias_de_plazo_restantes": 0,
  • "eventos": [
    ]
}

F29 (propuesta del SII)

La propuesta del Formulario 29 que arma el SII para tu empresa, leída del SII (con el remanente del mes anterior, las retenciones de honorarios y el PPM), y lo ya presentado del período. Sólo lectura, scope rcv:read, plan con la función f29 y API key sk_live_.

Propuesta de F29 que arma el SII para tu empresa

Lee del SII la propuesta del Formulario 29 que el SII arma para tu empresa en el período, y lo que ya se presentó de ese período. Es lo que verías en sii.cl → «Declarar IVA (F29)», con lo que nosotros no podemos calcular porque sólo lo conoce el SII: el remanente de crédito del mes anterior (código 504), las retenciones de honorarios (151/152) y el PPM (563, con su tasa en 115).

Sólo lectura: no guarda, no presenta ni firma nada.

Siempre responde 200 cuando la consulta llega a hacerse: el resultado va en estado, no en el código HTTP.

estado Qué significa
ok El SII devolvió su propuesta. Los códigos vienen en codigos.
sin_propuesta El SII todavía no tiene una propuesta para ese período.
no_autorizado El SII no permite consultar el F29 de esta empresa con el certificado cargado. Revisa la propuesta directamente en sii.cl. mensaje_sii trae la glosa literal del SII.
no_aplica Empresa de desarrollo (ambiente simulado): no se consulta al SII y no hay códigos.
error No se pudo consultar al SII (conexión o sesión). Vuelve a intentarlo en unos minutos.

no_autorizado es un resultado esperable, no una falla nuestra. El SII puede autorizar la consulta del F29 por la PERSONA titular del certificado y no por la empresa que esa persona representa. Si el SII no permite consultarlo con tu certificado, estado = no_autorizado. No podemos prometer que esta lectura funcione para todas las empresas.

Un null no es un cero. En destacados y en valor, null significa que el SII no propuso ese código. Los montos van en pesos; valor puede ser decimal (el código 115 es la tasa del PPM, por ejemplo 0.125). Cada código dice en unidad si su valor son pesos, una cantidad de documentos o una tasa: en el F29 cada línea de documentos tiene dos códigos, la cantidad (por ejemplo 503) y el monto (502).

Caché de 6 horas por empresa y período: cada lectura habla con el SII usando el certificado de la empresa. desde_cache: true indica que la respuesta sale de la caché; con refrescar=1 se vuelve a preguntar al SII, como máximo una vez cada 5 minutos por empresa y período (dentro de ese plazo responde la caché: cada consulta abre una sesión en el SII con el certificado de la empresa). Un error no se guarda en la caché.

No es la misma cifra que nuestra estimación del F29 (portal, módulo contable): esa se calcula con los documentos que emitiste y recibiste; ésta es la que arma el SII.

Scope rcv:read. Requiere que el plan incluya la función f29 (si no, 403 con upgrade_required: true). Requiere una API key sk_live_: el F29 es la declaración real y no tiene versión de prueba. Una key sk_test_ sobre una empresa real recibe 409 con codigo: "f29_no_disponible_en_prueba".

Authorizations:
ApiKeyAuth
query Parameters
periodo
required
string^\d{4}-?(0[1-9]|1[0-2])$
Example: periodo=202608

Período tributario, AAAAMM o AAAA-MM (por ejemplo 202608 o 2026-08).

refrescar
boolean
Default: false

Con 1 (o true) salta la caché de 6 horas y vuelve a preguntar al SII, como máximo una vez cada 5 minutos por empresa y período.

header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "desde_cache": true,
  • "periodo": "202608",
  • "estado": "ok",
  • "ambiente": "produccion",
  • "livemode": true,
  • "mensaje": "string",
  • "mensaje_sii": "string",
  • "consultado_en": "2019-08-24T14:15:22Z",
  • "destacados": {
    },
  • "totales_calculados": true,
  • "codigos_fuera_de_cobertura": [
    ],
  • "tipo_propuesta": 0,
  • "codigos": [
    ],
  • "grupos": {
    },
  • "estado_propuesta": "string",
  • "declaraciones": [
    ]
}

Clave tributaria del SII

La clave tributaria de la EMPRESA ante el SII (la de sii.cl, no la personal del representante). Algunas lecturas del SII —como la propuesta del F29— sólo se obtienen con la clave de la propia empresa, porque el certificado del representante da «no autorizado». La clave se entrega una sola vez, se valida contra el SII, se cifra y NUNCA se devuelve (el GET da sólo su estado). Scope explícito sii:credenciales y clave sk_live_. Cada conexión o cambio dispara un correo a la empresa.

Estado de la clave tributaria de la empresa

Dice si la empresa conectó su clave tributaria del SII y en qué estado está. Nunca devuelve la clave (ni cifrada ni enmascarada): sólo su estado. No habla con el SII.

estado Qué significa
sin_clave La empresa no ha conectado ninguna clave.
validando Se está validando contra el SII.
activa Conectada y aceptada por el SII; abre las lecturas que la exigen (p. ej. GET /f29/sii).
invalida La conectó, pero el SII ya no la acepta (la cambió en sii.cl): hay que volver a conectarla.
revocada Se desconectó.

Scope sii:credenciales. Requiere una API key sk_live_.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "conectada": true,
  • "estado": "sin_clave",
  • "alcance": "string",
  • "origen": "portal",
  • "validada_en": "2019-08-24T14:15:22Z",
  • "ultimo_uso_en": "2019-08-24T14:15:22Z",
  • "consentimiento": "string",
  • "consentimiento_vigente": "v2026-09-30"
}

Conectar (o reemplazar) la clave tributaria de la empresa

Entrega la clave tributaria de la EMPRESA (la de sii.cl, no la personal del representante). Se valida contra el SII antes de guardarla; si el SII la acepta, se cifra y queda activa. Si ya había una, la reemplaza.

La clave se entrega UNA sola vez y NUNCA se devuelve. El integrador no necesita guardarla: la custodiamos cifrada nosotros. Si aun así decides conservarla de tu lado, guárdala en tu gestor de secretos o en una variable de entorno (por ejemplo SII_CLAVE_TRIBUTARIA), nunca en el código fuente ni en logs. Cada conexión o cambio dispara un correo a la empresa.

En acepta_terminos manda el valor de consentimiento_vigente que trae el GET (hoy v2026-09-30).

El consentimiento de custodia lo da la empresa. Una API key que emitimos nosotros (desde nuestro panel o desde una sesión de soporte) no lo otorga: con ella sólo se reemplaza la clave cuando la empresa ya dio su consentimiento en la versión vigente, y la clave nueva lo hereda (acepta_terminos es opcional). Si no hay uno vigente responde 403 (codigo: consentimiento_del_cliente) y no se guarda nada: la empresa lo da desde su portal o con una llave que creó ella.

Scope sii:credenciales. Requiere una API key sk_live_: con sk_test_ responde 409 (codigo: clave_sii_no_disponible_en_prueba). Cupo propio de 6 intentos por minuto por empresa.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Request Body schema: application/json
required
clave
required
string [ 1 .. 25 ] characters

La clave tributaria de la empresa en sii.cl. Se valida, se cifra y nunca se devuelve. No la pongas en logs.

acepta_terminos
required
string

El valor de consentimiento_vigente que trae el GET. Si no coincide con el vigente, se rechaza con 422 (codigo: datos_invalidos).

Responses

Request samples

Content type
application/json
{
  • "clave": "string",
  • "acepta_terminos": "v2026-09-30"
}

Response samples

Content type
application/json
{
  • "conectada": true,
  • "estado": "sin_clave",
  • "alcance": "string",
  • "origen": "portal",
  • "validada_en": "2019-08-24T14:15:22Z",
  • "ultimo_uso_en": "2019-08-24T14:15:22Z",
  • "consentimiento": "string",
  • "consentimiento_vigente": "v2026-09-30"
}

Desconectar la clave tributaria de la empresa

Desconecta la clave tributaria: la marca revocada y borra el valor cifrado. Las lecturas que la exigen (p. ej. GET /f29/sii) vuelven a responder no_autorizado. Dispara un correo a la empresa.

Scope sii:credenciales. Requiere una API key sk_live_.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "conectada": true,
  • "estado": "sin_clave",
  • "alcance": "string",
  • "origen": "portal",
  • "validada_en": "2019-08-24T14:15:22Z",
  • "ultimo_uso_en": "2019-08-24T14:15:22Z",
  • "consentimiento": "string",
  • "consentimiento_vigente": "v2026-09-30"
}

Previred (credencial y nómina)

Previred para la empresa: (1) la credencial de Previred de la empresa (GET/PUT/DELETE /previred/credenciales, scope explícito previred:credenciales, clave sk_live_ para entregarla; se entrega una sola vez y NUNCA se devuelve: el GET da sólo su estado), con las empresas que administra ese usuario de Previred (/previred/credenciales/empresas: verlas, buscarlas en Previred y elegir cuál se sincroniza); (2) el mandato legal de Previred (GET/POST/DELETE /previred/mandato, scope explícito previred:mandato, clave sk_live_ para firmarlo/revocarlo): la autorización expresa, versionada y revocable para operar la cuenta de Previred de la empresa (un integrador pide el mandato a su cliente); y (3) el ensayo en seco y la generación del archivo de nómina de 105 campos (POST /previred/nomina/validar y /previred/nomina/archivo, scope previred:nomina). La nómina no se guarda, no se envía a Previred y no gasta nada: validar devuelve la lista completa de errores por línea y campo, y archivo entrega el TXT sólo si no hay un solo error. Todavía no hay subida ni pago por esta API: el archivo lo sube la persona en Previred.

Estado de la credencial de Previred de la empresa

Dice si la empresa conectó su credencial de Previred y en qué estado está. Nunca devuelve la clave (ni cifrada ni enmascarada): sólo su estado. No habla con Previred.

estado Qué significa
sin_credencial La empresa no ha conectado ninguna.
activa Conectada y vigente.
rechazada La conectó, pero Previred no abrió la sesión con ella (clave cambiada o vencida, cuenta bloqueada). No se vuelve a intentar: hay que volver a conectarla.
revocada Se desconectó.

Scope previred:credenciales.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "conectada": true,
  • "estado": "sin_credencial",
  • "rut_usuario": "string",
  • "modo": "empresa",
  • "empresas": [
    ],
  • "origen": "string",
  • "validada_en": "2019-08-24T14:15:22Z",
  • "ultimo_uso_en": "2019-08-24T14:15:22Z",
  • "consentimiento": "string",
  • "consentimiento_vigente": "v2026-10-07"
}

Conectar (o reemplazar) la credencial de Previred de la empresa

Entrega el RUT de usuario y la clave de Previred de la empresa (o del contador que la administra, con modo: contador y la lista de empresas). Se cifra y queda activa. Si ya había una del mismo usuario, la reemplaza.

La clave se entrega UNA sola vez y NUNCA se devuelve. No necesitas guardarla: la custodiamos cifrada. Si decides conservarla de tu lado, guárdala en tu gestor de secretos o en una variable de entorno, nunca en el código fuente ni en logs. Cada conexión o cambio dispara un correo a la empresa.

En acepta_terminos manda el valor de consentimiento_vigente que trae el GET.

El consentimiento de custodia lo da la empresa. Una API key que emitimos nosotros no lo otorga: sólo reemplaza la credencial cuando la empresa ya dio su consentimiento vigente (acepta_terminos es opcional); si no, 403 (codigo: consentimiento_del_cliente) y no se guarda nada.

Scope previred:credenciales. Requiere una API key sk_live_: con sk_test_ responde 409 (codigo: credencial_previred_no_disponible_en_prueba). Cupo propio de 6 intentos por minuto por empresa.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Request Body schema: application/json
required
rut_usuario
required
string <= 12 characters

RUT con el que se ingresa a Previred (con o sin puntos y guion; el dígito verificador se comprueba).

clave
required
string [ 1 .. 64 ] characters

La clave de Previred. Se cifra y nunca se devuelve. No la pongas en logs.

acepta_terminos
required
string

El valor de consentimiento_vigente que trae el GET. Si no coincide con el vigente, se rechaza con 422 (codigo: datos_invalidos).

modo
string
Enum: "empresa" "contador"

empresa (por defecto): la credencial es de la propia empresa. contador: un contador que administra las empresas listadas.

empresas
Array of strings <= 200 items [ items <= 12 characters ]

RUT de las empresas que administra la credencial (modo contador).

Responses

Request samples

Content type
application/json
{
  • "rut_usuario": "12.345.678-5",
  • "clave": "string",
  • "acepta_terminos": "v2026-10-07",
  • "modo": "empresa",
  • "empresas": [
    ]
}

Response samples

Content type
application/json
{
  • "conectada": true,
  • "estado": "sin_credencial",
  • "rut_usuario": "string",
  • "modo": "empresa",
  • "empresas": [
    ],
  • "origen": "string",
  • "validada_en": "2019-08-24T14:15:22Z",
  • "ultimo_uso_en": "2019-08-24T14:15:22Z",
  • "consentimiento": "string",
  • "consentimiento_vigente": "v2026-10-07"
}

Desconectar la credencial de Previred de la empresa

Desconecta la credencial: la marca revocada y borra el valor cifrado. Dispara un correo a la empresa.

Scope previred:credenciales.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "conectada": true,
  • "estado": "sin_credencial",
  • "rut_usuario": "string",
  • "modo": "empresa",
  • "empresas": [
    ],
  • "origen": "string",
  • "validada_en": "2019-08-24T14:15:22Z",
  • "ultimo_uso_en": "2019-08-24T14:15:22Z",
  • "consentimiento": "string",
  • "consentimiento_vigente": "v2026-10-07"
}

Empresas que administra la credencial de Previred y cuáles se sincronizan

Un usuario de Previred puede administrar varias empresas. Esta lista trae las que se encontraron en su cuenta de Previred (con POST /previred/credenciales/empresas/descubrir) y, por cada una, si la sincronización trae sus trabajadores (sincronizar). No habla con Previred.

pertenece Qué significa ¿Se puede activar?
esta_empresa Es el RUT de la empresa de la llave. Se sincroniza por defecto. Sí
cartera Es otra empresa de la cartera de tu organización. Sus trabajadores se traen desde esa empresa (con su credencial y su mandato). No
fuera_de_la_cuenta El usuario de Previred la administra, pero no está en tu cuenta. No

Si nunca se buscaron, la lista trae igual a la propia empresa (con en_ultima_busqueda: false): se sincroniza por defecto.

Scope previred:credenciales. No exige la función remuneraciones (como el estado de la credencial).

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "credencial": {
    },
  • "ultima_busqueda_en": "2019-08-24T14:15:22Z",
  • "empresas": [
    ]
}

Buscar en Previred las empresas del usuario de la credencial

Entra a Previred con la credencial custodiada, lista las empresas que administra ese usuario y sale (login → listado → cierre de sesión). No entra a ninguna empresa ni lee trabajadores. Guarda lo encontrado (RUT con dígito verificador, razón social y divisiones) y responde la lista, igual que el GET. Respeta lo que ya elegiste en sincronizar.

Hace UN solo intento de inicio de sesión. Si Previred no lo acepta (clave cambiada o vencida, cuenta bloqueada), la credencial queda rechazada y no se vuelve a usar hasta que la conectes de nuevo: varios intentos fallidos seguidos pueden bloquear la cuenta de Previred del cliente.

Exige el mandato de Previred vigente (opera la cuenta del cliente), la función remuneraciones y una API key sk_live_ (con sk_test_ responde 409). Scope previred:credenciales. Cupo propio de 3 por minuto.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "credencial": {
    },
  • "ultima_busqueda_en": "2019-08-24T14:15:22Z",
  • "empresas": [
    ]
}

Activar o desactivar la sincronización de una empresa de la credencial

Prende o apaga que la sincronización traiga los trabajadores de esa empresa. Apagar se puede siempre. Prender sólo la propia empresa (pertenece: esta_empresa): el mandato de Previred autoriza a operar la cuenta con la credencial que la propia empresa entregó, y los trabajadores se importan a la empresa que sincroniza. Con la empresa apagada, la sincronización termina en error (codigo: empresa_desactivada) sin entrar a Previred.

Exige la función remuneraciones y una API key sk_live_. Scope previred:credenciales.

Authorizations:
ApiKeyAuth
path Parameters
rut
required
string <= 12 characters
Example: 76354771-K

RUT de la empresa, con dígito verificador (con o sin puntos).

header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Request Body schema: application/json
required
sincronizar
required
boolean

true trae sus trabajadores al sincronizar; false no.

Responses

Request samples

Content type
application/json
{
  • "sincronizar": true
}

Response samples

Content type
application/json
{
  • "credencial": {
    },
  • "ultima_busqueda_en": "2019-08-24T14:15:22Z",
  • "empresas": [
    ]
}

Estado del mandato de Previred de la empresa (y su texto vigente)

Trae el texto legal vigente del mandato de Previred y el estado del mandato de la empresa: si está vigente, qué versión aceptó, cuándo y por dónde. El mandato es la autorización expresa, versionada y revocable para operar la cuenta de Previred de la empresa (Ley 19.628 / 21.719). No habla con Previred.

estado Qué significa
sin_mandato La empresa nunca firmó un mandato.
vigente Firmado y en vigor.
revocado Se revocó.

Scope previred:mandato.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "vigente": true,
  • "estado": "sin_mandato",
  • "version": "string",
  • "version_vigente": "v2026-10-08",
  • "al_dia": true,
  • "texto_hash": "string",
  • "aceptado_en": "2019-08-24T14:15:22Z",
  • "aceptado_por_origen": "string",
  • "revocado_en": "2019-08-24T14:15:22Z",
  • "revocado_motivo": "string",
  • "texto_vigente": "string"
}

Firmar (aceptar) el mandato de Previred de la empresa

Acepta el mandato legal de Previred en nombre de la empresa. En version manda el valor de version_vigente que trae el GET: si no coincide con la vigente, se rechaza con 422 (codigo: version_no_vigente). Se guarda la versión y el hash del texto exacto aceptado, con fecha, IP y quién lo firmó. Si ya había uno vigente, lo reemplaza. Dispara un correo a la empresa.

Scope previred:mandato. Requiere una API key sk_live_: con sk_test_ responde 409 (codigo: mandato_previred_no_disponible_en_prueba). El mandato autoriza operar la cuenta real de Previred. Cupo propio de 6 por minuto por empresa.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Request Body schema: application/json
required
version
required
string <= 20 characters

El valor de version_vigente que trae el GET. Si no es la vigente, se rechaza con 422 (codigo: version_no_vigente).

Responses

Request samples

Content type
application/json
{
  • "version": "v2026-10-08"
}

Response samples

Content type
application/json
{
  • "vigente": true,
  • "estado": "sin_mandato",
  • "version": "string",
  • "version_vigente": "v2026-10-08",
  • "al_dia": true,
  • "texto_hash": "string",
  • "aceptado_en": "2019-08-24T14:15:22Z",
  • "aceptado_por_origen": "string",
  • "revocado_en": "2019-08-24T14:15:22Z",
  • "revocado_motivo": "string",
  • "texto_vigente": "string"
}

Revocar el mandato de Previred de la empresa

Revoca el mandato: lo marca revocado, con fecha y motivo. Desde ese momento no se opera la cuenta de Previred de la empresa. Dispara un correo a la empresa.

Scope previred:mandato. Requiere una API key sk_live_ (con sk_test_ responde 409).

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Request Body schema: application/json
optional
motivo
string or null <= 190 characters

Motivo de la revocación (opcional). Queda en el registro.

Responses

Request samples

Content type
application/json
{
  • "motivo": "string"
}

Response samples

Content type
application/json
{
  • "vigente": true,
  • "estado": "sin_mandato",
  • "version": "string",
  • "version_vigente": "v2026-10-08",
  • "al_dia": true,
  • "texto_hash": "string",
  • "aceptado_en": "2019-08-24T14:15:22Z",
  • "aceptado_por_origen": "string",
  • "revocado_en": "2019-08-24T14:15:22Z",
  • "revocado_motivo": "string",
  • "texto_vigente": "string"
}

Validar una nómina de Previred (ensayo en seco)

Recibe los trabajadores y devuelve la lista completa de errores, por línea y por campo, con el mismo validador que usa /previred/nomina/archivo. No genera el archivo, no guarda nada, no habla con Previred y no gasta nada. Responde 200 siempre que el cuerpo tenga forma: valida: false + errores cuando la nómina tiene problemas (un 422 es sólo para un cuerpo mal formado).

Cada elemento de trabajadores es UNA línea del archivo y usa las claves de los 105 campos (NominaTrabajador). Una clave que no existe no se ignora: se reporta como error CLAVE_DESCONOCIDA (si se ignorara, el archivo saldría sin un dato que creíste haber enviado).

Valida: formato de cada campo, RUT con dígito verificador, códigos contra las tablas de Previred vigentes para el período, coherencia entre campos y de totales (siempre con tolerancia de ±1 peso) y la secuencia de líneas. No valida (necesita datos que no viajan acá): topes imponibles, tasa de cada AFP, SIS ni valor de la UF. Una nómina sin errores aquí no garantiza que Previred la acepte.

empresa_con_ccaf y empresa_con_mutual (opcionales) le dicen al validador si la empresa está afiliada a una caja o a una mutual; con ellos exige o prohíbe esos campos. Máximo 2.000 líneas por llamada y 500 errores en la respuesta (truncado: true si hubo más).

Scope previred:nomina. Funciona igual con sk_test_ y sk_live_.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Request Body schema: application/json
required
required
Array of objects (NominaTrabajador) [ 1 .. 2000 ] items

Las líneas de la nómina, en el orden en que irán en el archivo. Una línea adicional (01/03) va tras la principal del mismo RUT.

empresa_con_ccaf
boolean or null

true si la empresa está afiliada a una caja de compensación (se exige CCAF en los trabajadores); false si no (se prohíbe). Omitido = no se comprueba.

empresa_con_mutual
boolean or null

true si la empresa está afiliada a una mutual de seguridad (se exige); false si no (se prohíbe). Omitido = no se comprueba.

Responses

Request samples

Content type
application/json
{
  • "trabajadores": [
    ],
  • "empresa_con_ccaf": true,
  • "empresa_con_mutual": true
}

Response samples

Content type
application/json
{
  • "valida": true,
  • "lineas": 0,
  • "total_errores": 0,
  • "truncado": true,
  • "errores": [
    ]
}

Generar el archivo de nómina de Previred (TXT)

Valida la nómina con el mismo validador que /previred/nomina/validar y, sólo si no hay un solo error, entrega el archivo: una línea por registro, 105 campos separados por ;, saltos CRLF, en ISO-8859-1 (text/plain; charset=ISO-8859-1, con Content-Disposition y el nombre nomina_previred_AAAAMM.txt). Si hay errores responde 422 con codigo: nomina_invalida y la misma lista de /validar: jamás un archivo parcial.

Con ?formato=json responde un JSON (nombre_archivo, codificacion, lineas, bytes, sha256 y contenido en UTF-8, legible) en vez del archivo; el sha256 es el del archivo ISO-8859-1 real.

El archivo no se guarda ni se sube a Previred: lo sube la persona. No hay pago ni lectura del portal de Previred por esta API.

🔴 Reforma previsional (Ley 21.735): los aportes del empleador van en la línea, como los pide Previred (formato de 105 campos v100): afp_cotizacion (campo 28) = 10 % + comisión de la AFP + el 0,1 % del empleador (activo o pensionado por invalidez parcial, desde agosto de 2025); afp_sis (29) el SIS; cotizacion_expectativa_vida (94, desde agosto de 2025) y cotizacion_rentabilidad_protegida (95, desde agosto de 2026). Una línea que debería traer el 94 o el 95 y los trae en 0 no se rechaza (Previred no lo lista entre sus razones de rechazo), pero con ?formato=json aviso_reforma dice cuántas líneas no los declaran (null si todas los declaran).

Scope previred:nomina. Mismo cuerpo y mismos límites que /validar.

Authorizations:
ApiKeyAuth
query Parameters
formato
string
Value: "json"

json entrega el resultado en JSON (con el contenido en UTF-8) en vez del TXT ISO-8859-1.

header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Request Body schema: application/json
required
required
Array of objects (NominaTrabajador) [ 1 .. 2000 ] items

Las líneas de la nómina, en el orden en que irán en el archivo. Una línea adicional (01/03) va tras la principal del mismo RUT.

empresa_con_ccaf
boolean or null

true si la empresa está afiliada a una caja de compensación (se exige CCAF en los trabajadores); false si no (se prohíbe). Omitido = no se comprueba.

empresa_con_mutual
boolean or null

true si la empresa está afiliada a una mutual de seguridad (se exige); false si no (se prohíbe). Omitido = no se comprueba.

Responses

Request samples

Content type
application/json
{
  • "trabajadores": [
    ],
  • "empresa_con_ccaf": true,
  • "empresa_con_mutual": true
}

Response samples

Content type
No sample

Paquetes (módulos en beta)

Los módulos nuevos (remuneraciones y Previred, boletas de honorarios, estados financieros) vienen en paquetes que la empresa activa voluntariamente aceptando sus términos. Mientras estén en beta_gratis no tienen costo, sea el plan que sea: activar no crea cobro ni cambia la suscripción. Sin activar, sus operaciones responden 403 con codigo: requiere_activacion, el paquete y dónde activarlo. GET /paquetes lista el catálogo con el estado de la empresa (scope dte:read); activar y desactivar exigen el scope explícito paquetes:activar y, sobre una empresa real, una llave sk_live_ (con sk_test_ responde 409). Desactivar quita el acceso; los datos cargados no se borran y se pueden seguir descargando. Si la versión de los términos sube, hay que volver a aceptarla (requiere_reaceptar: true).

Catálogo de paquetes y su estado para la empresa

Lista los paquetes (módulos que se activan aceptando sus términos) con su estado para la empresa: activado, quién lo activó (empresa o estudio, que lo cascadea a su cartera), la versión de términos aceptada, si hay que reaceptar una versión nueva, y el texto de los términos vigentes. Un paquete en beta_gratis no tiene costo. Scope dte:read.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Activar un paquete aceptando sus términos

Activa el paquete para la empresa aceptando la versión vigente de sus términos (terminos_version, la que trae GET /paquetes). Queda registrado quién (la llave), cuándo, desde qué IP y qué versión. Idempotente. No cobra nada ni cambia la suscripción. Con una versión que no es la vigente, 422 (codigo: terminos_no_vigentes). Un paquete que no está en beta_gratis no se activa por acá (409, codigo: paquete_no_disponible).

Scope explícito paquetes:activar. Sobre una empresa real exige sk_live_: con sk_test_ responde 409 (codigo: paquete_no_disponible_en_prueba). En una empresa de desarrollo (simulada) basta la sk_test_.

Authorizations:
ApiKeyAuth
path Parameters
slug
required
string (PaqueteSlug)
Enum: "remuneraciones" "honorarios" "estados_financieros"

El identificador de un paquete del catálogo.

header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Request Body schema: application/json
required
terminos_version
required
string <= 20 characters

La terminos_version vigente del paquete (la trae GET /paquetes).

Responses

Request samples

Content type
application/json
{
  • "terminos_version": "2026-10-14"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Desactivar un paquete

Desactiva el paquete para la empresa: desde la petición siguiente sus operaciones responden 403 (codigo: requiere_activacion) y los procesos en cola de ese módulo no corren. Los datos ya cargados no se borran. Si no estaba activado, responde igual (200). No cobra nada. Scope explícito paquetes:activar; con sk_test_ sobre una empresa real, 409.

Authorizations:
ApiKeyAuth
path Parameters
slug
required
string (PaqueteSlug)
Enum: "remuneraciones" "honorarios" "estados_financieros"

El identificador de un paquete del catálogo.

header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Folios (CAF)

Estado de folios disponibles (CAF) con el scope caf:read, y solicitud de nuevos folios al SII (vía robot/RPA con tu certificado) con el scope caf:write.

Estado de folios por tipo de DTE

Folios disponibles, próximo folio y ambiente por tipo de documento.

Cada tipo trae además uso_del_rango: si el rango en curso ya viene usado ante el SII y desde qué folio se emite. Sirve para detectar antes de chocar que el mismo CAF está cargado en dos sistemas a la vez — el caso que termina en (DTE-3-101) Folio ya fue recibido en el SII. Se recalcula en cada lectura contra el RCV ya sincronizado; no consulta al SII.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Historial de solicitudes de folios al SII

Las ultimas ejecuciones del robot que pide folios (CAF) al SII, con lo que se solicito, lo que el SII autorizo y el error si lo hubo.

Existe para que la solicitud de folios no sea una caja negra: el SII puede autorizar MENOS de lo pedido (acotado: true) segun el comportamiento tributario del contribuyente, y sin este historial esa diferencia no se puede explicar ni auditar.

Qué mostrarle a una persona. error y resultado.errores[].mensaje son el detalle técnico tal como lo registró el robot (pueden traer JSON, trazas y diálogos del portal del SII que no son la causa). Para una pantalla o un correo usa mensaje_cliente (o errores_cliente + referencia): la explicación en español, qué hacer (casi siempre nada, porque se reintenta solo) y el código de referencia para soporte. error y resultado no cambian.

Scope caf:read.

Authorizations:
ApiKeyAuth
query Parameters
limit
integer <= 50
Default: 20

Cuantas ejecuciones traer (tope 50).

ambiente
string
Enum: "certificacion" "produccion" "mock"

Sólo las ejecuciones de ese ambiente (30-sep-2026). Sin él, todas.

header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Tipos de DTE con folios en alerta o agotados

Los tipos con una alerta (alerta distinto de ninguna): agotado, bajo, rango usado por otro sistema, vence pronto, o no autorizado por el SII estando en uso. Desde el 30-sep-2026 sale de la misma cuenta que /caf/status (los mismos disponibles), y un tipo que el SII no autoriza y la empresa no usa NO aparece. Cada ítem trae alerta, accion y ambiente.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Tipos de DTE que el SII autoriza al contribuyente

Solo lectura: los tipos de documento que el SII tiene habilitados para el contribuyente, tal como el robot de folios los fue registrando. No pide ni aloca folios: solo lee la memoria de autorizaciones.

autorizado_max (cupo maximo que el SII deja pedir) puede venir null, y techo_estado dice POR QUE:

  • leido: el SII publico el numero y ahi esta.
  • sin_techo_publicado: el SII NO publica techo para ese documento. Solo lo publica para los que tienen credito fiscal (33, 43, 46, 56, 61); para boleta, exenta, guia y exportacion no hay tope publicado. Es un hecho del SII, no una falla de lectura.
  • error: no se pudo leer. techo_motivo lo explica. Si igual hay un autorizado_max, es el ultimo valor que el SII si nos dijo.
  • null: todavia no se consulto para ese tipo.

techo_al es cuando se leyo el techo (distinto de ultima_consulta_at, que se mueve con cada SOLICITUD de folios) y folios_disponibles_sii son los folios que el SII cree que el contribuyente tiene sin usar.

Si un tipo entro en backoff por fallos, se expone bloqueado_hasta y ultimo_error.

Scope caf:read.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Solicitar folios (CAF) de un tipo de DTE al SII

Pide folios (CAF) al SII y los deja cargados y listos para emitir.

Por qué esto existe

El SII no tiene API de folios. No es una limitacion nuestra: no existe. La unica puerta es su portal web, y ahi se entra con el certificado digital (.p12) del contribuyente. Nosotros automatizamos ese tramite con un robot, y te lo damos como un endpoint.

Es el unico punto de toda la integracion donde hay un robot de por medio. Todo lo demas (emitir, consultar estado, RCV, reclamar) va por servicios.

Requisitos

  1. Certificado cargado. Sin el no hay como entrar al portal del SII. Sin certificado: 422 con codigo: "sin_certificado".

    Estudios contables: el certificado en Chile es de una persona (el representante legal), no de la empresa. NO existe un certificado "del estudio" que sirva para toda la cartera: cada empresa necesita el suyo. Cárgalos por empresa antes de integrar.

  2. Que el SII le tenga ese tipo autorizado a ese contribuyente. El SII autoriza los tipos de documento uno por uno. Si el tuyo no lo tiene, respondemos 422 con codigo: "tipo_no_solicitable" y te decimos que el tramite se hace en el portal del SII. No mandamos al robot a pelear con el portal: cada sesion perdida acerca el bloqueo por "maximo de sesiones" del SII.

  3. Scope caf:write.

Cuantos folios

cantidad es opcional, y lo normal es NO mandarla. Si la omites, decidimos nosotros: tu consumo real, acotado por lo que el SII te autoriza (a un emisor nuevo el SII suele autorizar entre 1 y 5).

Si la mandas, la respetamos — pero nunca por encima del techo del SII. Pedir 500 cuando el SII autoriza 5 no da 500 folios: da un rechazo y una sesion perdida. La respuesta te dice cuantos se pidieron de verdad.

Los folios son un recurso secuencial y finito del contribuyente: los que no se usan hay que declarárselos al SII. Pedir de mas no desperdicia CPU, le quema algo suyo.

Ambiente

Lo define tu API Key: sk_test_… baja folios de certificacion (maullin) y sk_live_… de produccion (palena). Nunca un default global — mezclar ambientes hace que el SII rechace el DTE con CAF-3-516.

Varias empresas

Con una clave de organizacion, elige la empresa con X-Empresa-RUT. Los folios son del contribuyente, no de quien lo administra.

Es idempotente: no pasa nada si lo llamas dos veces

Pedir folios aloca un rango real e irreversible en el SII, asi que este endpoint se protege solo. No necesitas mandar ninguna cabecera:

  • Si ya hay una solicitud del mismo tipo en curso (otro clic, otro proceso tuyo, tu reintento automatico), la segunda recibe 429 con codigo: "solicitud_en_curso" y Retry-After. No abrimos una segunda sesion en el SII. Espera lo que dice Retry-After (la solicitud en curso puede tardar minutos) y consulta GET /caf/status.
  • Si reintentas dentro de 2 minutos despues de una solicitud que si funciono, te devolvemos el mismo timbraje (201, con idempotente: true) en vez de pedir otro rango. Pasados 2 minutos, sin Idempotency-Key, un nuevo POST es un pedido nuevo (pide otro rango).
  • Con la cabecera Idempotency-Key la proteccion no vence: la misma clave devuelve siempre la misma solicitud (201 con idempotente: true si termino con folios; 429/409 si sigue en curso o verificandose). Si termino sin folios (fallida u omitida), la misma clave se puede usar para intentar de nuevo. Una clave reusada con otro tipo, cantidad o ambiente responde 422 idempotency_key_reutilizada. Recomendado: una clave estable por intencion de pedir folios.
  • Si el SII declara que todavia tienes folios de ese tipo sin usar, respondemos 409 con codigo: "folios_sin_usar_en_el_sii". Mientras queden folios sin emitir el SII no entrega nuevos: hay que emitirlos o anularlos en su portal.

Cuanto tarda, y que timeout poner

Sincrono (sin Prefer): la respuesta llega cuando el robot termino en el portal del SII. Lo normal es 1 a 3 minutos; el robot tiene hasta 300 s y la plataforma sostiene la peticion hasta 630 s. Configura tu cliente HTTP con un timeout de al menos 600 s. Si tu infraestructura no aguanta eso, usa el modo asincrono.

Modo asincrono (Prefer: respond-async)

Con la cabecera Prefer: respond-async validamos en la misma peticion todo lo que no toca el SII (422, 409, 429) y respondemos 202 con solicitud_id, estado: "en_cola" y la cabecera Location (/caf/solicitudes/{id}). El tramite lo hace un proceso en segundo plano:

  • Consulta GET /caf/solicitudes/{id} (respeta Retry-After) hasta que estado sea completado, fallido u omitido. Completada trae las mismas claves que el 201 (desde, hasta, caf_id, …).
  • O suscribete a los webhooks folios.recibidos y folios.solicitud_fallida.
  • Si ya hay una solicitud abierta del mismo tipo y ambiente, el 202 devuelve esa misma (no se encola otra).

Sin la cabecera, el comportamiento es el de siempre (201 sincrono).

Si no sabemos si el SII timbro: 504 resultado_incierto

Si la llamada al robot se corta sin respuesta, o el robot falla despues de enviar el pedido de numeracion al SII (desde el 16-oct-2026), no sabemos si el SII alcanzo a timbrar. Respondemos 504 con codigo: "resultado_incierto" y solicitud_id. No reintentes pidiendo otro rango: verificamos en el SII (a partir de verificar_desde, ~10 min despues del corte) y, si el SII timbro, rescatamos ese CAF y queda cargado. Mientras tanto, cualquier pedido del mismo tipo y ambiente responde 409 verificando_solicitud_anterior con Retry-After. El desenlace queda en GET /caf/solicitudes/{solicitud_id} (completado con codigo: "rescatado_tras_corte", o fallido con codigo: "sin_timbraje_en_el_sii", que significa que puedes volver a pedir) y en los webhooks de folios.

Si perdiste la respuesta

Con Idempotency-Key: repite el POST con la misma clave. Sin clave: consulta GET /caf/status o GET /caf/actividad antes de volver a pedir.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Prefer
string
Example: respond-async

respond-async para el modo asincrono (202 + Location). Sin ella, 201 sincrono.

Idempotency-Key
string <= 255 characters

Identifica UNA intencion de pedir folios (hasta 255 caracteres). La misma clave devuelve la misma solicitud, sin plazo de vencimiento.

Request Body schema: application/json
required
tipo_dte
required
integer
Enum: 33 34 39 41 46 52 56 61 110 111 112

Tipo de documento para el que se solicitan folios.

cantidad
integer [ 1 .. 500 ]
Default: 100

Cantidad de folios a solicitar.

ambiente
string
Enum: "certificacion" "produccion"

Para el portal. Con API Key se ignora: los folios se piden en el ambiente de la llave (sk_test_ = certificacion, sk_live_ = produccion).

Responses

Request samples

Content type
application/json
Example
{
  • "tipo_dte": 39
}

Response samples

Content type
application/json
{
  • "tipo_dte": 0,
  • "tipo_nombre": "string",
  • "desde": 0,
  • "hasta": 0,
  • "total_folios": 0,
  • "fecha_autorizacion": "string",
  • "caf_id": 0,
  • "uso_del_rango": {
    },
  • "message": "string",
  • "idempotente": true,
  • "solicitud_id": "696a0b13-577b-49ee-8881-cabf30a611ca"
}

Solicitar folios (CAF) de varios tipos en una sola sesión

Solicita CAF de varios tipos de documento en un solo ingreso al SII (una sola sesión del robot/RPA), usando el certificado digital (.p12) de tu empresa. Por defecto solicita sólo los tipos que tu empresa usa (desde el 21-oct-2026; antes, los habilitados al registrarse); con tipos pides los que nombres, y quedan en uso. Sin tipos y sin ningún tipo en uso: 422 sin_tipos_en_uso.

El ambiente lo define tu API Key (sk_test_…→certificación / sk_live_…→producción); opcionalmente puedes forzarlo por documento con el campo ambiente del body (por ejemplo para bajar folios de producción sin cambiar el ambiente por defecto). Nunca se usa un default global.

Requiere el scope caf:write. Sin certificado cargado responde 422. La respuesta lista los CAF cargados, los errores por tipo (carga parcial: algunos tipos pueden cargarse aunque otros fallen) y los omitidos: tipos que no se le pidieron al SII a proposito —porque ya habia una solicitud de ese tipo en curso, porque se acababa de aprovisionar, o porque el SII declara folios de ese tipo sin usar—. Un omitido no es un error: nada fallo, no se pidio.

Duracion: una sola sesion para todos los tipos; el robot tiene hasta 120 + 120 x tipos segundos (tope 540). Pon un timeout de cliente de al menos 600 s. Este endpoint es solo sincrono.

Si el robot no responde, 504 con codigo: "resultado_incierto": igual que en POST /caf/solicitar, no se sabe si el SII timbro, se verifica sola, y mientras tanto esos tipos aparecen en omitidos con motivo: "verificando_solicitud_anterior". Lo mismo para un tipo cuyo pedido de numeracion alcanzo a salir y el robot fallo despues (desde el 16-oct-2026): llega en errores y, hasta que se verifique, la proxima solicitud de ese tipo lo trae en omitidos con el mismo motivo.

Si el SII rechaza la sesion por maximo de sesiones a mitad del pedido (desde el 16-oct-2026), lo que alcanzo a bajar queda cargado y viene en cargados; los tipos que no se alcanzaron a pedir vienen en omitidos con motivo: "sii_maximo_de_sesiones" (no se le pidio nada al SII por ellos: se vuelven a pedir pasados ~35 min). Si el bloqueo llego DESPUES de pedir la numeracion de un tipo, aunque no haya bajado ningun CAF, la respuesta tambien es 201: ese tipo viene en errores (el pedido pudo llegar al SII: se verifica y no se vuelve a pedir hasta saberlo, como arriba) y los que quedaban, en omitidos. Solo si no se alcanzo a pedir nada sigue siendo el 502 sii_maximo_de_sesiones de siempre.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Request Body schema: application/json
optional
cantidad
integer [ 1 .. 500 ]
Default: 1

Folios a solicitar por cada tipo.

tipos
Array of integers
Items Enum: 33 34 39 41 46 52 56 61

Tipos de documento a solicitar: cada uno es un pedido explícito y queda en uso 180 días. Omitir = sólo los tipos que tu empresa USA en ese ambiente (emitidos en los últimos 180 días, registrados por el SII en tu RCV de ventas, o pedidos antes). Desde el 21-oct-2026 ya NO se piden los habilitados al registrarse ni la boleta «por defecto»: sin ningún tipo en uso responde 422 con codigo: "sin_tipos_en_uso" y no pide nada.

ambiente
string
Enum: "certificacion" "produccion"

Override opcional del ambiente por documento. Si se omite, manda el ambiente de la API Key (sk_test_/sk_live_) o el de tu empresa.

Responses

Request samples

Content type
application/json
Example
{ }

Response samples

Content type
application/json
{
  • "message": "string",
  • "cargados": [
    ],
  • "errores": [
    ],
  • "omitidos": [
    ]
}

Estado de una solicitud de folios

El estado de UNA solicitud de folios: la del 202 de Prefer: respond-async, la del 504 resultado_incierto, o la que identifica tu Idempotency-Key (todas traen solicitud_id; el 201 sincrono tambien).

estado Significa
en_cola Aceptada, esperando turno (el certificado abre una sesion a la vez en el SII).
procesando El robot esta en el portal del SII.
incierto El robot no respondio, o fallo despues de enviar el pedido de numeracion: estamos verificando en el SII si timbro (verificacion). No pidas otro rango.
completado Folios cargados. Trae las mismas claves que el 201 (desde, hasta, total_folios, fecha_autorizacion, caf_id). codigo: rescatado_tras_corte si se rescato tras un corte.
omitido No se le pidio al SII a proposito (codigo: precondiciones, solicitud_en_curso, folios_sin_usar_en_el_sii, tope_diario_solicitudes, verificando_solicitud_anterior, sii_maximo_de_sesiones —el SII rechazo la sesion a mitad de un pedido de varios tipos: no se alcanzo a pedir este—).
fallido No se cargaron folios (codigo: rpa_no_disponible, rpa_error, sii_maximo_de_sesiones, caf_invalido, sin_timbraje_en_el_sii, timbraje_sin_recuperar, expirada, no_procesada, plan_sin_folios, verificacion_vencida, cola_no_disponible).

Mientras la solicitud este abierta la respuesta trae Retry-After.

Para una persona (27-oct-2026, aditivo). Cada respuesta trae además situacion (en_proceso, listo, lo_resolvemos, accion_cliente, soporte), su titulo, mensaje_cliente (sin texto de la página del SII), accion cuando te toca hacer algo, plazo_esperado mientras está abierta —p50/p95 medidos del robot, no un número fijo— y cantidad_otorgada al completarse (el SII puede entregar menos de lo pedido). Ver Tiempos de respuesta y demoras en la Guía. Scope caf:read.

Authorizations:
ApiKeyAuth
path Parameters
solicitud_id
required
string <uuid>
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "solicitud_id": "696a0b13-577b-49ee-8881-cabf30a611ca",
  • "estado": "en_cola",
  • "tipo_dte": 0,
  • "tipo_nombre": "string",
  • "ambiente": "certificacion",
  • "cantidad": 0,
  • "modo": "sincrono",
  • "codigo": "string",
  • "mensaje": "string",
  • "creada_at": "2019-08-24T14:15:22Z",
  • "iniciada_at": "2019-08-24T14:15:22Z",
  • "terminada_at": "2019-08-24T14:15:22Z",
  • "verificacion": {
    },
  • "message": "string",
  • "desde": 0,
  • "hasta": 0,
  • "total_folios": 0,
  • "fecha_autorizacion": "string",
  • "caf_id": 0,
  • "situacion": "en_proceso",
  • "titulo": "string",
  • "motivo": "string",
  • "mensaje_cliente": "string",
  • "accion": {
    },
  • "plazo_esperado": {
    },
  • "cantidad_otorgada": 0,
  • "soporte": {
    }
}

Reportes

Agregados de ventas

Serie temporal de ventas

Una fila por día o mes. documentos cuenta TODO lo emitido en el período.

suma_total son VENTAS VÁLIDAS, no la suma de todo lo emitido (desde el 17-sep-2026; antes sumaba todo, incluso notas de crédito en positivo y rechazados):

suma_total = Σ (33, 34, 39, 41, 43, 56 válidos) − Σ (61 válidas)

  • Válido = estado_local aceptado o aceptado_con_reparos, o anulado por una nota de crédito emitida acá (el original suma y la nota resta: neto 0, sin restar dos veces).
  • suma_neto, suma_iva y suma_exento siguen la misma regla.
  • No entran (van en excluidos.por_motivo): guías de despacho 52 (guia_despacho), facturas de compra 46 (factura_compra), exportación 110/111/112 (exportacion_moneda_extranjera: su monto está en la moneda del documento, no en pesos), rechazados (rechazado), error_envio y anulado sin nota de crédito acá (anulado_sin_nota_credito).
  • Aparte (en_proceso): pendiente, enviando y enviado, sin veredicto del SII todavía. No se suman; súmalos tú si quieres una cifra temprana.
  • total_bruto_emitido es la suma de monto_total de todo el conjunto (la cifra que antes venía en suma_total).
Authorizations:
ApiKeyAuth
query Parameters
group_by
string
Default: "mes"
Enum: "dia" "mes"
desde
string <date>
hasta
string <date>
q
string <= 200 characters

Búsqueda libre por razón social o RUT del receptor (mismos filtros que GET /dte).

rut_receptor
string <= 20 characters
tipo_dte
string

Un tipo o CSV, ej. "33,34"

grupo
string
Enum: "facturas" "boletas" "todos"
estado_local
string <= 30 characters

Un estado o CSV (ver GET /dte).

estado_sii
string <= 60 characters

Un estado SII o CSV

monto_min
integer >= 0
monto_max
integer >= 0
incluir_pruebas
boolean
Default: false

Por defecto NO se devuelven los documentos que emitió Facturador Pulsando con tu RUT al poner en marcha el sistema (set de certificación, prueba inicial y sus notas de crédito; llevan marca_operativa). Con 1 se incluyen. Aplica igual al listado, al resumen y a los reportes.

ambiente
string
Enum: "certificacion" "produccion"

Ambiente de los documentos a mirar, desde el portal. Con API Key se ignora: se ven siempre los del ambiente de la llave (sk_test_ = certificacion, sk_live_ = produccion).

header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "group_by": "string",
  • "serie": [
    ]
}

Top receptores por monto

Receptores ordenados por suma_total descendente. suma_total son las VENTAS VÁLIDAS a ese receptor, con la misma fórmula que GET /dte/resumen (notas de crédito restan; guías 52, compras 46, exportación, rechazados, error_envio y en proceso no suman). documentos cuenta todo lo emitido a ese receptor y total_bruto_emitido suma su monto_total sin filtrar. Un receptor sólo con documentos excluidos aparece con suma_total: 0.

Authorizations:
ApiKeyAuth
query Parameters
limit
integer [ 1 .. 100 ]
Default: 10
desde
string <date>
hasta
string <date>
q
string <= 200 characters

Búsqueda libre por razón social o RUT del receptor (mismos filtros que GET /dte).

rut_receptor
string <= 20 characters
tipo_dte
string

Un tipo o CSV, ej. "33,34"

grupo
string
Enum: "facturas" "boletas" "todos"
estado_local
string <= 30 characters

Un estado o CSV (ver GET /dte).

estado_sii
string <= 60 characters

Un estado SII o CSV

monto_min
integer >= 0
monto_max
integer >= 0
incluir_pruebas
boolean
Default: false

Por defecto NO se devuelven los documentos que emitió Facturador Pulsando con tu RUT al poner en marcha el sistema (set de certificación, prueba inicial y sus notas de crédito; llevan marca_operativa). Con 1 se incluyen. Aplica igual al listado, al resumen y a los reportes.

ambiente
string
Enum: "certificacion" "produccion"

Ambiente de los documentos a mirar, desde el portal. Con API Key se ignora: se ven siempre los del ambiente de la llave (sk_test_ = certificacion, sk_live_ = produccion).

header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Enlace al receptor (portal)

Acceso por token para que el receptor consulte y descargue el DTE, sin inicio de sesión ni API Key. El token se obtiene con POST /dte/{id}/portal-link.

Metadatos del DTE por token (acceso del receptor, sin API Key)

Acceso por token (sin inicio de sesión ni API Key) que abre el receptor con el token generado por POST /dte/{id}/portal-link. El token es opaco y no enumerable, y su vigencia es de 6 años (la retención legal del XML). Ruta real: GET /api/portal/dte/{token}.

path Parameters
token
required
string

Token opaco de 64 caracteres

Responses

Response samples

Content type
application/json
{
  • "folio": 0,
  • "tipo_dte": 0,
  • "tipo_nombre": "string",
  • "fecha_emision": "2019-08-24",
  • "razon_emisor": "string",
  • "rut_emisor": "78211386-0",
  • "razon_receptor": "string",
  • "rut_receptor": "12345678-5",
  • "monto_total": 0,
  • "estado_sii": "string",
  • "pdf_url": "http://example.com"
}

PDF del DTE por token (acceso del receptor, sin API Key)

Devuelve el PDF binario del documento (ticket 80mm para boletas, carta para el resto). Acceso por token (sin inicio de sesión ni API Key) con el token de POST /dte/{id}/portal-link; vigencia de 6 años (la retención legal del XML). Ruta real: GET /api/portal/dte/{token}/pdf.

path Parameters
token
required
string

Responses

Mi suscripción

Qué te cobramos por usar el Facturador Pulsando y las facturas que te emitimos por eso — el gasto que este servicio representa para tu empresa. Sólo lectura, con el scope dte:read. Darte de baja NO se puede hacer por esta API ni por el MCP: se hace en el portal, con la cuenta del administrador de la empresa. La razón es que una clave sk_live_ es una credencial de máquina, puede vivir en el servidor de un tercero y no distingue quién la está usando.

Estado de tu suscripción al Facturador Pulsando

Qué te estamos cobrando por usar el servicio, y qué implicaría darte de baja.

El bloque baja es informativo: dice hasta cuándo conservarías acceso, qué se apagaría y qué conservarías, más donde_darse_de_baja con la dirección del portal.

La baja NO se puede ejecutar por esta API ni por el MCP. No es un endpoint que falte: esta API se autentica con una clave de máquina (sk_live_), que puede vivir en el servidor de un tercero, y no distingue quién de tu empresa la está usando. Dar de baja el servicio es una decisión del administrador y se hace desde el portal, con su cuenta.

Empresas de la cartera de un estudio contable u holding. Si tu empresa está en la cartera de una organización, la suscripción no es tuya: la administra y la paga esa organización. En ese caso estado, plan, ciclo, monto y periodo_fin son los de la suscripción de la organización —el monto es el de toda su cartera, no sólo el de tu empresa— y quien_paga lo dice con tipo: organizacion y su razón social. De la organización no sale nada más: ni sus otras empresas ni sus datos de pago.

Requiere scope dte:read.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Las facturas que te emitimos por tu suscripción

Lo que le pagaste al Facturador Pulsando y el documento tributario que te emitimos por cada pago — o sea, el gasto que este servicio representa para tu empresa. Sirve para incorporarlo a tu libro de compras junto con los DTE de tus otros proveedores.

pdf_url es un enlace público y sin login al PDF, con la misma vigencia que el XML (6 años). Cuando todavía no hay documento emitido, dte_motivo explica por qué (por ejemplo, que faltan datos de tu empresa).

Este listado sigue disponible aunque la suscripción esté morosa o dada de baja: son documentos de lo que ya pagaste.

Requiere scope dte:read.

Authorizations:
ApiKeyAuth
query Parameters
page
integer >= 1
per_page
integer [ 1 .. 200 ]
Default: 50
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Webhooks

Registro y gestión de webhooks salientes (requiere el scope webhook:manage). También gestionables desde el portal. La plataforma envía un POST firmado (HMAC-SHA256) a tu endpoint cuando el SII responde.

Requisitos de tu endpoint. Tiene que ser https, con un dominio que resuelva a una IP pública y un certificado TLS emitido por una CA pública. Un certificado autofirmado supera el registro pero falla en cada entrega con cURL error 60: SSL certificate problem — lo vas a ver en GET /webhooks/{id}/deliveries. Para probar desde tu máquina usa un túnel (Cloudflare Tunnel, ngrok): ya entregan https con certificado válido.

Si el dominio todavía no resuelve el registro se rechaza pidiéndote que reintentes: es transitorio, no hace falta cambiar la URL.

Entrega y reintentos. Cada evento tiene un id y un created_at que no cambian entre reintentos ni entre endpoints: deduplica por id. El header X-Webhook-Delivery, en cambio, identifica al intento y cambia en cada uno. Cada endpoint suscrito recibe su propia entrega, independiente de las demás.

Se reintenta ante un error de conexión, un timeout de 10 segundos o una respuesta 5xx, 408, 425 o 429: tres intentos como máximo, uno inmediato, otro a los 60 segundos y un último 5 minutos después.

No se reintenta ante una respuesta 3xx (las redirecciones no se siguen) ni ante el resto de los 4xx (por ejemplo, 401 por firma inválida o 404): el intento queda registrado en GET /webhooks/{id}/deliveries y no llega de nuevo. Tampoco se reintenta una URL que la plataforma bloquea por seguridad.

Qué responder. Responde 2xx apenas verifiques la firma y guardes el evento, y procésalo después: el cuerpo es una señal, y el estado de un documento lo dice GET /dte/{id}. Responde 5xx sólo si no pudiste guardar el evento, para que vuelva a llegar. Y deduplica por id: un mismo evento puede llegarte más de una vez.

El orden de llegada no está garantizado. Cada evento y cada endpoint se entregan por separado, y un reintento llega minutos después: un dte.aceptado puede llegarte antes que su dte.enviado. Decide con GET /dte/{id}, nunca por el orden en que llegan.

Firma con marca de tiempo (anti-replay). Además de X-Webhook-Signature, cada entrega trae X-Webhook-Timestamp (segundos Unix) y X-Webhook-Signature-V2: t=<timestamp>,v1=<hex>, donde v1 es HMAC-SHA256 con tu secret sobre <timestamp>.<cuerpo crudo> (el timestamp, un punto y el cuerpo). Verifica la V2 y rechaza un t con más de 5 minutos de diferencia con tu reloj: así un cuerpo capturado no sirve para reenviártelo después. La firma original sigue llegando igual.

Endpoints que fallan. GET /webhooks informa fallas_consecutivas (eventos seguidos que no se pudieron entregar) y fallando_desde. Al quinto evento seguido sin entregar avisamos por correo a los usuarios de la empresa, una vez por racha. El endpoint no se desactiva solo: la primera entrega buena reinicia la racha. Lo que no llegó se recupera con POST /webhooks/{id}/deliveries/{delivery}/reenviar, con el mismo id de evento.

Llaves de prueba en producción. Si la empresa está en producción, una llave sk_test_ puede consultar sus webhooks, pero no crearlos, modificarlos, borrarlos, probarlos, reenviar eventos ni rotar el secreto: responde 403 con codigo: webhook_requiere_llave_live. Esos endpoints reciben eventos de documentos con validez tributaria.

Historial. Se conservan 90 días de entregas. Borrar un endpoint borra su historial; para dejar de recibir sin perderlo, usa PATCH con activo: false.

A dónde se conecta. La plataforma resuelve tu dominio, comprueba que TODAS sus IP sean públicas y conecta a esas mismas IP. El puerto tiene que ser el 443 o uno sobre 1024 que no sea de un servicio interno conocido (por ejemplo 3306, 5432 o 6379).

Listar webhooks

Lista los endpoints de webhook registrados por tu empresa. También se pueden gestionar desde el portal (Configuración → Webhooks).

Requiere una API Key con el scope webhook:manage.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Registrar un webhook

Registra un endpoint al que enviaremos un POST firmado cuando ocurran los eventos suscritos. El secret se devuelve una sola vez en esta respuesta — guárdalo para verificar la firma X-Webhook-Signature.

La url debe ser https, no puede apuntar a hosts internos ni a direcciones privadas o de uso especial (todas las IP a las que resuelva tienen que ser públicas) y el puerto tiene que ser el 443 o uno sobre 1024 que no sea de un servicio interno. Máximo 10 endpoints por empresa.

Requiere una API Key con el scope webhook:manage. Si la empresa está en producción, la llave tiene que ser sk_live_ (ver 403).

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Request Body schema: application/json
required
url
required
string <uri>

URL https a la que enviaremos los POST. No puede apuntar a hosts internos ni a direcciones privadas/reservadas.

eventos
Array of strings
Items Enum: "dte.aceptado" "dte.rechazado" "dte.reparado" "dte.anulado" "dte.enviado" "dte.error_envio" "dte.reclamado" "dte.acuse_receptor" "dte.aceptado_tacitamente" "dte.respuesta_receptor" "dte.entrega_receptor_fallida" "factura_compra.recibida" "folios.por_agotarse" "folios.recibidos" "folios.solicitud_fallida" "nomina.fase_cambiada" "previred.sincronizacion_iniciada" "previred.conectado" "previred.trabajadores_leidos" "previred.fichas_creadas" "previred.sincronizacion_lista" "previred.sincronizacion_error"

Eventos a los que suscribirse. Omitirlo, null o la lista vacía [] significan todos (también los que se agreguen en el futuro). Para dejar de recibir, usa activo: false, no eventos: [].

descripcion
string or null <= 200 characters

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "message": "string",
  • "data": {
    }
}

Actualizar un webhook

Actualiza la url, los eventos, la descripcion o el estado activo. Requiere una API Key con el scope webhook:manage.

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Request Body schema: application/json
url
required
string <uri>

URL https a la que enviaremos los POST. No puede apuntar a hosts internos ni a direcciones privadas/reservadas.

eventos
Array of strings
Items Enum: "dte.aceptado" "dte.rechazado" "dte.reparado" "dte.anulado" "dte.enviado" "dte.error_envio" "dte.reclamado" "dte.acuse_receptor" "dte.aceptado_tacitamente" "dte.respuesta_receptor" "dte.entrega_receptor_fallida" "factura_compra.recibida" "folios.por_agotarse" "folios.recibidos" "folios.solicitud_fallida" "nomina.fase_cambiada" "previred.sincronizacion_iniciada" "previred.conectado" "previred.trabajadores_leidos" "previred.fichas_creadas" "previred.sincronizacion_lista" "previred.sincronizacion_error"

Eventos a los que suscribirse. Omitirlo, null o la lista vacía [] significan todos (también los que se agreguen en el futuro). Para dejar de recibir, usa activo: false, no eventos: [].

descripcion
string or null <= 200 characters

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "message": "string",
  • "codigo": "string"
}

Eliminar un webhook

Elimina el endpoint y todo su historial de entregas, sin vuelta atrás. Para dejar de recibir eventos sin perder el historial, usa PATCH con activo: false. Requiere una API Key con el scope webhook:manage.

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "message": "string",
  • "codigo": "string"
}

Enviar un evento de prueba

Envía un evento dte.aceptado de prueba sólo a este endpoint, para verificar que recibe y valida la firma. Llega con data.test = true y data.dte_id = 0: tu receptor debe responder 2xx sin tocar ningún documento. Si responde 2xx, la respuesta es 200 con el http_status que devolvió. Si no, es 502 con error y http_status, que viene en null cuando no hubo respuesta: error de conexión, timeout o URL bloqueada por seguridad. Requiere el scope webhook:manage.

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "message": "Evento de prueba enviado.",
  • "http_status": 200
}

Historial de entregas

Últimas 50 entregas del endpoint, de la más nueva a la más vieja. Cada intento es una fila, con el evento_id del evento, el cuerpo enviado (payload) y lo que respondió tu endpoint. Los que no se reintentan —3xx y los 4xx distintos de 408, 425 y 429— quedan registrados sólo acá. Las entregas de POST /webhooks/{id}/test vienen con es_prueba: true. Se conservan 90 días. Requiere el scope webhook:manage.

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Reenviar un evento

Vuelve a mandar a este endpoint el mismo evento de esa entrega: el mismo cuerpo y el mismo id, así que tu receptor lo deduplica si ya lo tenía. Sirve para recuperar lo que no llegó mientras tu servidor estuvo caído. Es síncrono y de un intento, y queda como una fila nueva en el historial. Responde igual que POST /webhooks/{id}/test: 200 si tu endpoint respondió 2xx, 502 si no. Requiere el scope webhook:manage (y sk_live_ si la empresa está en producción).

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer
delivery
required
integer

id de la entrega en GET /webhooks/{id}/deliveries.

header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "message": "Evento reenviado.",
  • "http_status": 200,
  • "evento_id": "wh_a1b2c3d4e5f6a7b8"
}

Rotar el secreto

Genera un secret nuevo y lo devuelve una sola vez. El anterior deja de valer en el acto: la próxima entrega ya va firmada con el nuevo, así que actualiza tu receptor antes (o acepta los dos secretos por un rato). El historial de entregas no se pierde. Requiere el scope webhook:manage (y sk_live_ si la empresa está en producción).

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "message": "string",
  • "data": {
    }
}

Eventos disponibles

Lista los eventos a los que un webhook puede suscribirse.

Authorizations:
ApiKeyAuth
header Parameters
X-Empresa-RUT
string
Example: 76354771-K

RUT de la empresa emisora. Se acepta en TODOS los endpoints de este canal.

  • Clave de organización (estudio contable, holding): obligatorio. Sin él la respuesta es 400. Usa GET /empresas para ver cuáles administras.
  • Clave de empresa: no lo envíes. Si lo mandas se ignora — el RUT emisor lo fija la clave y no se puede cambiar desde el request.

Formato libre: 76354771, 76354771-K o 76.354.771-K son equivalentes.

Este header selecciona la empresa; no la inventa. Los datos del emisor (RUT, razón social, giro, actividad económica) se leen siempre del registro de esa empresa, nunca del cuerpo de la petición.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}