Introducción a SII SDK
Qué es SII SDK, qué hace, qué no hace y el modelo mental de la librería: Resultado<T, ErrorSii>, texto literal del SII y tu sistema decide cuándo llamar.
Para agentes: esta página en Markdown está en /docs/introduccion.md, toda la documentación en /llms-full.txt y las reglas de integración en /agents.md.
En esta página
SII SDK es una librería TypeScript de Devlas SpA (paquetes @devlas-cl/*, versión publicada 0.6.0) para emitir y recibir documentos tributarios electrónicos ante el SII de Chile. Se instala como dependencia y corre dentro del sistema del integrador; no es un servicio alojado ni consulta servidores de Devlas al ejecutarse. Esta página resume qué hace, qué deja en manos de tu sistema y las reglas que siguen todas sus funciones.
SII SDK no es un producto del Servicio de Impuestos Internos ni está afiliado a él.
Qué hace
- Valida los datos de un documento contra las reglas del SII y los largos del XSD, sin recortar nada en silencio.
- Calcula montos (neto, IVA, exento, descuentos, impuestos adicionales), arma el XML en el orden del esquema, lo timbra con el CAF, lo firma y lo valida contra el XSD oficial antes de enviarlo.
- Se autentica (semilla y token), envía (boletas 39 y 41 por la API REST del SII; facturas, notas y guías por
DTEUpload) y consulta estados. - Pide, reobtiene y anula folios (CAF) y los repone con
autoCaf(paquete@devlas-cl/folios). - Lee el Registro de Compras y Ventas (RCV), responde el intercambio entre contribuyentes y registra aceptación o reclamo.
- Recorre la certificación ante el SII con un motor por etapas (paquete
@devlas-cl/certificacion) y verifica la habilitación en producción. - Genera la representación impresa (ticket térmico y PDF) con el timbre PDF417.
Qué no hace (y qué hace tu sistema)
| La librería no... | Qué hace tu sistema |
|---|---|
| Persiste nada: ni folios, ni sesiones, ni CAF, ni el XML emitido, ni el estado de un envío. | Guarda el XML firmado (la ley obliga a conservarlo 6 años), el track id (como texto) y el estado. Folios, sesiones y CAF entran por los puertos AlmacenCaf y AlmacenSesion, que implementas tú. |
| Planifica: no hay cola, temporizadores ni reintentos de negocio. | Decide cuándo llamar. La librería responde "qué hacer ahora" con funciones puras: siguienteConsultaDeEstado, siguienteAccionDeEnvio, decidirReenvio, autoCaf, avanzarCorrida. |
| Agrupa boletas por tiempo. | Cierra el grupo cuando siguienteAccionDeEnvio responde armar_sobres; la librería arma el sobre de hasta 500 boletas. |
| Recorta o corrige datos: un giro de 41 caracteres es un error, no se corta a 40. | Corrige el dato. |
| Lee tu correo. | Entrega el adjunto EnvioDTE o las glosas del correo del SII a las funciones de intercambio y de protocolo. |
| Cifra tus secretos. | Cifra en reposo el .pfx, su clave, el CAF (trae una llave privada) y las cookies de sesión. |
| Decide tu negocio (medios de pago, inventario, qué se documenta en una venta mixta). | Lo resuelve antes de llamar. |
| Llama a servidores de Devlas al ejecutarse. | Nada. Un servidor caído de Devlas no puede impedir emitir. |
| Tiene estado global. | Pasa la configuración y los puertos a cada llamada. Varias instancias y réplicas no se pisan. |
Modelo mental
1. Resultado en vez de excepciones
Toda operación devuelve Resultado<T, ErrorSii>:
import type { ErrorSii, Resultado } from '@devlas-cl/comun'
// type Resultado<T, E = ErrorSii> = { readonly ok: true; readonly valor: T } | { readonly ok: false; readonly error: E }
declare const r: Resultado<{ trackId: string }, ErrorSii>if (!r.ok) { r.error.codigo // CodigoError: catálogo cerrado ('VALIDACION', 'TRANSPORTE', 'LIMITE_SESIONES', ..., 'DESCONOCIDO') r.error.accion // 'reintentar' | 'esperar' | 'corregir' | 'tramitar' | 'escalar' r.error.mensajeSii // texto LITERAL del SII, o null si el error nace en la librería} else { r.valor.trackId}- Nada lanza por datos tuyos ni del SII. Solo lanza un argumento mal formado en la llamada (error de programación).
- El patrón de uso es
if (!r.ok) return r. - Decide por
codigo,codigoSiiyaccion, nunca comparando subcadenas demensajeSii. - El estado de un sobre no es un error:
consultarEstadoEnviodevuelveok: trueincluso con veredictorechazado.
2. El texto del SII llega literal
mensajeSii es el texto exacto del SII, decodificado del transporte (juego de caracteres y entidades HTML) y sin traducir ni recortar. Un mensaje que el catálogo no reconoce llega como DESCONOCIDO con su texto intacto y acción escalar. Para mostrar un error a una persona, mensajeParaUsuario(error) de @devlas-cl/comun devuelve { titulo, queHacer, detalle, nivel, reintentable } en español neutro, con el literal del SII aparte en detalle.
3. El ambiente es explícito
Ambiente = 'certificacion' | 'produccion'. Son registros distintos del SII: el folio, la resolución, el RCV y las sesiones de uno no existen en el otro. Se pasa en la configuración de cada llamada (ConfigToken.ambiente, ConfigPortal.ambiente) y en la clave de folios (ClaveCaf.ambiente).
4. El reloj es un parámetro
Las funciones puras reciben ahora: Date; las llamadas reciben un Reloj ({ ahora: () => Date }). Ningún paquete usa Date.now ni process.env por su cuenta. La fecha tributaria se calcula en hora de Chile con fechaTributaria(instante) de @devlas-cl/dominio, nunca con toISOString(): entre las 20:00 y las 24:00 de Chile la fecha UTC ya es la del día siguiente y el SII responde FECHA NO CORRESPONDE AL ENVIO.
5. Cuatro puertos
Lo que varía entre instalaciones entra por puertos que implementa tu sistema (la librería trae versiones en memoria para pruebas):
| Puerto | Contrato (de @devlas-cl/comun) |
Para qué |
|---|---|---|
Http |
{ solicitar(solicitud: SolicitudHttp): Promise<RespuestaHttp> } |
Llegar al SII. No sigue redirecciones, no guarda cookies, no reintenta y entrega el cuerpo en bytes. |
AlmacenSesion + Bloqueos |
obtener/guardar/borrar y adquirir/renovar/liberar |
La sesión del portal y el token, compartidos entre réplicas, y quién tiene el turno. |
AlmacenCaf |
guardarCaf/reservarFolio/liberarFolio/consultarCaf |
Los folios. reservarFolio debe ser atómico entre réplicas. |
Registro |
{ emitir(evento: EventoRegistro): void } |
Eventos y errores (por ejemplo emitir.envio_incierto, folios.bajos). No promete entrega. |
6. Una sola sesión por RUT
El SII cuenta las sesiones autenticadas por RUT y bloquea al superar el cupo (01.01.215.500.720, código LIMITE_SESIONES, acción esperar, al menos 35 minutos). Cerrar sesión no libera el cupo. Por eso las llamadas al portal comparten una sesión mediante AlmacenSesion y Bloqueos. Nunca reintentes un LIMITE_SESIONES: cada intento abre otra sesión.
Tres niveles de uso
| Nivel | Paquetes | Qué es |
|---|---|---|
| Piezas | comun, dominio, xml, protocolo, impresion |
Funciones puras: sin red, sin disco, sin reloj del sistema. Validar un RUT, calcular totales, armar y firmar un DTE, leer una respuesta del SII, dibujar el PDF417. |
| Llamadas | sii |
Una operación con el SII por el puerto Http. Hace una cosa y termina: emitir, enviarBoletas, enviarDte, consultarEstadoEnvio, resumenRcv. |
| Soluciones | soluciones, folios, certificacion |
Recetas que juntan lo anterior: habilitar, diagnosticarEmisor, autoCaf, el motor de certificación. |
Dependencias en un solo sentido: comun <- dominio <- xml <- protocolo <- sii <- soluciones <- folios <- certificacion. impresion usa solo dominio y xml.
emitir (de @devlas-cl/sii) compone validar, armar, timbrar, firmar, validar el XSD y enviar en una llamada. Cada paso también se usa suelto (prepararDte, prepararSobre, enviarBoletas, enviarDte) cuando necesitas intervenir entre pasos o agrupar boletas.
Requisitos
- Node.js 24 o superior. Solo ESM.
comun,dominio,impresiony el catálogo de errores corren también en el navegador, Electron y Capacitor. La firma, los certificados y la red al SII son solo de servidor.- Un certificado digital (
.pfxy su clave) del contribuyente o de un usuario autorizado, y una empresa certificada ante el SII para emitir en producción.
Páginas de esta documentación
docs/instalacion: registro privado,.npmrc, token y paquetes por nivel.docs/primeros-pasos: emitir una boleta 39 y consultar su estado.docs/autocaf: CAF,AlmacenCaf, pedir, reobtener, anular yautoCaf.docs/estado:consultarEstadoEnvio, códigos del SII ysiguienteConsultaDeEstado.docs/certificacion: motoravanzarCorrida, etapas, esperas y habilitación.docs/tiers: niveles, paquetes y licencia.docs/referencia-api: firmas de las funciones públicas y catálogo deErrorSii.docs/errores: errores comunes y cómo resolverlos.