Integrate
Ticket XML
The full tag reference: text, layout, tables, QR, barcodes, images.
A ticket is a small XML document. The root element must be <ticket>. Raven turns it into whatever the printer at the other end speaks, so the same ticket works on hardware with different command languages, widths and character sets.
Text mode · 48 col
Layout and wrapping match the printer exactly. Barcodes, QR codes and images are drawn by the printer, so they show here as placeholders — switch to Graphic mode to preview them.
Graphic mode
Images hosted on a private/LAN address may appear blank in this preview but can still print.
The two render modes
The format field on a print request picks between them. Text mode ("Xml", the default) composes the ticket in the printer's native character grid: fastest, most compatible, and what you want for ordinary receipts. SVG mode ("Svg") renders the ticket as a graphic and sends it as an image: proportional type, exact rules, and layout that does not have to land on character boundaries. It prints more slowly and uses more paper feed.
Author the same Ticket XML either way. Reach for SVG mode when the layout matters more than the speed; stay on the default otherwise.
Text and layout
No attributes; nest them freely.
| Tag | Effect |
|---|---|
<p> | A plain text line: the baseline. |
<c> | Centre its contents. |
<bold> | Bold. |
<big> | Double height. |
<wide> | Double width. <big><wide> is the classic "large". |
<italic> | Italic. No-op on Star Line printers. |
<inv> | Inverted: white on black. |
<small> | Font B: physically smaller. |
<tiny> | Font C: smallest, model-dependent. Downgraded to <small> on Star Line. |
Structure
Void elements: write them self-closed.
| Tag | Effect |
|---|---|
<hr/> | Rule across the full paper width. |
<br/> | One blank line. |
<cut/> | Cut, and end the page. On a roll, a partial cut: put it at the end, or between receipts. On label stock it cuts the stock and starts the next label. |
<page/> | End the page and cut nothing. On label stock the next content starts on a new label, which is how a batch is written: fifty labels separated by <page/>, and a single <cut/> at the end if you want the strip severed. On a continuous roll there is no page to leave, so it does nothing at all. |
<pulse/> | Kick the cash drawer. Refused on a label printer, which has no drawer port. |
Tables
A table has two different children, and mixing them up is the most common mistake in Ticket XML:
<col>defines a column, in document order. Its own text is that column's header.<row>is a data row, holding one<val>per cell.
What you write
<table>
<col s="3">Item</col>
<col s="1" a="r">Qty</col>
<col s="2" a="r">Price</col>
<row>
<val>Espresso</val>
<val>2</val>
<val>5.00</val>
</row>
<row>
<val>Croque-monsieur</val>
<val>1</val>
<val>9.50</val>
</row>
</table><col>defines a column. Its text is the header, not a cell.sis a relative weight: 3 / 1 / 2 over 48 columns resolves to 24 / 8 / 16 characters.<row>holds one<val>per cell, in column order.
What prints · 48 col
Layout and wrapping match the printer exactly. Barcodes, QR codes and images are drawn by the printer, so they show here as placeholders — switch to Graphic mode to preview them.
These are the format's only attributes:
| Attribute | On | Values | Default |
|---|---|---|---|
border | <table> | Truthy (1, true, yes) draws a full box. | off |
s | <col> | Integer > 0. Relative width: s="3" is three times s="1". | 1 |
a | <col> | l · r · c | l |
Rules worth knowing
- Cells are plain text. Style tags inside a
<val>are not supported: the text comes through, the formatting does not. If a total has to be bold, give it its own<p>line instead. - A header row appears only if some
<col>carries text. For a headerless block such as a totals table, write self-closing<col s="4"/>elements that carry weights and nothing else. - No
<col>at all is legal. The column count is then inferred from the widest row: equal widths, left aligned, no header. - Short and long rows are tolerated. Missing cells pad blank; cells past the last column are dropped.
- One font per table. A table inside
<small>renders wholly in that font and fits proportionally more columns. Mixed fonts would break the alignment, so they are not offered. - A table is always full width. Wrapping one in
<c>does nothing.
Media and symbology
| Tag | Content | Notes |
|---|---|---|
<qr> | Any string: a URL, text. | Wrap in <c> to centre. |
<ean> | 12 or 13 digits. | 12 digits and the printer adds the check digit. A wrong length prints an inline error instead. |
<img> | An absolute HTTPS URL. | Fetched at print time. On any failure the line prints as [image: <your URL>] rather than the ticket failing, so a broken logo is visible on the paper instead of silent. |
<svg> | Inline SVG markup. | Rendered as a picture, treated as opaque; don't nest Raven tags inside it. |
Worked examples
A receipt
<ticket>
<c><bold><big>LE COMPTOIR</big></bold></c>
<c><small>12 rue des Halles · Brussels</small></c>
<br/>
<hr/>
<table>
<col s="3">Item</col>
<col s="1" a="r">Qty</col>
<col s="2" a="r">Price</col>
<row><val>Espresso</val><val>2</val><val>5.00</val></row>
<row><val>Croque-monsieur</val><val>1</val><val>9.50</val></row>
</table>
<hr/>
<table>
<col s="4"/>
<col s="2" a="r"/>
<row><val>TOTAL</val><val>14.50</val></row>
</table>
<br/>
<c><qr>https://le-comptoir.example/receipt/42</qr></c>
<br/>
<cut/>
</ticket>A kitchen order
Large, no prices, no logo. It is read across a hot kitchen at arm's length.
<ticket>
<c><bold><big><wide>TABLE 7</wide></big></bold></c>
<hr/>
<big><p>2x Steak - rare</p></big>
<big><p>1x Frites</p></big>
<br/>
<cut/>
</ticket>Preview before you print
POST /printers/{id}/render returns the ticket as it would come out of that printer: its width, its character grid. Use it in your own tooling so you are not debugging layout by burning paper in a live venue.
Before you send
- Root element is
<ticket>. - There is a
<cut/>at the end. - Text that must be read across a room is
<big>, not just<bold>. - Money columns use
a="r". - You sent an
idempotencyKey. See Printing a ticket.