The certificate-authenticated SII portal: session, company data, folios and CAF requests, the purchase and sales register, the MIPYME backup and the activity verification; plus the certification sets and the certification runner. It runs on Node only, because fetch cannot present a client certificate.
TypeScript
import { createPortalClient, openPortalSession, queryFolioQuota } from 'dte-sdk/portal'
⚠️
What has met the real portal: in production, on 9 and 10 November 2026, the certificate login with the session reused between reads, for a company not enrolled as an issuer, and the register's reads (fetchRegisterSummary, listPeriodDocuments, fetchPurchaseDocument, listPurchaseTypes) with the rows of one received invoice; in earlier runs whose environment wasn't written down, login, logout, taxpayer data and the refusal pages, for a company not enrolled as an issuer, and the register's read-only requests for a company with no documents. The folio and CAF pages of an enrolled company have not been seen yet, because they need one, and neither have the register's writes or the MIPYME backup's downloads. The activity verification was read for a pending verification and, on 9 November, for a conditioned one pending accreditation; an approved one has not been seen yet, so its read stays unstable. The certification (sets, runner, exchange, upload of the samples) and the certification of receipts have not been run yet. All of it is tested against synthetic answers. See Status.
The groups below follow the guides: Portal, Register, Test sets, Runner, Exchange and samples and Receipts. The portal functions take a PortalClient first and a CallOverrides last; the certification steps take a CertificationDependencies and a CertificationState.
The portal reports a refusal as a DteError with code SII_PORTAL_REJECTED and details.rejection, one of the PortalRejection values. PORTAL_REJECTIONS and portalRejectionMessage give the Spanish text for the operator. The composite flows return refusals as data instead of throwing. Guide: Portal.
TypeScript
// What each rejection means and what to do about it, in Spanish, for the operator.const PORTAL_REJECTIONS: Readonly<Record<PortalRejection, string>>// The Spanish message of a rejection.function portalRejectionMessage(rejection: PortalRejection): string
Type
Description
AccountingStatus
Accounting status of a document in the register. Defined as 'registered' | 'pending' | 'notIncluded' | 'claimed'. Which ones each side can hold is in REGISTER_ACCOUNTING_STATUSES.
DocumentDirection
Which side of a document the taxpayer is on. Defined as 'issued' | 'received'.
PortalRejection
Why the SII refused a portal request.
RegisterOperation
Which book of the register. Defined as 'purchase' | 'sale'.
createPortalClient returns a frozen client; the portal operations are free functions that take it first and accept a trailing CallOverrides (signal, timeoutMs, retry). The portal runs on Node only, because fetch cannot present a client certificate: the default transport is node:https with the certificate and TLS verification on. The certificate must be enabled as a login method at sii.cl, or the login throws SII_PORTAL_CERT_NOT_ENABLED. Sessions open on demand; openPortalSession and closePortalSession do it explicitly. sessionCache and lock are ports for deployments with several replicas. Guide: Portal.
// Validates and completes the options into a frozen `PortalClient`.function createPortalClient(options: PortalClientOptions): PortalClient// Retry policy of the portal: 4 attempts at 2, 4 and 8 s, no jitter, repeating what// `isRetryablePortalError` accepts.const DEFAULT_PORTAL_RETRY_POLICY: RetryPolicy// True for what is worth repeating at the portal: transport failures, timeouts, HTTP 502/503/504,// and the TLS failures the SII produces intermittently with a client certificate (`EPROTO …// rsa_pss`), which are not a sign of a bad certificate.function isRetryablePortalError(error: unknown): boolean
Type
Description
PortalClient
The portal client: plain frozen data, every field resolved. Pass it to the portal functions.
PortalClientOptions
Options of createPortalClient.
Fields of PortalClientOptions
Field
Type
Description
environment
Environment
Target environment: selects maullin or palena for the CGI pages.
certificate
Certificate
Certificate presented at login; its holder is the portal user.
companyRut?
string
Company RUT used by every operation unless overridden per call.
transport?
HttpTransport
HTTP transport; Node https with the client certificate and a TLS 1.2 cap by default.
sessionCache?
TokenCache
Where the session lives; in memory by default. createDirectoryTokenCache({ dir }) from dte-sdk/node keeps it on disk, one owner-only file per certificate.
sessionTtlMs?
number
Session lifetime in the cache; 90 min by default, refreshed on each use.
lock?
PortalLock
Who may use the session now; a mutex in the process by default, which holds within one process only: processes that share a session on disk need a shared lock.
retry?
Partial<RetryPolicy> | false
Retry policy overrides, or false to disable retries.
timeoutMs?
number
Timeout per request, ms; 20 000 by default.
closePreviousSessions?
boolean
Close earlier sessions when the SII reports the limit and offers it; true by default.
logger?
Logger
Logger; silent by default.
capture?
HttpCapture
HTTP capture port; off by default.
now?
() => Date
Clock.
sleep?
SleepFn
Wait between retries and between steps.
randomId?
() => string
Source of the transaction ids of the RCV; crypto.randomUUID by default.
// Mutex per key inside one process.function createMemoryPortalLock(): PortalLock
Type
Description
PortalLock
Who may use a portal session now: run starts only when the lock is held and the lock is released when it settles, even if it fails. Defined as <T>(key: string, run: () => Promise<T>) => Promise<T>.
// Opens a session explicitly, reusing a cached one that is still alive, as the company page of the// client's environment (`ad_empresa1`) says. The other operations do not need this: they log in// on demand.function openPortalSession( portal: PortalClient, overrides?: CallOverrides,): Promise<PortalSessionInfo>// Closes the session to give its slot back, and always removes the cached session. A failed logout// is only logged: the SII expires the session on its own anyway.function closePortalSession(portal: PortalClient, overrides?: CallOverrides): Promise<void>
The resolution of the company (per environment), its taxpayer data, and the issuer profile that combines both. Guide: Portal.
TypeScript
// Reads the resolution of a company. It is per environment: certification and production answer// different dates and numbers for one RUT, and the wrong pair gets an envelope rejected with// "Error en Carátula".function fetchCompanyResolution( portal: PortalClient, input?: { readonly companyRut?: string; readonly environment?: Environment; }, overrides?: CallOverrides,): Promise<CompanyResolution>// Reads taxpayer data: name, address split in its parts, activities and branches.function fetchTaxpayerData( portal: PortalClient, input?: { readonly companyRut?: string; }, overrides?: CallOverrides,): Promise<TaxpayerData>// Reads the resolution and the taxpayer data in sequence and combines them. In parallel, one reply// overwrites the balancer cookie the other needs and `ad_empresa2` answers empty.function fetchIssuerProfile( portal: PortalClient, input?: { readonly companyRut?: string; readonly environment?: Environment; }, overrides?: CallOverrides,): Promise<IssuerProfile>
Type
Description
IssuerProfile
What a company needs to fill an Issuer and an envelope cover.
CompanyResolution
What ad_empresa2 says about a company in one environment.
TaxpayerData
What ce_consulta_muestra_e says about a taxpayer. It only answers on the certification host.
TaxpayerActivity
One economic activity.
TaxpayerBranch
One registered branch.
Fields of IssuerProfile
Field
Type
Description
rut
SiiRut
Company RUT.
businessName
string
Business name.
businessActivity
string
Line of business: the first activity, else the description.
Reads the state of each test set and book on the certification host. It only reads; declaring progress is declareProgress. Guide: Test sets.
TypeScript
// Reads the state of each test set and book, on the certification host. It only reads: declaring// progress is `declareProgress`.function queryCertificationSets( portal: PortalClient, input?: { readonly companyRut?: string; }, overrides?: CallOverrides,): Promise<CertificationSets>
Type
Description
CertificationSets
The certification state of a company.
CertificationSet
One test set or book of the certification, and its state.
List the document types the company can stamp, read the folio quota (this stamps nothing) and request a CAF. The SII may grant less than you ask for: read granted. The CAF XML holds a private key: treat it as a secret. Guide: Portal.
TypeScript
// Lists the document types the portal offers for stamping with this company. An error page is not// "no types": a page with no selector and no stated rejection throws.function listStampableTypes( portal: PortalClient, input?: { readonly companyRut?: string; }, overrides?: CallOverrides,): Promise<readonly StampableType[]>// Reads how many folios the SII authorizes for a type, stopping at the form that shows it: nothing// is stamped and the quota does not move. `MAX_AUTOR` and `FOLIOS_DISP` appear only while the SII// rations the type. The form is the one whose selector has the type chosen: the company's page, with// none chosen, is reloaded with it, and a last page that is not that form throws// `SII_PORTAL_SESSION_EXPIRED` or `SII_PORTAL_UNEXPECTED_PAGE` instead of reading as an unrationed type.function queryFolioQuota( portal: PortalClient, input: { readonly type: DocumentType; readonly companyRut?: string; }, overrides?: CallOverrides,): Promise<FolioQuota>// Requests a range of folios and downloads its CAF through the five portal steps. A rejection can// arrive at any step. With the effective maximum exceeded and no `minQuantity`, it asks once more// for one folio. When the SII answers the request with the request form again, nothing is sent a// second time: it throws `SII_PORTAL_REJECTED` with `stampingUncertain`, since the folios may have// been granted, and `listReobtainableRanges` says whether they were.function requestCaf( portal: PortalClient, input: CafRequestInput, overrides?: CallOverrides,): Promise<ObtainedCaf>
Type
Description
CafRequestInput
Input of requestCaf.
FolioQuota
The stamping quota of a document type.
ObtainedCaf
A CAF obtained from the portal. xml holds the CAF private key: store it as a secret.
QuotaFields
The quota of a form: both null when the SII is not rationing this type, because only then it publishes them.
StampableType
A document type the portal offers for stamping.
Fields of CafRequestInput
Field
Type
Description
type
DocumentType
Document type.
quantity
number
Folios wanted.
minQuantity?
number
Least acceptable: below it nothing is stamped, because a short range goes unused and lowers the next maximum.
companyRut?
string
Company RUT; the client's by default.
Fields of FolioQuota
Field
Type
Description
maxAuthorized
number | null
Most folios the SII authorizes now.
availableFolios
number | null
Folios stamped and unused.
unrestricted
boolean
The SII is not rationing this type.
blocked
boolean
The SII authorizes nothing: "NO SE AUTORIZA TIMBRAJE".
Fields of ObtainedCaf
Field
Type
Description
xml
string
The file as the SII served it.
caf
Caf
The file parsed.
granted
number
Folios it covers.
maxAuthorized
number | null
Most folios the SII authorized, or null when it was not rationing.
availableFolios
number | null
Stamped and unused folios, or null when it was not rationing.
recovered
boolean
It came back through "ya fue autorizado" or the re-download flow.
Annulling unused folios is irreversible and needs an explicit scope. List the unused ranges first. Guide: Portal.
TypeScript
// Lists the unused ranges of a document type, following the pages of the listing. It changes// nothing.function listFolioRanges( portal: PortalClient, input: { readonly type: DocumentType; readonly companyRut?: string; }, overrides?: CallOverrides,): Promise<FolioRanges>// Annuls unused folios: up to four passes over the listing, by range and folio by folio when the// part of the range was annulled or received before, stopping a pass after two real refusals in a// row. A single folio keeps the SII's answer. Once the SII has answered for some folios, a// `DteError` that ends the walk (an expired session, a block, the caller's abort, a later listing// refused or not understood) comes back in `failure`, with what was done until then; a range that// never got through (`transport`) is no answer, and before any answer the error is thrown. A range// answered folio by folio comes back in as few pieces as its answers allow, and a walk cut short at// one folio keeps the folios answered before it.function annulFolios( portal: PortalClient, input: AnnulFoliosInput, overrides?: CallOverrides,): Promise<AnnulmentResult>
Type
Description
AnnulFoliosInput
Input of annulFolios. One of range, withinDays or all is required: annulment cannot be undone and annulled folios count against the stamping quota for six months.
AnnulmentResult
What an annulment did, even when a later step cut it short.
FolioRanges
The unused ranges of a document type.
FolioSpan
Some folios and how many they are.
AnnulmentRejectionReason
Why folios were not annulled. alreadyAnnulled and received are what the SII said about them and are final; siiError, transport and unknown (an answer in no known words) are not, since the SII may have annulled them all the same. Defined as 'alreadyAnnulled' | 'received' | 'siiError' | 'transport' | 'unknown'.
UnusedFolioRange
A stamped range with unused folios, as the annulment page lists it. Annulled ranges stay on this list forever.
Fields of AnnulFoliosInput
Field
Type
Description
type
DocumentType
Document type.
range?
{ readonly from: number; readonly to: number }
Only these folios.
withinDays?
number
Only ranges stamped within these days; a range with no readable date is skipped.
all?
boolean
Every unused range, up to maxRanges.
reason?
string
Reason; "Folios no utilizados" by default.
maxRanges?
number
Most ranges tried in EACH pass, taken from the end of the listing; 50 by default. It is not a limit on the call: there are up to four passes, so one call can annul up to four times this many ranges (200 by default).
exclude?
readonly { readonly from: number; readonly to: number }[]
Folios never to touch, such as a CAF still in use.
knownAnnulled?
readonly string[]
knownAnnulled of the previous run: a listed range whose folios these keys cover, in one key or several, is not tried again.
companyRut?
string
Company RUT; the client's by default.
Fields of AnnulmentResult
Field
Type
Description
annulled
readonly FolioSpan[]
Folios annulled. Folios next to each other with the same answer are one span.
Folios not annulled, and why, folios next to each other with the same answer in one span. alreadyAnnulled and received are expected results, not refusals; unknown is an answer the SII gave in no known words, so those folios may be annulled or not.
totalAnnulled
number
Sum of annulled.
totalRejected
number
Sum of rejected.
knownAnnulled
readonly string[]
from-to keys that are final (annulled, alreadyAnnulled or received): persist it and pass it back, because the portal keeps listing them forever. A range answered folio by folio comes in as few keys as its answers allow, one for each run of folios with the same answer, so read the keys as spans of folios, not as the listing's ranges. Nothing the SII answered in unknown words goes here.
failure
FolioFlowFailure | null
What stopped the walk once the SII had answered for some folios, or null: a DteError of a later listing (listFolioRanges) or of a later range (annulFolios), a refusal included. Annulling cannot be undone, so what was done until then comes back: persist knownAnnulled whether failure is set or not. Null on a walk that finishes.
Download again the CAF of a range the SII already authorized. It costs no quota. Guide: Portal.
TypeScript
// Lists the authorized ranges the SII lets download again. Annulled ranges appear there unmarked,// so learning which are costs one request per range. The procedure is entered like the others, with// a login on demand and the representation screen. Only a listing gives a list, empty when it has// no ranges: a page that states a refusal throws `SII_PORTAL_REJECTED`, a login page// `SII_PORTAL_SESSION_EXPIRED` and any other page `SII_PORTAL_UNEXPECTED_PAGE`.function listReobtainableRanges( portal: PortalClient, input: { readonly type: DocumentType; readonly companyRut?: string; }, overrides?: CallOverrides,): Promise<readonly ReobtainableRange[]>// Downloads the CAF of an already authorized range. It costs no quota. The procedure is entered// first, as `listReobtainableRanges` enters it, with a login on demand, so a cached session that// expired since the listing logs in again instead of posting the range with it. A page that states// a refusal at the entry throws `SII_PORTAL_REJECTED` and any other page that is not the procedure// `SII_PORTAL_UNEXPECTED_PAGE`, before anything is posted; a login page at any step throws// `SII_PORTAL_SESSION_EXPIRED`, never the refusal of a step.function reobtainCaf( portal: PortalClient, input: { readonly type: DocumentType; readonly range: ReobtainableRange; }, overrides?: CallOverrides,): Promise<ObtainedCaf>
Type
Description
ReobtainableRange
An authorized range the SII lets download again. The list also holds ranges already issued, which the SII does not mark at all: re-using one gets each document rejected with DTE-3-101.
Entering the procedure makes reobtainCaf one GET more, of rf_reobtencion1_folios, than before 0.7.0. A caller that took reobtainDownloadMissing or reobtainCafMissing for an expired session now gets SII_PORTAL_SESSION_EXPIRED.
Composite flows built on the operations above. They return refusals as data and, once they hold something the caller must not lose (CAFs, or folios the SII annulled), any other DteError too, in failure. The original error goes first to the client's logger, as the warning sii portal flow stopped, keeping what it holds, with the error's details, flow, code and stoppedAt, and every text detail redacted. The warning leaves out what a page said (portalMessage, body) and the url it came from, which can name the company and its RUT; the thrown errors keep them. Guide: Portal.
TypeScript
// Requests one CAF that covers the whole quantity; below it nothing is stamped. With `allowAnnul`,// once the SII has answered the annulment, a `DteError` that cuts it short, or one of the request// asked once more after it, ends the flow with `rejection: null`, the first request's quota, the// failure in `failure` and what was annulled in `knownAnnulled`; a cut-short annulment is not// followed by another request. Before the annulment's first answer it throws.function requestCafExact( portal: PortalClient, input: RequestCafExactInput, overrides?: CallOverrides,): Promise<RequestCafExactResult>// Covers a quantity across several CAFs, for when `FOLIOS_DISP` is 0 and `MAX_AUTOR` is small: the// SII rations by history, there is nothing to annul or download again, and waiting does not move// it. A refusal comes back with its own kind and `portalMessage`, on the first trip or a later one;// after a grant, only one folio over the maximum (`quotaExceeded`) reads as `quotaCapReached`. Once// a CAF is in hand, a later trip that fails with a `DteError` other than// a refusal (a transport failure, a timeout, an expired session, a block, `CAF_INVALID`, the// caller's abort) ends the flow with the CAFs obtained, the last quota seen and the failure in// `failure`; with no CAF in hand it throws. `quantity` must be a whole number of at least 1, or it// throws `INVALID_OPTION` before anything goes out.function requestCafInBatches( portal: PortalClient, input: RequestCafInBatchesInput, overrides?: CallOverrides,): Promise<FolioFlowResult>// Covers a quantity from authorized ranges without spending quota, oldest folio first. It is what// lifts a stamping block, since the SII asks for folios to be issued. The listing logs in on demand,// and whatever fails while listing (a refusal, an expired session, a page that is not the listing)// reads as no ranges, with the failure in `reason`: it does not throw. A refused download is logged// and the walk moves on. Once a CAF is in hand, a download that fails with any other `DteError` (a// transport failure, a timeout, an expired session, a block, the caller's abort) ends the walk with// the CAFs downloaded, the failure's message in `reason` and the failure in `failure`; with no CAF// in hand it throws. A login page in answer to the range or to the file is an expired session, not// a refused download.function reobtainFolios( portal: PortalClient, input: ReobtainFoliosInput, overrides?: CallOverrides,): Promise<ReobtainResult>
Type
Description
FolioFlowFailure
The DteError that stopped a folio flow already holding something the caller must not lose: CAFs, or folios the SII has annulled. Only its code is kept, with the kind of a refusal, since its other details may carry what a page said; the logger gets the rest of them, never what a page said or its address.
FolioFlowResult
The outcome of a composite flow. Refusals come back as data, because the flow may already hold CAFs: those must reach the caller, and a CAF cannot travel in an error's details, which get logged. For the same reason, once a CAF is in hand, or folios were annulled, any other DteError comes back as data too, in failure.
ReobtainFoliosInput
Input of reobtainFolios.
ReobtainResult
What reobtainFolios obtained. What was downloaded comes back even when it falls short or a later download fails, so the caller asks only for the difference.
RequestCafExactInput
Input of requestCafExact.
RequestCafExactResult
The outcome of requestCafExact, plus the memory of annulled ranges. Its failure is set once the SII has answered its annulment and a later step fails, and knownAnnulled then keeps what was annulled.
The step that failed. Reading the quota or listing ranges changes nothing; a request may have been granted all the same, and listReobtainableRanges says whether it was; an annulment may have gone through, and the next one hears it from the SII as "already annulled".
rejection?
PortalRejection
The kind of refusal when code is SII_PORTAL_REJECTED, as a listing the SII refuses after an annulment; absent otherwise.
Fields of FolioFlowResult
Field
Type
Description
complete
boolean
The quantity asked for was covered.
cafs
readonly ObtainedCaf[]
Every CAF obtained, even when falling short.
granted
number
Folios covered.
maxAuthorized
number | null
Last MAX_AUTOR seen, or null.
availableFolios
number | null
Last FOLIOS_DISP seen, or null.
rejection
PortalRejection | null
Why it fell short, or null.
portalMessage
string | null
What the portal said, with its secrets redacted, or null.
failure
FolioFlowFailure | null
What stopped the flow while it held something the caller must not lose, or null; rejection is then null. requestCafInBatches sets it with CAFs in hand, when it was not a refusal; requestCafExact once the SII has answered its annulment, with what cut the annulment short or the request after it, and knownAnnulled keeps what was annulled.
Fields of ReobtainFoliosInput
Field
Type
Description
type
DocumentType
Document type.
quantity
number
Folios to cover.
isIssued?
(range: { readonly from: number; readonly to: number }) => boolean | Promise<boolean>
The caller's record of ranges already sent to the SII, which the portal does not mark.
isFolioFree?
(folio: number) => boolean | Promise<boolean>
Confirms a folio at the SII, typically with folioReceived.
The register runs on the portal session. The reads give typed fields (null when absent) and a raw copy of the row. The writes (changePurchaseType, moveVatToCommonUse, moveVatToRecoverable) change the real register on a production client. What the register does with each document code is data in the package: see Register document codes and statuses. Guide: Register.
TypeScript
// Changes the type of purchase of a document. In production this changes the real register.function changePurchaseType( portal: PortalClient, input: ChangePurchaseTypeInput, overrides?: CallOverrides,): Promise<void>// One purchase as the register holds it, including its current type of purchase.function fetchPurchaseDocument( portal: PortalClient, key: PurchaseDocumentKey, overrides?: CallOverrides,): Promise<PurchaseDocument | null>// The official totals of a period by document type and accounting status, including what the SII// aggregates, such as receipts. Response codes are not looked at, so a month the SII refuses to// show reads as an empty one.function fetchRegisterSummary( portal: PortalClient, input: RegisterSummaryInput, overrides?: CallOverrides,): Promise<RegisterSummary>// Every document of a period, with no XML: the summary per type, then one detail call per row, at// the same time. This is not the official register. Response codes are not looked at, so a month// the SII refuses to show reads as an empty one.function listPeriodDocuments( portal: PortalClient, input: ListPeriodDocumentsInput, overrides?: CallOverrides,): Promise<PeriodDocuments>// The types of purchase the SII lets a document have.function listPurchaseTypes( portal: PortalClient, overrides?: CallOverrides,): Promise<readonly PurchaseType[]>// Moves the VAT of a document from recoverable to common use. In production this changes the real// register.function moveVatToCommonUse( portal: PortalClient, input: MoveVatInput, overrides?: CallOverrides,): Promise<void>// Moves the VAT of a document from common use back to recoverable: the inverse of// `moveVatToCommonUse`, with the same rules. Moving it all back leaves `commonUseVat` at 0 and// `recoverableVat` with the total.function moveVatToRecoverable( portal: PortalClient, input: MoveVatInput, overrides?: CallOverrides,): Promise<void>
Type
Description
ChangePurchaseTypeInput
What changePurchaseType needs.
ListPeriodDocumentsInput
What listPeriodDocuments needs.
MoveVatInput
What the functions that move VAT need: the final amount of each bucket after the change, not a delta. An absent amount goes empty.
PurchaseDocumentKey
Which purchase of the register.
RegisterSummaryInput
What fetchRegisterSummary needs.
PeriodDocument
One document of a period: no time of day and no XML. The field names are not measured, as in PeriodSummaryRow.
PeriodDocuments
The documents of a period.
PeriodSummaryRow
One row of the summary of a period, per document type and section.
PurchaseDocument
A purchase as the register holds it. The field names are not measured, as in PeriodSummaryRow.
PurchaseType
A type of purchase the SII lets a document have. Measured.
RcvObject
An object of an RCV answer, as the SII sent it. Defined as Readonly<Record<string, unknown>>.
RegisterHeader
The header of the official register. The field names are not measured, as in PeriodSummaryRow. proportionalityFactor is a number from 0 to 1, read also from a text with spaces and a decimal comma (" 1,0000"); a value outside that range is null and stays in raw.
RegisterSummary
The official register of a period.
RegisterSummaryRow
One row of the official register. The field names are not measured, as in PeriodSummaryRow.
What the register does with each document code, and which accounting statuses each side can hold. They are data in the package, added in 0.2.0: nothing here calls the SII. Use them when you read the totals of fetchRegisterSummary: which codes subtract, which never reach the register, which the register lists document by document, and where the buyer withholds the VAT. Guide: Register.
TypeScript
import { REGISTER_ACCOUNTING_STATUSES, REGISTER_DOCUMENT_CODES, registerDocumentCode } from 'dte-sdk/portal'registerDocumentCode(61)?.sign // -1: a credit note subtracts from the totalsregisterDocumentCode(52)?.inRegister // false: dispatch guides never reach the registerregisterDocumentCode(71) // undefined: not one of the 49 codesREGISTER_DOCUMENT_CODES.length // 49REGISTER_ACCOUNTING_STATUSES.sale // ['registered']
TypeScript
// The 49 document codes of the purchase and sales register, sorted by code.const REGISTER_DOCUMENT_CODES: readonly RegisterDocumentCode[]// What the register does with a document code, or `undefined` when the code is not one of the 49.function registerDocumentCode(code: number): RegisterDocumentCode | undefined// The accounting statuses each side of the register can hold: all four for purchases, only// `registered` for sales, since no SII source describes other states of a sale.const REGISTER_ACCOUNTING_STATUSES: Readonly<Record<RegisterOperation, readonly AccountingStatus[]>>
Type
Description
RegisterDocumentCode
One document code of the register, with what the register does with it.
Fields of RegisterDocumentCode
Field
Type
Description
code
number
SII document code, the tax document type number.
name
string
Official SII label, in Spanish, as the SII's code tables write it.
operations
readonly RegisterOperation[]
Sides of the register where the code appears, purchase before sale; empty when the code is not in the register.
electronic
boolean
Issued as a DTE, in the SII XML format. Codes 47 and 48 are not DTEs.
inRegister
boolean
False when the code never reaches the register: the dispatch guides 50 and 52. Inferred.
sign
1 | -1
-1 when the code subtracts from the register's totals (credit notes and decreases), 1 otherwise. Inferred from the F29. The amounts of codes 40, 43 and 103 may arrive negative and carry their own sign.
perDocument
boolean
False when the register shows only a monthly summary line for the code, with no document by document detail.
buyerWithholdsVat
boolean
The buyer withholds the VAT (cambio de sujeto). Debit and credit notes tied to a purchase invoice may carry the withholding per document, not per code, so this flag does not cover them.
The buyer withholds the VAT (buyerWithholdsVat: true)
29, 45, 46
DTEs (electronic: true)
33, 34, 39, 41, 43, 46, 52, 56, 61, 110, 111, 112
The catalog follows the SII's public sources: the "Información Electrónica de Compras y Ventas" format v3.0 (the code tables of each side and their "solo en resumen" column), the register's upload formats for purchases, sales and the sales summary, its FAQ, Resolución Exenta SII N° 12 of 2011 (the buyer of a factura de inicio withholds the whole VAT) and the F29 instructions (credit notes subtract). What the SII does not state, the catalog infers, and its JSDoc says so: the dispatch guides 50 and 52 appear in no code table of the register, so they are marked as outside it; the sign of each code is the F29's, not one the register states; code 906 is summary only; and codes 500 and 501 come from the older book format. It has not been checked against a real register with documents in it yet.
The four accounting statuses: registered is a document in the register; pending, a purchase still missing the buyer's receipt acknowledgement; claimed, a purchase claimed within 8 days, which cannot move to another status; notIncluded, a purchase the taxpayer chose to leave out.
Downloads the XML of the issued or received documents of a date range from the MIPYME backup. Guide: Register.
TypeScript
// Downloads the XML of the issued or received documents of a date range from the MIPYME backup,// splitting the range until each piece fits the 20 documents the SII allows per download.function downloadMipymeBackup( portal: PortalClient, input: MipymeBackupInput, overrides?: CallOverrides,): Promise<MipymeBackup>
To issue electronic documents with VAT, the SII asks for more than being a VAT taxpayer: the company needs a positive on-site verification of its activities, or one in progress (the SII's requirements). Without it, a CAF request for a type that needs it is refused with activityVerificationPending. unstable_fetchActivityVerification reads that verification from the SII's "Consulta estado de verificación y acreditación", and listAccreditationDocuments the catalog of the documents that accredit an activity, from the same app. Both run on the same session as the rest of the portal and were added in 0.3.0. Both read production whatever the client's environment, because the app exists only there. Guide: Portal.
⚠️
unstable_ means the shape may change in any release, a patch included.unstable_fetchActivityVerification has been read against the real SII on 8 November 2026, for a company whose verification was pending, and on 9 November, for a conditioned verification pending accreditation. The SII's codes for an approved verification are not known yet, so nothing in the result says by itself whether the company may issue documents with VAT. Once an approved verification has been read, the function becomes fetchActivityVerification. Until then, pin the version and read the changelog before every upgrade, patches too. listAccreditationDocuments is not marked unstable.
TypeScript
import { listAccreditationDocuments, unstable_fetchActivityVerification } from 'dte-sdk/portal'const { requests, messages } = await unstable_fetchActivityVerification(portal)requests.length // 0 when the company never asked for the verificationrequests[0]?.status // 'PAC', described as 'PENDIENTE DE ACREDITACIÓN'requests[0]?.preliminaryResult // 'CONDICIONADA'requests[0]?.finalResult // null while there is nonerequests[0]?.requestedOn // 'YYYY-MM-DD'messages.filter((message) => message.blocking) // the messages the SII's own page stops atconst documents = await listAccreditationDocuments(portal)documents[0] // { category: 'general', code: 1, description: '…' }
TypeScript
// Unstable: its shape may change in any release, a patch included. The company's activity// verification, the SII's "Consulta estado de verificación y acreditación". It sends the company's// RUT, not the session's, and a request of another RUT throws instead of passing as the company's.// It reads production whatever the client's environment. Officials, comments and the address// never come out.function unstable_fetchActivityVerification( portal: PortalClient, input?: ActivityVerificationInput, overrides?: CallOverrides,): Promise<ActivityVerification>// The kinds of document the SII takes to accredit an activity, as the SII orders them: a general// list and a specific one, whose codes repeat. It reads production whatever the client's// environment.function listAccreditationDocuments( portal: PortalClient, overrides?: CallOverrides,): Promise<readonly AccreditationDocument[]>
Type
Description
ActivityVerificationInput
What unstable_fetchActivityVerification needs.
ActivityVerification
The verification of a company's activities. Officials, comments, the address and the procedure's internals are left out on purpose, and there is no raw. Unstable.
ActivityVerificationRequest
One request for the verification of the company's activities. Unstable.
ActivityVerificationMessage
A message the SII adds to the verification.
AccreditationDocument
A kind of document the SII takes to accredit an activity. The code repeats across categories: the pair is the key.
AccreditationDocumentCategory
Which list a document that accredits an activity belongs to. Defined as 'general' | 'specific'.
Fields of ActivityVerificationInput
Field
Type
Description
companyRut?
string
Company, when it is not the client's.
Fields of ActivityVerification
Field
Type
Description
requests
readonly ActivityVerificationRequest[]
The requests; empty when the company never asked for the verification.
messages
readonly ActivityVerificationMessage[]
The SII's messages.
Fields of ActivityVerificationRequest
Field
Type
Description
number
number | null
Number of the verification.
kind
string | null
Kind of verification, such as VIA.
reason
string | null
Why it was opened, as the SII words it.
preliminaryResult
string | null
Preliminary result, such as CONDICIONADA.
finalResult
string | null
Final result; null while there is none.
status
string | null
Status code, such as PAC.
statusDescription
string | null
What the status means, such as PENDIENTE DE ACREDITACIÓN.
requestedOn
string | null
Date of the request, YYYY-MM-DD.
accreditationDeadline
string | null
Last day to accredit the activity, YYYY-MM-DD; null when there is none.
procedureStatus
string | null
Status of the accreditation procedure, as the SII words it.
hasCertificate
boolean
True when the SII has issued the verification's certificate.
Fields of ActivityVerificationMessage
Field
Type
Description
text
string
The message.
blocking
boolean
True when the SII's own page stops at it.
Fields of AccreditationDocument
Field
Type
Description
category
AccreditationDocumentCategory | null
The category; null for one dte-sdk does not know.
code
number | null
Code within the category.
description
string | null
Name of the document.
What they throw:
An SII error code in the answer throws SII_PORTAL_REJECTED with rejection: 'activityVerificationRefused', and the SII's words in details.portalMessage when it said something.
A request whose RUT is not the company's throws SII_PORTAL_UNEXPECTED_PAGE with step: 'otherTaxpayer', and nothing of it is returned. The SII's own page shows the verification of whoever logged in; this function sends the company's RUT, and the SII answered a session of the company's legal representative.
An answer with no verification or no catalog in it throws SII_PORTAL_UNEXPECTED_PAGE. With no company on the call or the client, unstable_fetchActivityVerification throws MISSING_FIELD, and with an invalid one, INVALID_RUT. Session and transport codes are as elsewhere in the portal.
Like the reads of the register, each call to the SII's app is one request unless you opt in with retry, while the login and the visit to the app keep their retries. A read that meets an expired session or an unreadable page starts over once with a fresh session.
Local control of folios: which were reserved, sent and annulled. createFolioRegistry works over a store you provide; createMemoryFolioRegistry keeps it in memory, and createDirectoryFolioRegistry (from dte-sdk/node) keeps it in a JSON file. Guide: Portal.
TypeScript
// First 12 hex characters of the SHA-256 of a CAF file, to tell apart two files for one range.function cafFingerprint(xml: string): string// A registry over a store. Calls run one after another inside this process, each reading the// ledger fresh; several processes need a store or a registry of their own that takes care of it.function createFolioRegistry(store: FolioLedgerStore, now?: () => Date): FolioRegistry// A registry that lives in memory: for tests and short runs.function createMemoryFolioRegistry(now?: () => Date): FolioRegistry
Type
Description
FolioLedgerStore
Where a ledger is kept.
FolioRegistry
Local control of folios: which were reserved, sent and annulled. A service with its own database implements these functions with its own transactions; the rest build one with createFolioRegistry.
FolioEntry
One entry of the ledger.
FolioLedger
The whole registry as one JSON-friendly value.
FolioScope
The folios of one CAF for one company in one environment.
One per entry of the registry, that is per CAF file: its range, the environment of its scope and the cafFingerprint of the file it counts (null when its scope has none), and its folios used, sent and still unused. Two files of one range, or one range in both environments, are two entries, told apart by these two fields. A FolioRegistry of your own returns both in each range.
Fields of ReserveOptions
Field
Type
Description
lowestFree?
boolean
Hand out the lowest folio of the range that is neither used nor annulled, wherever the used ones lie: a folio given back, or left free below a folio marked sent, goes out again.
Everything that needs no portal: parse the SII test-set text, plan what each set issues, allocate folios, issue the documents and build the books. Nothing here sends anything; the runner does. Guide: Test sets.
// Kinds of set the SII test-set text can hold, by their English name.const TEST_SET_KINDS: { readonly basic: "basic" readonly exempt: "exempt" readonly guide: "guide" readonly purchase: "purchase" readonly export: "export" readonly settlement: "settlement" readonly salesBook: "salesBook" readonly purchaseBook: "purchaseBook" readonly exemptPurchaseBook: "exemptPurchaseBook" readonly guideBook: "guideBook" readonly other: "other"}// Names of the sets and books as the certification portal lists them (`pe_avance2`).const TEST_SET_PORTAL_NAMES: Readonly<Partial<Record<TestSetKind, string>>>// The reference document type every document of a test set carries on its first reference line.const TEST_SET_REFERENCE_TYPE = 'SET'// The counterparty written on every entry of the certification purchase books: the SII's own RUT// and a placeholder name. The SII accepts it, it exists as a taxpayer and it is nobody's personal// data.const CERTIFICATION_COUNTERPARTY: { readonly rut: "60803000-K"; readonly name: "Razon Social" }
// Parses the text of the SII test set: sets, their cases with items and references, the supplier// documents of the purchase-book sets and the proportionality factor.function parseTestSetText(text: string): readonly TestSet[]
// The cases each set issues, with the folios every document type needs, from the parsed sets. For// each kind the last set of the text wins.function planCertificationSets(sets: readonly TestSet[]): CertificationPlan
Type
Description
CertificationPlan
What the certification issues, per set kind; a kind the text lacks is absent. The sales and guide books have no plan: they come from the issued basic and guide sets.
// A folio source over one or several CAFs: one counter per CAF, the first CAF of the type with a// folio left wins, a folio is never given twice, and the CAF returned is the one whose range holds// the folio, so it stamps with its own key.function createFolioAllocator(cafs: readonly Caf[], options?: FolioAllocatorOptions): FolioSource
Type
Description
FolioSource
Where the next folio of a type comes from, with the CAF that stamps it. The in-memory allocator below is one implementation; the runner may implement it with the folio registry.
FolioAllocatorOptions
Options of createFolioAllocator.
Fields of FolioAllocatorOptions
Field
Type
Description
usedFolios?
readonly { readonly type: number; readonly folio: number }[]
Folios already used; the allocator starts after the highest used one of each CAF.
// Issues every document of a set plan and signs its envelope.function issueTestSet(plan: IssuableSetPlan, options: IssueSetOptions): Promise<IssuedSet>// `SetDTE/@ID` of every certification envelope.const TEST_SET_ENVELOPE_ID = 'DTE_SetDoc'
Type
Description
IssueSetOptions
What issuing a set needs.
IssuableSetPlan
The plans issueTestSet accepts. Defined as BasicSetPlan | ExemptSetPlan | GuideSetPlan | PurchaseSetPlan.
IssuedCase
One issued document of a set.
IssuedSet
An issued set: its documents in issue order and the signed envelope that carries them.
Fields of IssueSetOptions
Field
Type
Description
issuer
IssuerInput
The issuer, as for a document.
receiver
ReceiverInput
The customer every document names; purchase invoices and internal transfers name the issuer instead.
// Issues every case of the four set plans again with fresh folios, in the order basic, exempt,// guide and purchase, and signs one envelope with all of them.function issueSimulation( plan: CertificationPlan, options: IssueSetOptions,): Promise<IssuedSimulation>
Type
Description
IssuedSimulation
The simulation: every case of the four sets issued again, in one envelope.
// The sales book of the certification: only the basic set's invoices and notes, dated the 15th of// the period, with the customer as counterparty, every amount present (0 when absent) and the VAT// rate on every line.function createCertificationSalesBook( set: IssuedSet | SalesBookSource, input: CertificationSalesBookInput,): SignedPurchaseSalesBook// A purchase book of the certification from a purchase-book set: one line per supplier document// with the SII's placeholder counterparty, the VAT at 19 % of the affected amount, common-use VAT,// non-recoverable VAT for free deliveries, the withholding of a purchase invoice, the referenced// folio of a note from its observation, and, for the exempt taxpayers' book, non-recoverable VAT// on every affected line, the paper exempt invoice as type 32 and notes inheriting the amounts of// the document they reference.function createCertificationPurchaseBook( plan: PurchaseBookPlan, input: CertificationBookInput,): SignedPurchaseSalesBook// The guide book of the certification: only the guide set's guides, with their transfer reason and// issue date; by position the second guide carries `Operacion` 1 and the third is voided// (`Anulado` 2, total 0 and nothing else), unless `caseFlags` says otherwise; a sale carries the// customer, the net, the VAT rate and the VAT; every guide its total.function createCertificationGuideBook( set: IssuedSet | GuideBookSource, input: CertificationGuideBookInput,): SignedGuideBook
Type
Description
CertificationBookInput
What every certification book needs.
CertificationSalesBookInput
Options of createCertificationSalesBook.
CertificationGuideBookInput
Options of createCertificationGuideBook.
BookReceiver
The customer written on the sales and guide books.
GuideBookCaseFlag
How a guide enters the guide book. Defined as 'normal' | 'modified' | 'voided'.
BookCaseTotals
The totals of one issued document, as the books read them.
SalesBookCase
One document of the sales book: the issued set's case, or what a run kept of it.
GuideBookCase
One guide of the guide book: the issued set's case, or what a run kept of it.
SalesBookSource
A sales-book source that is not the issued set itself: its kind and cases, as a resumed run holds them.
GuideBookSource
A guide-book source that is not the issued set itself.
Fields of CertificationBookInput
Field
Type
Description
period
string
Tax period YYYY-MM; the runner chooses it against the portal history.
issuerRut
string
Company the book belongs to.
senderRut
string
Authorized sender, normally the certificate holder.
The portal operations of the certification (download the set, declare progress, read progress, advance the stage, book history, declaration of compliance), the store that keeps the state of a run, the runtime every step shares, and one function per step. The runner chains them. Guide: Runner.
// The sets in the order they are sent.const SET_KEYS: readonly SetKey[] = ['basic', 'guide', 'exempt', 'purchase']// The books in the order they are sent.const BOOK_KEYS: readonly BookKey[] = ['purchaseBook', 'salesBook', 'guideBook', 'exemptPurchaseBook']// The books every certification must get approved.const MANDATORY_BOOK_KEYS: readonly BookKey[] = ['purchaseBook', 'salesBook', 'guideBook']// The file name each book travels under in the upload, as the SII expects it.const BOOK_FILE_NAMES: Readonly<Record<BookKey, string>> = { salesBook: 'LibroCV.xml', purchaseBook: 'LibroCV.xml', exemptPurchaseBook: 'LibroCVExentos.xml', guideBook: 'LibroGuia.xml',}// The artefact name of each book.const BOOK_ARTEFACT_NAMES: Readonly<Record<BookKey, string>> = { salesBook: 'libro-ventas.xml', purchaseBook: 'libro-compras.xml', exemptPurchaseBook: 'libro-compras-exentos.xml', guideBook: 'libro-guias.xml',}// The artefact name of each set envelope.const SET_ARTEFACT_NAMES: Readonly<Record<SetKey, string>>// The optional sets ticked when downloading the test set: guides (03), exempt invoices (06), the// sales (07), purchase (08) and guide (09) books, the purchase book for exempt taxpayers (15) and// the purchase set (72).const DEFAULT_OPTIONAL_SETS: readonly string[] = ['SET03', 'SET06', 'SET07', 'SET08', 'SET09', 'SET15', 'SET72']// The stages of a certification, in order, as the runner keeps them.const CERTIFICATION_STAGES: readonly [ "testSets", "books", "simulation", "exchange", "printedSamples", "compliance", "done"]// The words the portal uses for a stage (`pe_avance6`, "paso <b>…</b>"), from the latest stage// down. Any wording past the exchange lands in `printedSamples`: the compliance declaration tells// whether the samples are approved.const PORTAL_STAGE_WORDS: readonly { readonly stage: CertificationStage; readonly words: readonly string[] }[]// The names of the progress events the steps emit.const CERTIFICATION_STEPS: readonly [ "SETS_DOWNLOADING", "SETS_LOADED", "SETS_REGENERATED", "CAF_REQUESTING", "CAF_OK", "SET_START", "SET_OK", "SET_ERROR", "SETS_DECLARING", "SETS_DECLARED", "POLLING", "SETS_APPROVED", "SETS_REJECTED", "BOOKS_START", "BOOK_SKIPPED", "BOOK_SENDING", "BOOK_OK", "BOOK_ERROR", "BOOK_PERIOD_RETRY", "BOOKS_DECLARING", "BOOKS_DONE", "ADVANCE_WAITING", "ADVANCE_DONE", "SIM_START", "SIM_SENDING", "SIM_OK", "SIM_DECLARING", "SIM_DONE", "INTERCAMBIO_START", "INTERCAMBIO_DESCARGADO", "INTERCAMBIO_DONE", "MUESTRAS_UPLOADING", "MUESTRAS_DONE", "CERT_DONE", "CERT_ERROR"]
Type
Description
SetKey
The four sets the certification issues. Defined as 'basic' | 'exempt' | 'guide' | 'purchase'.
BookKey
The books of the certification. Defined as 'salesBook' | 'purchaseBook' | 'exemptPurchaseBook' | 'guideBook'.
DeclarationKey
Every row the declaration form (pe_avance2) can hold, by key. Defined as SetKey | BookKey | 'simulation' | 'export1' | 'export2' | 'settlement'.
CertificationStage
Union of the stages. Defined as (typeof CERTIFICATION_STAGES)[number].
CertificationStep
Union of the progress event names. Defined as (typeof CERTIFICATION_STEPS)[number].
// Downloads the test set from `pe_generar`. Without a session in the cache the progress page is// read first, which logs in and lets the SII refresh the application; whatever that read answers,// the download goes on.function downloadTestSet( portal: PortalClient, input?: DownloadTestSetInput, overrides?: CallOverrides,): Promise<DownloadedTestSet>// Declares the track id and date of envelopes on `pe_avance2`, posted to `pe_avance3`. The form is// read for its hidden fields and for the index of each row's field, found by the row's label (the// indexes move as sets are approved).function declareProgress( portal: PortalClient, input: DeclareProgressInput, overrides?: CallOverrides,): Promise<DeclarationResult>// Reads the progress page: the entry sequence, `pe_avance5`, then `pe_avance6` with the company.// No page on the way is searched for a refusal, and a page that names no stage and no state is// still an answer.function readProgress( portal: PortalClient, input?: { readonly companyRut?: string; }, overrides?: CallOverrides,): Promise<ProgressReport>// Asks the portal to move the application to its next stage: `pe_avance4` with `TOTREG` and `PASO`// as `pe_avance2` holds them (`PASO` changes with the stage; a fixed value makes the SII answer// "ya se encuentra en el paso"), with `pe_avance2` as referer.function advanceStage( portal: PortalClient, input?: { readonly companyRut?: string; }, overrides?: CallOverrides,): Promise<AdvanceResult>// Lists the books the SII holds for a year (`QEstLibro`, after `DTEauth?7` binds the session to// that CGI). Every period listed is occupied for a new total submission.function listBookHistory( portal: PortalClient, input: { readonly year: number; readonly companyRut?: string; }, overrides?: CallOverrides,): Promise<BookHistory>// The declaration of compliance: `pe_avance7`, `pe_avance8` with the company, once more with every// input of the page when the portal asks to continue (`OK_MSG`), then the `pe_avance9` form with// every input of the page, `Salir` apart, every `OPCn` at `S` and `CONFIRMAR`, both posts with// `pe_avance8` as referer.function declareCompliance( portal: PortalClient, input?: { readonly companyRut?: string; }, overrides?: CallOverrides,): Promise<ComplianceResult>
Type
Description
DownloadTestSetInput
Input of downloadTestSet.
DownloadedTestSet
What downloadTestSet read. Downloading generates the set: the SII assigns the cases anew, so anything sent for an earlier set is void.
DeclarationEntry
One envelope to declare: its track id and the date it was sent, YYYY-MM-DD in Chile.
DeclarationEntries
The entries of one declaration, by row key. Defined as Readonly<Partial<Record<DeclarationKey, DeclarationEntry>>>.
DeclareProgressInput
Input of declareProgress.
DeclarationOutcome
How a declaration ended, in a word. Defined as | 'accepted' | 'inReview' | 'contentErrors' | 'allRejected' | 'notSaved' | 'inconsistent' | 'declined' | 'failed'.
DeclarationResult
What declareProgress did and what the portal answered, with the facts the declaration loop decides on.
ProgressReport
The progress of the application as pe_avance6 shows it.
AdvanceResult
What advanceStage got. Defined as AdvanceAnswer.
BookHistory
What listBookHistory read for one year.
ComplianceResult
What declareCompliance did.
SetGenerationState
One row of the set table of pe_generar1: a set and whether the company obtained it.
OptionalSetOption
One optional set the page offers as a checkbox.
SetGenerationPage
What pe_generar1 shows before a set is generated.
DeclarationForm
The pe_avance2 form as the declaration reads it: only what a quoted attribute gives.
DeclarationAnswer
What a pe_avance3 answer says, read on the page as it came.
DeclarationVerification
What the re-read form says of the rows just declared.
AdvanceAnswer
What pe_avance4 answered.
ItemState
The state of one set or book on the progress page. Defined as | 'approved' | 'inReview' | 'rejected' | 'objections' | 'pending' | 'annulled' | 'inconsistent' | 'unknown'.
ProgressPage
The progress page (pe_avance6) read.
BookHistoryEntry
One book the SII holds, as QEstLibro lists it.
ComplianceForm
The pe_avance9 form, ready to post: its action and its fields.
Fields of DownloadTestSetInput
Field
Type
Description
companyRut?
string
Company RUT; the client's by default.
optionalSets?
readonly string[]
Optional sets to tick, SETnn; DEFAULT_OPTIONAL_SETS by default. Only those the page offers are sent.
download?
boolean
False to read the state table only, without generating a set.
previousAttentionNumber?
string
The attention number of the set in hand, to tell a regenerated set.
// A fresh state for a company.function createCertificationState(companyRut: string, now?: Date): CertificationState// A store in memory: for tests and short runs.function createMemoryCertificationStore(): CertificationStore// Throws unless the name is a relative path of safe segments: no empty segment, no `.`, no `..`,// no absolute path, nothing outside `[A-Za-z0-9._-]`.function assertArtefactName(name: string): void// A store in a directory: `state.json` written atomically (temp file and rename), the artefacts as// files, a `/` in a name as a sub-directory.function createDirectoryCertificationStore( options: DirectoryCertificationStoreOptions,): CertificationStore
Type
Description
CertificationState
The whole state of a certification run: what was downloaded, obtained, sent, declared and approved. A plain JSON value the store keeps between runs; the runner resumes from it.
CertificationStore
Where the state and the artefacts of a run live. The names are relative paths with / as separator; a service may back this with its own storage.
SentEnvelope
An envelope sent to the SII: its track id, the Chile date it was sent (what the declaration takes), the instant.
SentCase
One case of a sent set.
SentSet
A set sent, with its cases.
SentBook
A book sent: its period, its submission kind, and whether the portal approved it.
BooksState
What the books phase keeps.
AccumulatedTotals
The period totals accumulated per period and operation, for adjustment submissions. Defined as Readonly< Record<string, { readonly purchase?: readonly BookTotals[]; readonly sale?: readonly BookTotals[] }> >.
EnvelopeDiagnosis
What the SOAP status of an envelope said, kept for diagnosis.
DirectoryCertificationStoreOptions
Options of createDirectoryCertificationStore.
Fields of CertificationStore
Field
Type
Description
load
() => Promise<CertificationState | null>
The stored state, or null.
save
(state: CertificationState) => Promise<void>
Replaces the stored state.
writeArtefact
(name: string, content: string) => Promise<void>
Writes an artefact, replacing it.
readArtefact
(name: string) => Promise<string | null>
Reads an artefact, or null.
listArtefacts
() => Promise<readonly string[]>
Every artefact name, sorted.
Fields of DirectoryCertificationStoreOptions
Field
Type
Description
dir
string
The directory of state.json and the artefacts; created on first use. It holds CAF private keys: keep it out of version control.
// What the run fills in for an issuer that leaves it out: the line of business, the activity code,// the commune and the city. The RUT, the name and the address have no default.const DEFAULT_CERTIFICATION_ISSUER: Readonly<{ businessActivity: "ACTIVIDADES DE PROGRAMACION INFORMATICA"; activityCode: 620200...// The test receiver the run uses when none is given.const DEFAULT_CERTIFICATION_RECEIVER: ReceiverInput
Type
Description
CertificationDependencies
What every step needs: the clients, the store, the registry, the company and the clock.
CertificationIssuerInput
The issuer as the run takes it: the line of business and the commune may be left out.
CertificationProgressEvent
The progress events the steps emit, with their step names.
PollingLabel
What a POLLING event waits for. Defined as 'sets' | 'declaration' | 'books' | 'simulation'.
StepResult<Outcome extends string>
What a step returns: the state it saved, how it ended, and a word or sentence on why.
Fields of CertificationDependencies
Field
Type
Description
portal
PortalClient
The portal client on the certification environment.
sii
SiiClient
The SII client on the certification environment.
store
CertificationStore
Where the state and the artefacts live.
registry
FolioRegistry
The folio registry.
issuer
CertificationIssuerInput
The company that certifies; what it leaves out takes the defaults of DEFAULT_CERTIFICATION_ISSUER.
receiver?
Partial<ReceiverInput>
The receiver of the documents of the run; the test receiver of DEFAULT_CERTIFICATION_RECEIVER by default, field by field.
// Downloads the test set, parses it, plans the sets and keeps the text and the plan as artefacts.// Downloading generates the set anew at the SII, so a run that already had a plan starts over:// everything sent is void.function obtainTestSet( deps: CertificationDependencies, state: CertificationState, options?: { readonly optionalSets?: readonly string[]; },): Promise<StepResult<"loaded" | "regenerated">>// Sends one test set: issues it with the folios of the state's CAFs through the registry, keeps// the envelope and every document as artefacts, uploads it, marks the folios sent whatever// happened, and records the track id and the Chile date of the send.function sendTestSet( deps: CertificationDependencies, state: CertificationState, options: { readonly kind: SetKey; },): Promise<StepResult<"sent">>// Declares the sets sent so far with today's date, with the declaration loop; the outcome and any// diagnosis go to the state.function declareTestSets( deps: CertificationDependencies, state: CertificationState,): Promise<DeclarationStepResult>// Waits for the sent sets to be approved: 5 attempts 10 s apart, sleeping first, reading the// progress page. A read that fails only uses up its attempt.function waitForTestSetsApproval( deps: CertificationDependencies, state: CertificationState,): Promise<StepResult<"approved" | "rejected" | "timedOut">>// Asks the portal for the next stage after the books: the progress page is read, up to 30 times 10// s apart while it cannot be read; on the first page that reads the advance is asked for at once,// whatever the page says of the books (the portal decides); then the page is read again for the// stage, and the state's stage moves to the portal's when that is later.function advanceToNextStage( deps: CertificationDependencies, state: CertificationState,): Promise<StepResult<"advanced" | "unchanged" | "failed" | "timedOut">>// Sends the simulation: fresh CAFs for one folio per case (never the sets' CAFs), every case of// the four sets issued again in one envelope, the envelope and the documents kept as artefacts,// the upload, the folios marked sent whatever happened, and the track id with the Chile date of// the send.function sendSimulation( deps: CertificationDependencies, state: CertificationState,): Promise<StepResult<"sent">>// Declares the simulation, unless the progress page names the exchange as the step the application// is at: a later step is declared like any other, and so is a page that cannot be read.function declareSimulation( deps: CertificationDependencies, state: CertificationState,): Promise<DeclarationStepResult<DeclarationOutcome | "skipped">>// Waits for the simulation: 30 polls 10 s apart of the progress page, polling first. A read that// fails only uses up its attempt.function waitForSimulationApproval( deps: CertificationDependencies, state: CertificationState,): Promise<StepResult<"done" | "confirmed" | "rejected" | "timedOut">>// The end of the certification: one more request to advance the stage, then the declaration of// compliance.function declareComplianceFinal( deps: CertificationDependencies, state: CertificationState,): Promise<StepResult<"declared" | "blocked">>
// Makes sure the run holds the folios each type needs. The CAFs in hand first: an expired one is// skipped, folios of this run the SII never received are given back, and folios the SII already// received are marked used so they are skipped. Every CAF obtained is saved in the state at once.// Still short it throws `FOLIO_OUT_OF_RANGE` or, when the batches stopped on a failure and not on// the SII's answer, that failure's code. A re-obtaining or an annulment cut short by a failure ends// the step with that failure's code too, once what it brought and was kept, or what it annulled, is// in the state. Only a rationing refusal leads to annulling: a later batch refused for the company,// the option or the person keeps its kind, and a block on the person is first lifted by re-obtaining.function prepareFolios( deps: CertificationDependencies, state: CertificationState, options?: PrepareFoliosOptions,): Promise<PrepareFoliosResult>// The folios each type needs for the sets not yet sent: the sum of each set plan's `folios`, never// more, because unused authorized folios make the SII ration the next request.function setFolioNeeds( plan: CertificationPlan, sent: readonly string[],): Readonly<Record<number, number>>// The folios the simulation needs: one per case, by type.function simulationFolioNeeds(plan: CertificationPlan): Readonly<Record<number, number>>
Type
Description
PrepareFoliosOptions
Options of prepareFolios.
PrepareFoliosResult
What prepareFolios returns: the state, and the CAFs that cover the needs.
Fields of PrepareFoliosOptions
Field
Type
Description
needs?
Readonly<Record<number, number>>
Folios needed per type; the sets not yet sent by default.
fresh?
boolean
Ignore the CAFs in hand and request new ones (the simulation never reuses the sets' CAFs).
Fields of PrepareFoliosResult
Field
Type
Description
state
CertificationState
outcome
Outcome
detail?
string
cafs
readonly string[]
The CAF files to issue with: the ones in hand plus the new ones, or only the new ones with fresh; ranges obtained again that were kept take the place of the ones in hand of their type.
// The books phase.function runBooks( deps: CertificationDependencies, state: CertificationState,): Promise<StepResult<BooksOutcome>>// The month before a `YYYY-MM` period.function previousPeriod(period: string): string// The first period at or below `period` the SII does not hold, stepping down month by month, at// most 400 times.function nextFreePeriod(period: string, occupied: ReadonlySet<string>): string
Type
Description
BooksOutcome
How the books phase ended: every wanted book approved; a mandatory book never sent; a declaration the portal did not take or books the SII refused; the approval wait exhausted. Defined as 'approved' | 'incomplete' | 'rejected' | 'timedOut'.
The exchange and the printed samples are answered on two portals that speak GWT-RPC. This group holds the GWT helpers, the operations of each portal, the exchange answers, and the two steps the runner uses. Guide: Exchange and samples.
// The exchange portal (`pfeInternet`): the certification's exchange set is downloaded there and// its answers uploaded.const EXCHANGE_PORTAL: GwtPortal// The printed samples portal (`pdfdteInternet`), the SII's automatic validator of the printed// documents.const SAMPLES_PORTAL: GwtPortal// The file names of the exchange answers, as the portal's uploads name them: the reception// response, the receipts and the commercial approval.const EXCHANGE_ANSWER_FILES: Readonly<Record<ExchangeAnswerKey, string>> = { reception: 'respuesta-recepcion-envio.xml', receipts: 'envio-recibos.xml', approval: 'respuesta-aprobacion-comercial.xml',}// The exchange answers in upload order.const EXCHANGE_ANSWER_KEYS: readonly ExchangeAnswerKey[] = ['reception', 'receipts', 'approval']
Type
Description
GwtPortal
A GWT portal of the SII: its module base, its RPC service path and interface, its module name and the hash pair known to work (captured in June 2026; the SII changes both when it redeploys the portal).
ExchangeAnswerKey
The keys of the three exchange answers. Defined as 'reception' | 'receipts' | 'approval'.
// The request body of a call: `7|0|N|` + the string table + the body, every item followed by `|`.function gwtBody(call: GwtCall): string// Reads an answer: `//OK`, the string table, the message, the Long tokens.function gwtAnswer(body: string): GwtAnswer// A number in the GWT base-64 alphabet, most significant digit first (`264872` is `BAqo`).function encodeGwtLong(value: number): string// The number a GWT base-64 token holds, or null when a character is not in the alphabet.function decodeGwtLong(token: string): number | null// The hashes of a GWT portal: the caller's pair when given; else the module's `nocache.js` is read// (the 32-hex strings delimited by `=`, `'` or `,`): the known pair stands when its permutation is// listed, else the first one listed is the permutation and its `cache.html` gives the policy, the// first quoted 32-hex string that differs from it; any failure, empty page or missing candidate// keeps the known pair.function discoverGwtHashes(context: PortalContext, input: GwtDiscoveryInput): Promise<GwtHashes>
Type
Description
GwtCall
One GWT-RPC call: where it goes and what it carries.
GwtParameter
One parameter of a GWT-RPC call, as the SII's portals serialize it: a string (interned in the table, 0 when null, or in a slot of its own when distinct), a boxed java.lang.Integer, a boxed java.lang.Long (a number, or a token already in the GWT base-64 alphabet), a primitive boolean (Z), null (a String unless it names its declared type), or an object with its fields in serialization order.
GwtAnswer
A GWT-RPC answer, read.
GwtHashes
The two hashes a GWT portal requires on every call.
GwtDiscoveryInput
What discoverGwtHashes needs: the module, the pair known to work, and a pair from the caller that wins.
GwtStage
A stage of work on one GWT portal: one authenticated entry, one warm-up and one pair of hashes that every call of the stage shares. Its cookies live only as long as the stage.
Fields of GwtDiscoveryInput
Field
Type
Description
moduleBase
string
The module base URL, with its trailing slash.
moduleName
string
The module name (<name>.nocache.js).
known
GwtHashes
The pair known to work.
override?
GwtHashes
A pair the caller knows better; nothing is fetched then.
// Downloads the exchange set from the exchange portal: the warm-up, then `downloadFile` with the// company in the query and an empty multipart body. The download does not change the application.function downloadExchangeSet( portal: PortalClient, input?: ExchangeCompanyInput, overrides?: CallOverrides,): Promise<ExchangeSetDownload>// Validates the user on the exchange portal: the warm-up, then `validarUsuario` with the company// and the certificate holder over the known hashes. The answer says whether the company stands in// the exchange stage; `//OK` is not required.function validateExchangeUser( portal: PortalClient, input?: ExchangeGwtInput, overrides?: CallOverrides,): Promise<ExchangeUserValidation>// Uploads the three exchange answers, in the portal's order: the reception response to// `uploadFile1`, the receipts to `uploadFile2`, the commercial approval to `uploadFile3`, each a// single `uploadFormElement` part.function uploadExchangeAnswers( portal: PortalClient, input: UploadExchangeAnswersInput, overrides?: CallOverrides,): Promise<ExchangeUploadResult>// Confirms the exchange on the portal: `validarSetContriPostSeguimiento` with the company (its// answer is kept, not judged), then `updatePostulacionSeguimiento` for the follow-up ids 40, 41// and 43, one per uploaded answer, each of which must answer `//OK`.function confirmExchange( portal: PortalClient, input?: ExchangeGwtInput, overrides?: CallOverrides,): Promise<ExchangeConfirmation>// Runs `run` in one stage of the exchange portal: the session made sure of, one warm-up, and every// call that is given the stage sent once over it. The upload, the user validation and the// confirmation share one stage.function withExchangeStage<T>( portal: PortalClient, operation: string, overrides: CallOverrides | undefined, run: (stage: GwtStage) => Promise<T>, sessionChecked?: boolean,): Promise<T>
Type
Description
ExchangeCompanyInput
Input of the exchange operations that only name the company.
ExchangeGwtInput
Input of the exchange operations that call the portal's service.
ExchangeSetDownload
What downloadExchangeSet read.
ExchangeUserValidation
What validateExchangeUser read: the state and the raw answer, with the hashes used, for the next calls.
UploadExchangeAnswersInput
Input of uploadExchangeAnswers: the three answers as XML, signed.
ExchangeUploadAnswer
What one upload page answered.
ExchangeUploadResult
What uploadExchangeAnswers did.
ExchangeConfirmationAnswer
What one follow-up confirmation answered.
ExchangeConfirmation
What confirmExchange did.
ExchangeUserState
What the exchange portal said when the user was validated.
Fields of ExchangeCompanyInput
Field
Type
Description
companyRut?
string
Company RUT; the client's by default.
stage?
GwtStage
The stage to run in, from withExchangeStage; the call opens a stage of its own without one.
Fields of ExchangeGwtInput
Field
Type
Description
companyRut?
string
Company RUT; the client's by default.
stage?
GwtStage
The stage to run in, from withExchangeStage; the call opens a stage of its own without one.
gwt?
GwtHashes
The portal's hashes, when the caller knows better than the pair known to work, which is the default; they are never looked up.
Fields of UploadExchangeAnswersInput
Field
Type
Description
companyRut?
string
Company RUT; the client's by default.
stage?
GwtStage
The stage to run in, from withExchangeStage; the call opens a stage of its own without one.
reception
string
The reception response (respuesta-recepcion-envio.xml).
receipts
string
The receipts (envio-recibos.xml).
approval
string
The commercial approval (respuesta-aprobacion-comercial.xml).
// Reads the company's printed samples review: `leeImpreso` with the company RUT. The portal// answers HTTP 200 with a state, or with a sentence when the application is not in the printed// samples stage (before it, and after it too).function readSamplesReview( portal: PortalClient, input?: ReadSamplesReviewInput, overrides?: CallOverrides,): Promise<SamplesReview>// Creates a printed samples review: `creaLista` with the company as sender and provider. The// portal only creates one when the current review is `RECHAZADO` or `APROBADO`, or there is none;// a review in `INGRESO` is resumed instead.function createSamplesReview( portal: PortalClient, input?: SamplesCompanyInput, overrides?: CallOverrides,): Promise<SamplesReviewCreated>// Uploads one PDF to a review: `POST upload` with the parts `Filedata` (the file), `id` (the// review id in decimal) and `ambiente` (`false`), the referer the permutation's `cache.html`. HTTP// 200 is success.function uploadSample( portal: PortalClient, input: UploadSampleInput, overrides?: CallOverrides,): Promise<SampleUploaded>// Submits a review to the SII: `solicitaRevisionSII` with the review token. The answer is// `//OK[0,[],0,7]` whether the SII accepts or rejects the samples: the state is read again// afterwards.function submitSamplesReview( portal: PortalClient, input: SamplesReviewInput, overrides?: CallOverrides,): Promise<{ readonly body: string; }>// Reads how the SII filed each PDF of a rejected review: `muestraMail` with the review token. A// failure is logged and gives an empty detail: the rejection stands without it.function readSamplesDetail( portal: PortalClient, input: SamplesReviewInput, overrides?: CallOverrides,): Promise<SamplesDetail>// Runs `run` in one stage of the samples portal: the session made sure of, one warm-up, the hashes// looked up once, and every call that is given the stage sent once over it.function withSamplesStage<T>( portal: PortalClient, operation: string, overrides: CallOverrides | undefined, run: (stage: GwtStage) => Promise<T>,): Promise<T>
Type
Description
SamplesCompanyInput
Input of the samples operations that name the company.
ReadSamplesReviewInput
Input of readSamplesReview.
SamplesReviewInput
Input of the samples operations that name a review by its token.
SamplesReview
What readSamplesReview read.
SamplesReviewCreated
What createSamplesReview did.
UploadSampleInput
Input of uploadSample.
SampleUploaded
What uploadSample did.
SamplesDetail
What readSamplesDetail read.
ReviewState
The states a samples review can be in, as the portal writes them. Defined as 'APROBADO' | 'POR REVISAR' | 'EN REVISION' | 'RECHAZADO' | 'INGRESO' | 'ENVIADO AL SII'.
SampleDetail
One row of the rejection detail: how the SII filed one PDF.
Fields of SamplesCompanyInput
Field
Type
Description
companyRut?
string
Company RUT; the client's by default.
gwt?
GwtHashes
The portal's hashes, when the caller knows them; discovered otherwise.
stage?
GwtStage
The stage to run in, from withSamplesStage; the call opens a stage of its own without one.
Fields of ReadSamplesReviewInput
Field
Type
Description
companyRut?
string
Company RUT; the client's by default.
gwt?
GwtHashes
The portal's hashes, when the caller knows them; discovered otherwise.
stage?
GwtStage
The stage to run in, from withSamplesStage; the call opens a stage of its own without one.
anyStatus?
boolean
True to read the answer whatever its HTTP status; by default any status but 200 is unexpected.
// Builds and signs the three answers to an exchange set, as the certification expects them: the// reception response (the envelope received, every document received when its receiver is the// company, else "error en RUT receptor"), the receipts of Ley 19.983 (one per document, signed by// the certificate holder) and the commercial approval (accepted when the receiver is the company,// else rejected with `CodRchDsc` -1).function createExchangeAnswers(setXml: string, input: CreateExchangeAnswersInput): ExchangeAnswers// Reads the exchange set loosely: the XML is not checked for well-formedness and its tags are read// by their full name, so a prefixed envelope is no envelope; the root is `EnvioDTE`, `EnvioDTEB`,// `EnvioDTETraslado` or `EnvioBOLETA`; the set id (the `ID` attribute, else an `ID` child, else// `SetDTE`), the cover's RUTs and, per document, its type (`TipoDTE` or `TpoDoc`), folio, issue// date, issuer and receiver (the cover's when the document names none) and total.function parseExchangeSet(setXml: string): ExchangeSet
Type
Description
ExchangeDocument
One document of the exchange set, as the answers describe it.
ExchangeSet
The exchange set the SII sends: its id, its cover and its documents.
ExchangeContact
The contact the answers name, every field optional.
CreateExchangeAnswersInput
Input of createExchangeAnswers.
ExchangeAnswer
One answer, ready to upload.
ExchangeAnswers
The three answers of the exchange and the set they answer.
ExchangeState
The exchange stage: the set answered and how far the answers got.
SamplesState
The printed samples stage: the review and what was uploaded to it.
Fields of CreateExchangeAnswersInput
Field
Type
Description
companyRut
string
The company that answers: the receiver the SII expects on every document.
// The exchange stage: the set (given, kept from an earlier run, or downloaded), the three answers// generated and kept as artefacts, the user validated on the portal, the answers uploaded and the// exchange confirmed, which moves the application to the printed samples.function runExchange( deps: CertificationDependencies, state: CertificationState, input?: RunExchangeInput,): Promise<StepResult<ExchangeOutcome>>// The artefact that holds the exchange set; the caller fills it by hand when the download fails.const EXCHANGE_SET_ARTEFACT: "intercambio/set-intercambio.xml"// The printed samples stage: the review read (a block or a review already sent end here; none yet// is created), resumed when it stands in `INGRESO` with a readable id or created otherwise, every// PDF uploaded in order (each name saved as it goes), the review submitted, and its state read// again (a failed reading is warned about and leaves the state unknown): `RECHAZADO` brings the// detail and its summary.function uploadPrintedSamples( deps: CertificationDependencies, state: CertificationState, input: UploadPrintedSamplesInput,): Promise<StepResult<SamplesOutcome>>
Type
Description
RunExchangeInput
Input of runExchange.
ExchangeOutcome
How runExchange ended: done with the answers uploaded and confirmed; alreadyDone when the state or the portal says the exchange was completed; setUnavailable when the set could not be downloaded (the artefact named in the detail must be filled by hand); notInExchange when the portal says the company is not in the stage. Defined as 'done' | 'alreadyDone' | 'setUnavailable' | 'notInExchange'.
UploadPrintedSamplesInput
Input of uploadPrintedSamples.
SamplesOutcome
How uploadPrintedSamples ended: submitted with the review sent to the SII; alreadySubmitted when a review was already sent (its state in the detail); blocked when the portal says the application is not in the stage; rejected when the SII rejected the review at once (the summary in the detail). Defined as 'submitted' | 'alreadySubmitted' | 'blocked' | 'rejected'.
PrintedSampleFile
A sample file as the certification uploads it: its base name and its bytes.
Fields of RunExchangeInput
Field
Type
Description
setXml?
string
The exchange set, when the caller has it (downloaded by hand from the portal).
Fields of UploadPrintedSamplesInput
Field
Type
Description
samples
readonly PrintedSampleFile[]
The PDFs to upload, in order; readPrintedSamples reads them from a directory.
runCertification runs the HTML side of the certification in stage order (test sets, books, simulation, exchange, printed samples, declaration of compliance), resumed from the saved state, and stops with a RunStop. The declaration of compliance is irreversible and is made only with declareCompliance: true. Guide: Runner.
TypeScript
// The HTML side of the certification, in stage order, resumed from the saved state: the test set// (downloaded once), the folios, each set not yet sent, their declaration and approval; the books;// the advance; the simulation sent, declared and confirmed; the exchange set answered, uploaded// and confirmed; the printed samples uploaded and submitted when the `samples` option gives them// (else it stops there); and then it declares compliance, only with `declareCompliance: true`,// because that declaration cannot be undone.function runCertification( dependencies: CertificationDependencies, options?: RunCertificationOptions,): Promise<RunCertificationResult>
Type
Description
RunCertificationOptions
Options of runCertification.
RunCertificationResult
What runCertification returns.
RunStop
Why the runner stopped. Defined as | 'done' | 'exchange' | 'printedSamples' | 'compliance' | 'until' | 'blocked' | 'rejected' | 'timedOut' | 'incomplete'.
Fields of RunCertificationOptions
Field
Type
Description
until?
CertificationStage
Stop once this stage is complete.
optionalSets?
readonly string[]
The optional sets to tick when downloading; DEFAULT_OPTIONAL_SETS by default.
declareCompliance?
boolean
Make the declaration of compliance, the sworn statement of the legal representative, which cannot be undone. Off by default: the runner stops at compliance instead.
exchangeSetXml?
string
The exchange set, when it was downloaded by hand from the portal.
The receipts (boletas) certification is an application of its own with no runner: these are pieces you chain. A receipt (39, 41) takes receiptReferences, never references. Guide: Receipts.
// The receipts portal (`certBolElectDteInternet`), where the certification of electronic receipts// runs. Its hashes are not discovered: `moduleName` is what its interface suggests, not a recorded// fact.const RECEIPTS_PORTAL: GwtPortal// Parses the receipts test set the receipts portal delivers, a plain text.function parseReceiptsTestSet(text: string): readonly ReceiptsTestCase[]
Type
Description
ReceiptsTestCase
One case of the receipts test set: one receipt to issue.
// Issues the receipts test set: one receipt of type 39 per case, in order, each with the next// folio of the source, the final consumer as receiver, the prices of the set taken as including// VAT, the exemption of an exempt item, the unit of measure an observation names on its first// item, and one reference with the code `SET` and the reason `CASO-<n>`; then signs the// `EnvioBOLETA` that carries them, with the certificate holder as sender (the issuer when the// certificate names none) and the SII as receiver.function issueReceiptsSet( cases: readonly ReceiptsTestCase[], options: IssueReceiptsSetOptions,): Promise<IssuedReceiptsSet>
Type
Description
IssueReceiptsSetOptions
What issuing the receipts set needs.
IssuedReceipt
One issued receipt of the set.
IssuedReceiptsSet
The receipts set issued: its receipts in case order and the signed envelope that carries them.
Fields of IssueReceiptsSetOptions
Field
Type
Description
issuer
CertificationIssuerInput
The issuer, as for a document; what it leaves out takes the defaults of DEFAULT_CERTIFICATION_ISSUER. The RUT, the name and the address have none.
certificate
Certificate
The signing certificate; its holder is the sender of the envelope.
folios
FolioSource
Where the folios of type 39 and their CAFs come from.
The resolution of the certification environment; number 0 and the UTC date of the instant by default, field by field.
now?
() => Date
Clock, read once for the issue date (its UTC date), once per receipt for its stamps (the UTC instant to the second) and once for the envelope (the time of Chile).
// Sends the receipts set: uploads the envelope and reads the reply (`STATUS` 0 with a track id is// sent; `STATUS` 7 with a track id is also taken as sent, and without one it is a duplicate that// skips to the report with no track id; `STATUS` 99 and any other reply is a failure and throws),// waits 20 s and reads the status of a sent envelope once (a rejection ends here; a query that// never got through is logged, and an answer without a state, or an unknown one, blocks nothing),// then sends the folio consumption report built from the envelope, with the sequence number// `sequence` plus the attempt, up to ten attempts: a `STATUS` 7 without a track id is a duplicate// and three in a row mean today's report was already accepted; a `STATUS` 99 or another refusal// ends it as `consumptionFailed`; an uploaded report is given 30 s and its status read once: a// success or an intermediate state (a query error code or `0` too) accepts it, a query that never// got through accepts it, and anything else (a rejection, no state, an unknown state) tries the// next sequence number, unless its gloss speaks of authorisation or signing.function sendReceiptsSet( sii: SiiClient, issued: { readonly envelope: SignedEnvelope; }, options?: SendReceiptsSetOptions,): Promise<ReceiptsSendResult>// Builds the folio consumption report again from a receipts envelope already sent and uploads it// once, with the sequence number given.function resendReceiptsConsumption( sii: SiiClient, input: ResendReceiptsConsumptionInput,): Promise<{ readonly sequence: number; readonly xml: string; readonly trackId: string; readonly duplicate: boolean; }>
Type
Description
ReceiptsProgressEvent
The progress events of sendReceiptsSet, with their step names. Defined as { readonly step: 'BOLETA_SOAP_CHECK' } | { readonly step: 'BOLETA_RCOF' }.
SendReceiptsSetOptions
Options of sendReceiptsSet.
ReceiptsConsumptionAttempt
One folio consumption report tried.
ReceiptsSendResult
What sendReceiptsSet did.
ResendReceiptsConsumptionInput
Input of resendReceiptsConsumption.
Fields of SendReceiptsSetOptions
Field
Type
Description
sequence?
number
The sequence number of the first folio consumption report; 100 by default (also when it is 0), and each attempt adds one.
sleep?
(ms: number) => Promise<void>
Wait function; the client's by default.
onProgress?
(event: ReceiptsProgressEvent) => void
Progress events.
Fields of ReceiptsSendResult
Field
Type
Description
outcome
'sent' | 'envelopeRejected' | 'consumptionFailed'
How it ended.
notAuthorized
boolean
The SII's gloss or the error speaks of authorisation or signing: the company cannot sign receipts yet.
envelopeTrackId
string | null
The envelope's track id, to declare on the receipts portal; null when the SII already had the envelope and named none.
envelopeDuplicate
boolean
The SII already had the envelope.
consumptionTrackId
string | null
The accepted report's track id, or null.
consumptionSequence
number | null
The accepted report's sequence number, or null.
consumptionAlreadySent
boolean
Three reports in a row were duplicates: one was already accepted today.
consumptions
readonly ReceiptsConsumptionAttempt[]
Every report tried, in order.
detail?
string
The gloss or error that ended it, when it did not end in sent.
// Downloads the receipts test set.function downloadReceiptsTestSet( portal: PortalClient, input?: DownloadReceiptsTestSetInput, overrides?: CallOverrides,): Promise<ReceiptsTestSetDownload>// Declares the track id of the receipts envelope, so the SII validates the set// (`ingresarTrackId`), exactly as it is given. Sent once.function declareReceiptsTrackId( portal: PortalClient, input: ReceiptsPortalInput & { readonly trackId: string; }, overrides?: CallOverrides,): Promise<{ readonly body: string; }>// Reads the state of the receipts application: whether the company is enrolled (it has valid// representatives), whether the SII approved the set (`P90`, ready to declare) and whether the// declaration was made (`P91`).function readReceiptsStatus( portal: PortalClient, input?: ReceiptsPortalInput, overrides?: CallOverrides,): Promise<ReceiptsStatus>// Makes the declaration of compliance of the receipts application, which authorises the company to// issue receipts in production (`autorizarEmpresaBolProd`). It cannot be undone.function declareReceiptsCompliance( portal: PortalClient, input: DeclareReceiptsComplianceInput, overrides?: CallOverrides,): Promise<ReceiptsComplianceResult>// Reads whether the company may issue receipts. In production, a GET of the stamping entry page// and a POST of its form with the company, and type 39 among the quoted option values of the// answer (which must have a selector).function verifyReceiptsAuthorization( input: VerifyReceiptsAuthorizationInput,): Promise<ReceiptsAuthorization>
Type
Description
ReceiptsPortalInput
What every operation of the receipts portal takes.
DownloadReceiptsTestSetInput
Input of downloadReceiptsTestSet.
ReceiptsTestSetDownload
What downloadReceiptsTestSet read.
ReceiptsStatus
The state of the receipts application.
ReceiptsProvider
The software provider the declaration names.
DeclareReceiptsComplianceInput
Input of declareReceiptsCompliance.
ReceiptsComplianceResult
How declareReceiptsCompliance ended.
VerifyReceiptsAuthorizationInput
Input of verifyReceiptsAuthorization.
ReceiptsAuthorizationCheck
One side of verifyReceiptsAuthorization. queryFailed means the portal did not answer the question: it is never "not authorised".
ReceiptsAuthorization
What verifyReceiptsAuthorization read; a side is null when its client was not given.
ReceiptsProgress
The receipts row of the progress page.
Fields of ReceiptsPortalInput
Field
Type
Description
companyRut?
string
Company RUT; the client's by default.
gwt?
GwtHashes
The portal's hashes, when the pair known to work has gone stale.
sessionChecked?
boolean
True when an earlier operation of the same run already checked the saved session.
Fields of DownloadReceiptsTestSetInput
Field
Type
Description
companyRut?
string
Company RUT; the client's by default.
gwt?
GwtHashes
The portal's hashes, when the pair known to work has gone stale.
sessionChecked?
boolean
True when an earlier operation of the same run already checked the saved session.
providerMail?
string
The software provider's mail the portal asks for with the set.
Fields of DeclareReceiptsComplianceInput
Field
Type
Description
companyRut?
string
Company RUT; the client's by default.
gwt?
GwtHashes
The portal's hashes, when the pair known to work has gone stale.
sessionChecked?
boolean
True when an earlier operation of the same run already checked the saved session.
provider
ReceiptsProvider
The software provider; a company that is its own provider passes itself.
businessName
string
The company's business name.
link?
string
The query link; www.sii.cl by default.
Fields of VerifyReceiptsAuthorizationInput
Field
Type
Description
production?
PortalClient
A client on production, to read the stamping form.
certification?
PortalClient
A client on certification, to read the progress page.
companyRut?
string
Company RUT; each client's by default.
sessionChecked?
boolean
True when an earlier operation of the same run already checked the saved sessions.