GET/v1/printers
List printers
Returns the merchant's printers, cursor page first. Ordered by name, then id.
Devices should not call this to sync — use listChanges, which returns only what has
changed. This is the dashboard's printer read.
Parameters
-
cursorquery · stringOpaque cursor from a previous page's
next_cursor. Omit to start from the beginning.Pass it back exactly as received. It is base64 and its structure is not part of this contract — decoding it, or constructing one by hand, will break without notice.
-
limitquery · integer · int32Maximum items to return. The server may return fewer, so always drive the loop from
has_morerather than from the size of the page you got back. -
location_idquery · string · uuidOnly printers at this location.
Responses
-
200
A page of printers.
PrinterPage · application/json
has_morebooleanRequired
Whether another page follows.
-
itemsarray of PrinterRequired
idstring · uuidRequired
namestringRequired
1–255 chars
auto_printbooleanRequired
Whether a completed sale prints automatically on this printer, or is merely offered.
command_setstring · enumThe command set the printer speaks, so a till encodes the bytes it can render.
escposis the Epson dialect the till uses by default on every transport;star_line_modeis Star's own text command set, for a Star printer that does not emulate ESC/POS. A till reaches the printer the same way regardless and renders the same receipt, bill, kitchen ticket and drawer kick in the chosen bytes.escposstar_line_modedefault escpos
-
connectionobjectRequired
How the till reaches the printer.
typestring · enumRequired
The transport.
networkis a printer on the shop's LAN reached by TCP;bluetoothis one a till pairs with;usbis one plugged into the till.networkbluetoothusbhoststringRequired
Where the printer is — an IP address or host name for a network printer, a Bluetooth address for one a till pairs with, or a device path for a USB printer.
1–255 chars
portintegerThe raw ESC/POS socket port;
9100is the usual one. Used only for a network printer; a Bluetooth or USB printer leaves it 0.0–65535
created_atTimestampRequiredRead only
Server-assigned RFC 3339 timestamp, always UTC.
Server-assigned because device clocks drift and cannot be trusted for ordering — a till that has been powered off for a week may come back with a clock hours out. Where the device's own view of time matters it is carried separately in
client_created_at.device_idstring · uuidNullable
The single device this printer is bound to. A
receiptprinter that belongs to one counter till is bound to it; a printer shared by a whole location is not. A device resolves its own receipt printer from this first, then the location's.location_idstring · uuidRequired
The room or site the printer is installed in. A printer is only offered to devices at its own location.
merchant_idstring · uuidRequiredRead only
paper_width_mminteger · enumRequired
The paper roll width, in millimetres. It decides the column width a receipt is rendered at;
40is the narrow roll a smart-pos terminal's built-in printer takes,58the receipt printers a counter till pairs with,80the standard roll kitchen and receipt printers take.405880rolestring · enumRequired
What the printer is for. A
receiptprinter takes the document a customer is handed; akitchenprinter takes kitchen tickets; adrawer_kickprinter only opens the cash drawer, on a cash tender and on a recorded no-sale. A device resolves which of the location's printers a particular document goes to from this role.receiptkitchendrawer_kickstation_idstring · uuidNullable
The station a
kitchenprinter is bound to, so a ticket for the grill prints at the grill: a ticket is routed to the printer bound to its station first, then to a station-less kitchen printer. A receipt or drawer printer is never station-bound.updated_atTimestampRequiredRead only
Server-assigned RFC 3339 timestamp, always UTC.
Server-assigned because device clocks drift and cannot be trusted for ordering — a till that has been powered off for a week may come back with a clock hours out. Where the device's own view of time matters it is carried separately in
client_created_at.versionVersionRequiredRead only
Optimistic concurrency version, raised by the server on every write. A version is never lower than one already returned for the resource, though it may rise by more than one.
Returned in the
ETagresponse header as well as in the body. Send it back inIf-Matchon an update and the write is rejected with412if anyone else has written since — which is what stops two tills silently overwriting each other's edit to the same product when both come back online at once.≥ 1
next_cursorstringNullable
Opaque cursor for the next page, or null on the last page. Pass it back verbatim as the
cursorquery parameter; its contents are not part of this contract.
-
400
The request could not be parsed. Malformed JSON, a bad query parameter, or a header that failed to decode, among them an
API-Versionlater than the server speaks or not a date (api-version-unknown, with the server's own inapi_version).Distinct from
422: a400never reached validation, soinvalid_paramsis absent. Retrying without changing the request will fail again, except that a request refused for itsAPI-Versiongoes once the server is updated. -
401
No credentials, or credentials that could not be verified — missing bearer token, malformed JWT, expired token, or a signature that failed against the issuer's JWKS.
Refresh the token and retry once. Repeated
401after a refresh means the device needs to re-enrol. -
403
Authenticated, but not permitted. The token is valid and its merchant was resolved, but the caller's role does not allow this operation, or the target belongs to a different merchant.
Cross-tenant access is reported as
403on a resource the caller may not see, and as404where even confirming existence would leak information. Retrying will not help. -
410
The request names an
API-Versionthis server no longer serves (docs/decisions/0011). Nothing in it was read.api_versionnames the version the server speaks: the client is behind, and sends the request again once it is updated. -
429
Rate limit exceeded. Honour
Retry-Afterrather than applying your own backoff.A fleet of tills coming back online together after an outage is the realistic cause, which is exactly when uncoordinated client-side retry turns a brief outage into a sustained one. The limit is per process, and per site for what records trade there — a request spends its site's budget, and a till's own smaller one inside it — and per
(client, merchant)for everything else; noRateLimitfield is sent, so this response and itsRetry-Afterare the whole of the contract. -
500
Something failed on our side.
trace_ididentifies the request in our tracing — quote it in a support ticket.The body never carries internal detail: no SQL, no stack traces, no upstream error strings. Safe to retry with the same
Idempotency-Key. -
503
Temporarily unable to serve the request — a dependency is down or the service is shedding load.
Retry with the same
Idempotency-KeyafterRetry-After. This is always safe: a request that did take effect before the failure will be recognised as a replay.