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):
Blocks
| Block | Fields |
|---|---|
text | value, align (left, center, right), bold, underline, size 1–8, invert, font (a or b) |
line | style: solid, dashed or double |
pair | left and right on one line (the left side is shortened when needed), bold |
table | columns (each with width as a fraction of the line, and align), rows (lists of strings), bold. Long cells wrap. |
qr | value, size (module size in dots, 1–16), errorLevel (L, M, Q, H), align |
barcode | format (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. |
image | src (an https URL, or base64 PNG/JPEG), width in dots, align, dithering (floyd-steinberg or threshold) |
feed | lines to feed |
cut | mode: full or partial |
drawer | opens the cash drawer; pin 2 (default) or 5 |
raw | data: 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:
| Paper | Font A | Font B |
|---|---|---|
| 58 mm | 32 | 42 |
| 80 mm | 48 | 64 |
A 58 mm receipt with every block type:
A kitchen ticket with large text, inverted text, font B and a wrapped table:
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.
widthis 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
thresholdfor 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.