Print operations queue a receipt on the terminal's thermal printer (Sunmi P3, Sunmi P2 SE) through Kushki's cloud relay. You describe the receipt as an ordered commands array; array order is physical paper order.Kushki ONE Cloud is currently in Beta for Chile 🇨🇱. Do not deploy to production without coordinating with the Kushki integration team.
Operations#
Both require the same signed Authorization and timestamp headers as the Payment API.Printing is asynchronous even on the /sync/ prefix. The 202 means queued, not printed. The real outcome arrives by webhook or polling.
How a job resolves#
1.
POST .../sync/print with your commands array → 202 and a printJobId.
2.
The terminal prints. Then either:Webhook — supply webhookUrl in the request and Kushki POSTs the final state to it. Fire-and-forget, not retried.
Polling — POST .../sync/print_job with print_job_id in the body, every 2–3 seconds, until COMPLETED or FAILED.
| 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 |
Commands#
Write 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 CHILE\n", "align": "CENTER", "size": 32, "bold": true },
{ "type": "divider", "dividerType": "DOTTED", "offset": 10 },
{ "type": "columns", "columns": [
{ "text": "Producto Premium", "weight": 2, "align": "LEFT" },
{ "text": "$10.000", "weight": 1, "align": "RIGHT" }
]},
{ "type": "feed", "lines": 3 },
{ "type": "cut" }
]
}
Amounts are CLP — print them with no decimals ($10.000), matching what the terminal charged.
Practical limits#
| 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 |
| HTTP timeout | ≥ 15 seconds — the relay adds latency to the 202 |
Hardware failures come back as errorCode: OUT_OF_PAPER, COVER_OPEN, PAPER_JAM, PRINTER_HOT, CUTTER_ERROR, OFFLINE and others. Surface them to the cashier — most are fixed by someone touching the device.
Got a suggestion on this documentation? Contact us.