sendToSii()
Sube documentos firmados al SII dentro de un sobre firmado y retorna el track ID con el que les haces seguimiento.
Uso básico#
import { sendToSii } from 'dte-sdk'
const { trackId, receivedAt } = await sendToSii(signed, {
certificate,
environment: 'certification',
senderRut: '15.234.567-4',
resolution: { number: 0, date: '2026-09-01' },
})
trackId // '0234567890'
receivedAt // '2026-10-28T10:15:44-03:00'Firma de tipo#
function sendToSii(
docs: SignedDte | SignedDte[],
options: {
certificate: Certificate
environment: 'certification' | 'production'
senderRut: string // RUT of the person sending (certificate owner)
resolution: { number: number; date: string }
signal?: AbortSignal
},
): Promise<{ trackId: string; receivedAt: string }>Parámetros#
docs(SignedDte | SignedDte[]) - Un documento firmado, o varios para enviarlos en un solo sobre. Envía documentos de un solo emisor por llamada.optionscertificate(Certificate) - Cargado conloadCertificate(). Firma el sobre y autentica ante el SII.environment('certification' | 'production') - Usa'certification'mientras pasas por el proceso de certificación del SII, y'production'una vez que estés autorizado.senderRut(string) - El RUT de la persona que envía, dueña del certificado. No es el RUT de la empresa.resolution({ number, date }) - Número y fecha (YYYY-MM-DD) de la resolución del SII que autoriza al emisor a emitir documentos electrónicos. En certificación el número es0.signal(AbortSignal, opcional) - Cancela el envío, por ejemplo conAbortSignal.timeout(30_000).
Valor de retorno#
Retorna una promesa de:
trackId(string) - El identificador que el SII asignó al envío. Guárdalo: es la forma de consultar el resultado más adelante.receivedAt(string) - Cuándo lo recibió el SII, como marca de tiempo ISO 8601.
Un track ID significa que el SII recibió el sobre, no que aceptó los documentos. La aceptación llega después, a través de getStatus().
Qué hace#
Arma el sobre
Pone cada documento firmado dentro de un sobre EnvioDTE y firma el sobre con tu certificado.
Se autentica
Pide una semilla al SII, la cambia por un token y guarda el token en caché por certificado, para que las llamadas seguidas no vuelvan a autenticarse.
Sube el sobre
Envía el sobre al ambiente que elegiste.
Retorna el track ID
Resuelve con trackId y receivedAt en cuanto el SII confirma la recepción.
Errores#
| Código | Cuándo | Qué hacer |
|---|---|---|
SII_UNAVAILABLE | No se pudo conectar con el SII, se agotó el tiempo de espera o el servicio está caído | Reintenta más tarde con backoff, usando los mismos documentos firmados |
SII_REJECTED | El SII rechazó el envío, por ejemplo la autenticación o el sobre | No reintentes tal cual: revisa el certificado, el RUT del enviador y la resolución |
getStatus()#
Le pregunta al SII qué pasó con un envío.
import { getStatus } from 'dte-sdk'
const status = await getStatus('0234567890', {
certificate,
environment: 'certification',
issuerRut: '76.123.456-0',
})
status.state // 'accepted'
status.documents // [{ type: 33, folio: 1024, state: 'accepted' }]function getStatus(
trackId: string,
options: {
certificate: Certificate
environment: 'certification' | 'production'
issuerRut: string
},
): Promise<Status>
type Status = {
state: 'received' | 'accepted' | 'accepted_with_objections' | 'rejected'
documents: {
type: DteType
folio: number
state: 'received' | 'accepted' | 'accepted_with_objections' | 'rejected'
reason?: string
}[]
}trackId- El identificador que retornósendToSii().options.certificate,options.environment- Los mismos con los que enviaste.options.issuerRut- El RUT de la empresa que emitió los documentos.
Igual que sendToSii(), lanza SII_UNAVAILABLE cuando no se puede conectar con el SII.
Estados de aceptación#
| Estado | Significado | Qué hacer |
|---|---|---|
received | El SII tiene el sobre y todavía lo está validando. | Vuelve a consultar más tarde |
accepted | Los documentos son válidos | Entrégalos al cliente |
accepted_with_objections | Aceptado con reparos. reason explica cada uno. | El documento es válido; corrige la causa en los próximos documentos |
rejected | El SII lo rechazó. reason explica por qué. | Corrige la causa y vuelve a emitir el documento |
state resume el sobre completo. Cuando envías varios documentos a la vez, revisa documents para ver el resultado de cada uno.
Ejemplos#
Enviar un lote#
import { sendToSii } from 'dte-sdk'
const { trackId } = await sendToSii([invoice, creditNote], {
certificate,
environment: 'production',
senderRut: process.env.DTE_SENDER_RUT!,
resolution: {
number: Number(process.env.SII_RESOLUTION_NUMBER),
date: process.env.SII_RESOLUTION_DATE!,
},
})Cortar envíos lentos#
const { trackId } = await sendToSii(signed, {
...siiOptions,
signal: AbortSignal.timeout(30_000),
})Reintentar cuando el SII no está disponible#
import { DteError, sendToSii, type SignedDte } from 'dte-sdk'
async function sendWithRetry(docs: SignedDte[], attempts = 3) {
for (let attempt = 1; ; attempt++) {
try {
return await sendToSii(docs, siiOptions)
} catch (error) {
const retryable = error instanceof DteError && error.code === 'SII_UNAVAILABLE'
if (!retryable || attempt === attempts) throw error
await new Promise((resolve) => setTimeout(resolve, 2_000 * 2 ** attempt))
}
}
}Esperar un estado final#
La validación suele tomar un rato. Consulta con una espera creciente, y deja el resto a un job en segundo plano si sigue en received:
import { getStatus } from 'dte-sdk'
async function waitForSii(trackId: string) {
for (let attempt = 0; attempt < 5; attempt++) {
const status = await getStatus(trackId, {
certificate,
environment: 'production',
issuerRut: '76.123.456-0',
})
if (status.state !== 'received') return status
await new Promise((resolve) => setTimeout(resolve, 5_000 * 2 ** attempt))
}
return null // still processing: check again from a scheduled job
}Revisa Emitir una factura para ver un flujo completo que guarda el track ID y consulta el estado desde un job.
Funciones relacionadas#
signDte()- Produce losSignedDteque envíastoXml()- Guarda una copia exacta de lo que enviastecreateDte()- Donde empieza todo documento