What goes inside data
The shared vocabulary for amounts, open fields, delivery address, tax regime, logo, software, numbering authorization and legal notes.
Every call sends the document type and its data. There is a complete example body for each type in the Quickstart; the fastest way to start is to take the one for your type, replace its data with yours and send it. Then trim whatever doesn’t apply.
One vocabulary for amounts
Totals go nested, and they are the same for every design:
"totals": {
"gross": 240000, // gross value
"taxableBase": 240000, // taxable base
"tax": 45600, // VAT (IVA)
"withholding": 6000, // withholding tax (retefuente)
"discount": 0, // global discount
"surcharge": 0, // global surcharge
"total": 285600
}
Keeping them independent of the chosen design is deliberate: if each design read the figures its own way, you would have to know which design you requested to know how to send them, and that is the kind of trap you pay for with a wrong invoice.
Remember that nothing is calculated: if total doesn’t add up with the lines, what arrived is what gets printed. The same goes for withholding: it is printed on its own line and is not subtracted from the total. If you don’t send it, the line appears without a figure, because a $ 0,00 would say there was no withholding.
The VAT rate of each line goes in the item, and is printed in its column as 19 %. It goes as a number, without the percent sign —19, not "19%"—: the engine adds the « %» suffix. If you don’t send it, the cell stays empty:
"items": [
{ "code": "SRV-DOM-001", "name": "Registro de dominio .com — anual",
"quantity": 1, "amount": 240000, "taxRate": 19, "total": 240000 }
]
What each company prints, in an open list
Salesperson, channel, concept, purchase order, order number, delivery point, cost center, billed period… Every company prints different ones, so they are not fields with their own name: they go in fields, and they are drawn in the order you send them.
"fields": [
{ "label": "Vendedor", "value": "Mariana Gómez Uribe" },
{ "label": "Orden de compra", "value": "OC-2026-0448" },
{ "label": "Punto de entrega", "value": "Centro de datos, Carrera 70 #45-23, Medellín" }
]
A field you send without its value —empty, null or absent— is printed anyway: the label appears and the gap stays empty. That way the row is still there and you don’t have to filter the list before sending it. What does get discarded is a field without a label: a loose gap doesn’t say what it is for. A 0 is data and is printed as such. If you send none, the box is not drawn.
Keys are accepted in English and in Spanish: { "label", "value" } or { "etiqueta", "valor" }.
Data with its own meaning —the number, the dates, the CUFE, the totals— does not go here: those have their own place and their own rule.
The delivery address
Delivery address (shipTo: name, address, phone) — today only the destacada design draws it; if you don’t send it, it doesn’t appear. It is optional: the other designs ignore it, so you can always send it without anything changing in them.
"shipTo": {
"name": "Bodega central",
"address": "Autopista Sur 12-34, Itagüí",
"phone": "6043334455"
}
Without a name or an address, the block doesn’t appear: a «Enviar a» (“Ship to”) that doesn’t say where is of no use to anyone.
Your tax regime
What your company declares about itself —VAT-responsible, self-withholder or not, large taxpayer— goes in yourCompany.taxRegime and is printed next to the NIT, exactly as you send it:
"yourCompany": {
"name": "Empresa Emisora S.A.S.",
"nit": "900123456-7",
"taxRegime": "Responsables de IVA · No autorretenedores"
}
If you don’t send it, it takes up no row. We deliberately don’t fill it in for you: it is your tax declaration, and a generator that assumed it would be signing it on your behalf.
Your logo
The logo is yours, not ours: it arrives in yourCompany.logo and each application sends the logo of the issuing company. There is nothing to upload to us or configure in advance.
"yourCompany": {
"name": "Empresa Emisora S.A.S.",
"nit": "900123456-7",
"logo": "https://su-dominio.com/logo.png"
}
Three things that avoid a surprise:
- Absolute URL or
data:. A path like/logo.pngmeans nothing on a server: with no browser to complete it, there is nowhere to look for it. - PNG or JPEG, not SVG. This was verified by measuring the PDF transformation matrix: an SVG is drawn at its original size and the style box only crops it, so it comes out cut off unless it measures exactly the size of the box. A PNG does scale to fit.
- What is fixed is the slot, not the image. The logo fits inside without being distorted, so a wide mark and a square one both fit. If you send none, the document starts with the company name: no blank space is reserved and no “no logo” box is drawn, because a company not having a logo is not a shortcoming that needs announcing.
Who makes the software
Every electronic invoice states which software it was issued with. It is not a courtesy credit: it identifies who is answerable for the issuance.
"software": {
"manufacturer": "CoreLink S.A.S.",
"name": "CoreLink Facturación Electrónica",
"version": "1.0",
"web": "www.corelink.com.co"
}
The authorization number
Next to the sequential number goes the numbering authorization number, its date, the authorized range and its expiry. Without it, nobody can check that the printed number is within what was authorized:
"authorization": {
"number": "18764101686441853",
"authorizedAt": "18-11-2025",
"prefix": "PIFE", "rangeFrom": 1, "rangeTo": 10000,
"validFrom": "18-11-2025", "validUntil": "18-11-2027",
"resolution": "18764101686441", "economicActivity": "6201"
}
If it is missing, the document says «Sin número de autorización» (“No authorization number”) instead of staying silent.
Text in the margin
What has to be there but doesn’t need to get in the way —«Documento generado por computador», the software brand, a control number— is written top to bottom in the left margin, on every page:
"sideNotes": [
"Documento generado por computador. No requiere firma autógrafa.",
"CoreLink by Piensa IT S.A.S."
]
It uses a margin that would otherwise be wasted and lightens the footer, which on an electronic invoice is already full of CUFE and resolution.
It works the same on the invoice, the credit and debit notes, the Premium cash receipt, the account statement and the payslip. If you send none, the margin stays blank.
You provide the legal notes
The texts the invoice must carry —its treatment as a bill of exchange, the tacit acceptance under Law 1231, whatever applies to your regime— go in legalNotes, and are printed as is:
"legalNotes": [
"Esta factura electrónica de venta se asimila en todos sus efectos legales a una letra de cambio, conforme al artículo 774 del Código de Comercio.",
"Documento generado por computador. No requiere firma autógrafa."
]
We deliberately don’t choose them. Which notes an invoice must carry depends on the regime, the tax responsibilities and the activity of whoever issues it; a generator that decided them on its own would be drafting someone else’s document, and nobody corrects a wrong note on a signed invoice afterwards.
What changes for existing integrations
A few new things, for those who were already sending invoices:
- The left margin and the fields box are no longer filled in automatically: if you don’t send
sideNotesandfields, they simply don’t appear. - The entries in
fieldsare drawn in the order you send them. - The VAT rate of each line is empty if you don’t send
taxRate—previously the Estándar design printed0 %—. - The withholding line appears without a figure if you don’t send
totals.withholding. - The footer with the resolution, the software manufacturer and the page number now appears on every page, not only the first.
- The Premium title is printed smaller.
