commands array; array order is physical paper order.| Operation | Endpoint | Returns |
|---|---|---|
| Create Print Job | POST /terminal/v1/print | 202 Accepted with status PENDING |
| Get Print Job Status | GET /terminal/v1/print_job?data=… | PENDING, IN_PROGRESS, COMPLETED or FAILED |
/sync/ and /async/ prefixes that payment operations do.Authorization: Basic <SHA512>, timestamp in seconds, and the payload as the encrypted envelope {"data":"<iv_hex>:<cipher_hex>"}. The commands array shown on this page is the plaintext you encrypt, not what travels on the wire. See Authentication.GET, so the encrypted value travels as the data query parameter and no other parameter may be sent: the URL carries ?data=<iv_hex>:<cipher_hex> and the plaintext you encrypt is {"print_job_id": "..."}.202 means queued, not printed — the real outcome arrives by webhook or polling.200 and the outcome lives in the body — the print endpoints return real HTTP codes:| Code | Meaning |
|---|---|
202 | Job queued |
404 | The print_job_id does not exist |
409 | The printer is busy, or skipIfBusy was true |
TER-004 on these endpoints means the printer is busy — the message names the action in progress, and the job can be retried in a few seconds. The same code on a payment endpoint means the cardholder canceled on the terminal, which must not be retried. See the Error Catalog.POST /terminal/v1/print with your commands array → 202 and a printJobId.webhookUrl and the terminal POSTs the final state to it. Fire-and-forget, not retried.GET /terminal/v1/print_job?data=… every 2–3 seconds until COMPLETED or FAILED. The print_job_id travels inside the encrypted payload, not as its own query parameter.| Field | Why it matters |
|---|---|
printJobId | Your idempotency key. Reuse it on retries — the terminal deduplicates and will not print twice |
externalReference | Free-form traceability. Echoed back in status and webhook responses |
skipIfBusy | true returns 409 instead of queueing. Never set it to true for a payment receipt |
webhookUrl you supplied, and you implement it on your side. Its page documents the payload your endpoint will receive.type in lowercase. Every other enum value — align, dividerType, algorithm, errorLevel — is UPPERCASE.type | What it prints |
|---|---|
text | A line or paragraph, with size, alignment, bold, italic, underline |
columns | Proportional columns on one line — item and price |
divider | Full-width rule: SOLID, DOTTED or EMPTY |
feed | N blank lines |
space | Pixel-precise vertical whitespace |
cut | The auto-cutter. Silently ignored on cutterless terminals |
image | A Base64 PNG/JPG, typically the merchant logo |
qr | A QR code generated in printer hardware |
barcode | A CODE128 barcode generated in printer hardware |
{
"printJobId": "RECEIPT-20240317-001",
"commands": [
{ "type": "text", "text": "MI COMERCIO COLOMBIA\n", "align": "CENTER", "size": 28, "bold": true },
{ "type": "text", "text": "NIT: 900.123.456-7\n", "align": "CENTER", "size": 20 },
{ "type": "divider", "dividerType": "SOLID", "offset": 8 },
{ "type": "columns", "columns": [
{ "text": "2x Combo Hamburguesa", "weight": 2, "align": "LEFT" },
{ "text": "$ 300.000", "weight": 1, "align": "RIGHT" }
]},
{ "type": "columns", "columns": [
{ "text": "TOTAL", "weight": 2, "align": "LEFT" },
{ "text": "$ 380.000", "weight": 1, "align": "RIGHT" }
]},
{ "type": "qr", "content": "https://facturacion.micomercio.co/ticket/4421", "dotSize": 6, "errorLevel": "M", "align": "CENTER" },
{ "type": "feed", "lines": 4 },
{ "type": "cut" }
]
}$ 380.000), matching what the terminal charged.| Rule | Detail |
|---|---|
Always end with feed + cut | Advance ≥ 3 lines, or the cut lands on printed content |
| Max image width | 384 px on Sunmi hardware |
| Logos | Prefer BINARIZATION — sharper edges on monochrome art. DITHERING is for photos |
| Base64 | Raw string only. The data:image/png;base64, prefix makes the image fail silently |
| Codes | Prefer qr and barcode over image — hardware generation is faster and denser |
| HTTP timeout | ≥ 15 seconds on the local network |
errorCode: OUT_OF_PAPER, COVER_OPEN, PAPER_JAM, PRINTER_HOT, CUTTER_ERROR, OFFLINE and others. They surface with type: TERMINAL-PRINTER in the error body. Surface them to the cashier — most are fixed by someone touching the device.Got a suggestion on this documentation? Contact us.