Skip to content

sendToSii()

Uploads signed documents to the SII in a signed envelope and returns the track id you use to follow them.

Basic Usage#

TypeScript
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'

Type Signature#

TypeScript
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 }>

Parameters#

  • docs (SignedDte | SignedDte[]) - One signed document, or several to send in a single envelope. Send documents from one issuer per call.
  • options
    • certificate (Certificate) - From loadCertificate(). It signs the envelope and authenticates with the SII.
    • environment ('certification' | 'production') - Use 'certification' while you go through the SII certification process, and 'production' once you're authorized.
    • senderRut (string) - The RUT of the person sending, who owns the certificate. This is not the company RUT.
    • resolution ({ number, date }) - Number and date (YYYY-MM-DD) of the SII resolution that authorizes the issuer to emit electronic documents. In certification the number is 0.
    • signal (AbortSignal, optional) - Cancels the upload, for example with AbortSignal.timeout(30_000).

Return Value#

Returns a promise of:

  • trackId (string) - The id the SII assigned to the upload. Persist it: it's how you ask for the result later.
  • receivedAt (string) - When the SII received it, as an ISO 8601 timestamp.

A track id means the SII received the envelope, not that it accepted the documents. Acceptance comes later, through getStatus().

What It Does#

1

Wraps the documents

Puts every signed document into an EnvioDTE envelope and signs the envelope with your certificate.

2

Authenticates

Requests a seed from the SII, exchanges it for a token, and caches the token per certificate so consecutive calls don't authenticate again.

3

Uploads

Sends the envelope to the environment you chose.

4

Returns the track id

Resolves with trackId and receivedAt as soon as the SII confirms reception.

Errors#

CodeWhenWhat to do
SII_UNAVAILABLEThe SII could not be reached, timed out, or is downRetry later with backoff, using the same signed documents
SII_REJECTEDThe SII refused the upload, for example the authentication or the envelopeDon't retry as is: check the certificate, sender RUT and resolution

getStatus()#

Asks the SII what happened to an upload.

TypeScript
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' }]
TypeScript
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 - The id sendToSii() returned.
  • options.certificate, options.environment - The same ones you sent with.
  • options.issuerRut - The RUT of the company that issued the documents.

Like sendToSii(), it throws SII_UNAVAILABLE when the SII can't be reached.

Acceptance States#

StateMeaningWhat to do
receivedThe SII has the envelope and is still validating it.Ask again later
acceptedThe documents are validDeliver them to the customer
accepted_with_objectionsAccepted, but the SII noted objections (reparos). reason explains each one.The document is valid; fix the cause for future documents
rejectedThe SII rejected it. reason explains why.Fix the cause and issue the document again

state summarizes the whole envelope. When you send several documents at once, check documents for the outcome of each one.

Examples#

Send a Batch#

TypeScript
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!,
  },
})

Time Out Slow Uploads#

TypeScript
const { trackId } = await sendToSii(signed, {
  ...siiOptions,
  signal: AbortSignal.timeout(30_000),
})

Retry When the SII Is Unavailable#

TypeScript
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))
    }
  }
}

Wait for a Final State#

Validation usually takes a little while. Poll with a growing delay, and hand off to a background job if it's still received:

TypeScript
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
}

See Issue an Invoice for a complete flow that persists the track id and polls from a job.

  • signDte() - Produces the SignedDte documents you send
  • toXml() - Keep a copy of exactly what you sent
  • createDte() - Where every document starts