Skip to main content

Receipts

Describe a receipt as JSON (type: "receipt", encoding: "json"). The agent converts it to ESC/POS for the target printer, so you never write printer commands. The same document prints on 58 mm and 80 mm printers of every supported brand.

Example​

{
"width": "80mm",
"codepage": "CP858",
"blocks": [
{ "type": "image", "src": "https://example.com/logo.png", "width": 384, "align": "center" },
{ "type": "text", "value": "Boutique Bèl Fanm", "align": "center", "bold": true, "size": 2 },
{ "type": "text", "value": "Pétion-Ville, Haïti", "align": "center" },
{ "type": "line", "style": "dashed" },
{
"type": "table",
"columns": [
{ "width": 0.6, "align": "left" },
{ "width": 0.15, "align": "right" },
{ "width": 0.25, "align": "right" }
],
"rows": [
["Rouj a lèv", "2", "1 500,00"],
["Poud", "1", "900,00"]
]
},
{ "type": "line", "style": "solid" },
{ "type": "pair", "left": "TOTAL", "right": "2 400,00 HTG", "bold": true },
{ "type": "qr", "value": "https://example.com/r/10492", "size": 6, "align": "center" },
{ "type": "barcode", "format": "CODE128", "value": "10492", "height": 60, "hri": "below" },
{ "type": "feed", "lines": 3 },
{ "type": "cut", "mode": "partial" },
{ "type": "drawer" }
]
}

What it prints on an 80 mm printer (drawn by the agent's renderer; the remote logo shows as a crossed box in previews):

The example receipt printed at 80 mm

Blocks​

BlockFields
textvalue, align (left, center, right), bold, underline, size 1–8, invert, font (a or b)
linestyle: solid, dashed or double
pairleft and right on one line (the left side is shortened when needed), bold
tablecolumns (each with width as a fraction of the line, and align), rows (lists of strings), bold. Long cells wrap.
qrvalue, size (module size in dots, 1–16), errorLevel (L, M, Q, H), align
barcodeformat (CODE128, EAN13, EAN8, UPC-A, CODE39, ITF), value, height in dots, width 1–6, hri (none, above, below, both), align. EAN and UPC check digits are validated.
imagesrc (an https URL, or base64 PNG/JPEG), width in dots, align, dithering (floyd-steinberg or threshold)
feedlines to feed
cutmode: full or partial
draweropens the cash drawer; pin 2 (default) or 5
rawdata: printer bytes in base64 (escape hatch)

A document has at most 2 000 blocks. The full schema is protocol/schemas/receipt-document.json.

Paper width and characters per line​

width is 58mm or 80mm; when missing, the printer's paper applies. Characters per line come from the printer's profile, not from the document:

PaperFont AFont B
58 mm3242
80 mm4864

A 58 mm receipt with every block type:

Every block type at 58 mm

A kitchen ticket with large text, inverted text, font B and a wrapped table:

A restaurant kitchen ticket at 80 mm

Accents and codepages​

Thermal printers do not understand UTF-8. The agent converts your text to the printer's codepage: CP437, CP850, CP858 (the default choice for French and Creole, with the euro sign), CP1252, CP866 or ISO-8859-15. Characters that the codepage lacks are transliterated (œ → oe), or printed without their accent as a last resort.

Set the codepage in the document (codepage), in the job (options.codepage), or per printer in the device config (printers.defaults.<printerId>.codepage). See Troubleshooting when accents come out wrong.

Images​

  • URLs are downloaded by the agent (5 seconds and 2 MB at most, cached for 24 hours). Inline base64 always works, also offline.
  • width is in printer dots: 384 dots is the full width of a 58 mm printer, 576 of an 80 mm printer.
  • Images are converted to black and white with Floyd–Steinberg dithering by default. Use threshold for logos with flat colours.

Build receipts in code​

The browser SDK has a fluent builder that produces the same JSON:

const doc = jp
.receipt({ width: "80mm", codepage: "CP858" })
.text("Boutique Bèl Fanm")
.bold()
.center()
.size(2)
.line("dashed")
.pair("TOTAL", "2 400,00 HTG")
.qr("https://example.com/r/10492")
.feed(3)
.cut();
await jp.print({ type: "receipt", data: doc });

From a server, send the JSON as data with POST /v1/jobs. To check a layout without printing, use POST /v1/receipt/preview (see Sandbox).

Job options for receipts​

options.cut (full, partial, none) and options.openDrawer apply after the document. options.copies prints it several times. Per-printer defaults (paper, codepage, cut) come from printers.defaults in the config.

On the free plan, receipts end with a small "Printed with JodaPrint" line.