Skip to content

createDte()

Builds an immutable, validated electronic tax document with its totals already calculated. It is the first step of every DTE lifecycle.

Basic Usage#

TypeScript
import { createDte } from 'dte-sdk'
 
const dte = createDte({
  type: 33,
  folio: 1024,
  issuedAt: '2026-10-28',
  issuer: {
    rut: '76.123.456-0',
    businessName: 'Arrow Software SpA',
    activity: 'Desarrollo de software',
    acteco: 620200,
    address: 'Av. Providencia 1234',
    commune: 'Providencia',
  },
  receiver: {
    rut: '77.654.321-7',
    businessName: 'Comercial Los Andes Ltda.',
    activity: 'Comercio al por menor',
    address: 'Huérfanos 1055',
    commune: 'Santiago',
  },
  items: [{ name: 'Licencia anual', quantity: 1, unitPrice: 120000 }],
})
 
dte.totals
// { net: 120000, exempt: 0, vatRate: 19, vat: 22800, total: 142800 }

Type Signature#

TypeScript
function createDte(input: CreateDteInput): Dte
 
type DteType = 33 | 34 | 39 | 41 | 46 | 52 | 56 | 61
 
interface CreateDteInput {
  type: DteType
  folio: number
  issuedAt?: string // 'YYYY-MM-DD', defaults to today in America/Santiago
  issuer: {
    rut: string
    businessName: string
    activity: string
    acteco: number | number[]
    address: string
    commune: string
    city?: string
  }
  receiver: {
    rut: string
    businessName: string
    activity?: string
    address?: string
    commune?: string
    city?: string
    email?: string
  }
  items: LineItem[] // 1..60 lines
  references?: Reference[] // required for 56 and 61
  paymentMethod?: 'cash' | 'credit' | 'free'
  dueDate?: string
}
 
interface LineItem {
  name: string
  description?: string
  quantity: number
  unitPrice: number
  unit?: string
  discountPercent?: number
  exempt?: boolean
}
 
interface Reference {
  type: DteType | 'SET'
  folio: number | string
  date: string
  code?: 1 | 2 | 3 // 1 = voids document, 2 = fixes text, 3 = fixes amounts
  reason?: string
}
 
// Dte = CreateDteInput with resolved defaults + `totals: Totals`, deeply readonly

Parameters#

  • input.type (DteType) - The document type code. See Document types below.
  • input.folio (number) - The document number, a positive integer from a CAF range you hold for this type. stampDte() checks it against the CAF.
  • input.issuedAt (string, optional) - Issue date as YYYY-MM-DD. Defaults to today in the America/Santiago time zone, not the server's.
  • input.issuer - Your company, as registered with the SII:
    • rut - The issuer RUT, with or without dots.
    • businessName - Legal name (razón social).
    • activity - Business line (giro).
    • acteco (number | number[]) - One or more economic activity codes.
    • address, commune - Street address and commune of origin. city is optional.
  • input.receiver - The customer. rut and businessName are required; activity, address, commune, city and email are optional.
  • input.items (LineItem[]) - Between 1 and 60 detail lines:
    • name - What you sell. description adds a longer text.
    • quantity, unitPrice - Quantity and net unit price in CLP (gross on receipts, see calculateTotals()).
    • unit (optional) - Unit of measure, such as 'UN' or 'KG'.
    • discountPercent (optional) - Line discount from 0 to 100.
    • exempt (optional) - true when the line is not subject to IVA.
  • input.references (Reference[]) - Other documents this one refers to. Required for debit notes (56) and credit notes (61).
    • type, folio, date - The referenced document. Use 'SET' as the type to reference a certification test set.
    • code - 1 voids the referenced document, 2 fixes text, 3 fixes amounts.
    • reason - Free text explaining the reference.
  • input.paymentMethod (optional) - 'cash', 'credit' or 'free' (no charge).
  • input.dueDate (optional) - Payment due date as YYYY-MM-DD.

Return Value#

Returns a Dte: your input with its defaults resolved (issuedAt is always set) plus a totals object, calculated with the same rules as calculateTotals().

The document is immutable. Its type is deeply readonly and the object is frozen, so every later step (stamping, signing) returns a new object instead of changing this one.

Errors#

createDte() throws a DteError when the input can't become a valid document:

CodeWhen
MISSING_FIELDA required field is missing or empty, including items and, for types 56 and 61, references
INVALID_RUTThe issuer or receiver RUT is malformed or its Modulo 11 check digit is wrong
INVALID_AMOUNTA quantity is not a positive number, a unit price is negative or not finite, or a discount is outside 0–100

Messages are generic on purpose: they never include RUTs or amounts. Branch on error.code, not on the message.

TypeScript
import { createDte, DteError } from 'dte-sdk'
 
try {
  createDte(input)
} catch (error) {
  if (error instanceof DteError && error.code === 'INVALID_RUT') {
    // Ask the user to check the customer's RUT
  } else {
    throw error
  }
}

Examples#

Exempt Lines#

Mark a line with exempt: true and it goes to totals.exempt instead of the taxable net:

TypeScript
import { createDte } from 'dte-sdk'
 
// `issuer` and `receiver` as in Basic Usage
const dte = createDte({
  type: 33,
  folio: 1024,
  issuer,
  receiver,
  items: [
    { name: 'Licencia anual', quantity: 1, unitPrice: 120000 },
    { name: 'Curso de capacitación', quantity: 2, unitPrice: 45000, exempt: true },
  ],
})
 
dte.totals
// { net: 120000, exempt: 90000, vatRate: 19, vat: 22800, total: 232800 }

Credit Note With a Reference#

Credit and debit notes must point at the document they modify:

TypeScript
import { createDte } from 'dte-sdk'
 
const creditNote = createDte({
  type: 61,
  folio: 501,
  issuer,
  receiver,
  items: [{ name: 'Licencia anual', quantity: 1, unitPrice: 120000 }],
  references: [
    { type: 33, folio: 1024, date: '2026-10-28', code: 1, reason: 'Anula factura' },
  ],
})

Leave out references on a type 61 and createDte() throws MISSING_FIELD. See Issue a Credit Note for the full flow.

Credit Sale With a Due Date#

TypeScript
const dte = createDte({
  type: 33,
  folio: 1025,
  issuer,
  receiver,
  items: [{ name: 'Licencia anual', quantity: 1, unitPrice: 120000 }],
  paymentMethod: 'credit',
  dueDate: '2026-11-27',
})

Immutability#

TypeScript
dte.folio = 1026 // ✗ TypeScript error: 'folio' is a read-only property
 
// Build a new document instead
const next = createDte({ ...input, folio: 1026 })

Document Types#

dte-sdk supports eight document types. DTE_TYPES maps each code to its official Spanish name:

CodeDocument
33Electronic invoice
34Exempt electronic invoice
39Electronic receipt
41Exempt electronic receipt
46Electronic purchase invoice
52Electronic dispatch guide
56Electronic debit note
61Electronic credit note
TypeScript
import { DTE_TYPES } from 'dte-sdk'
 
DTE_TYPES[33] // 'Factura electrónica'
DTE_TYPES[61] // 'Nota de crédito electrónica'