Examples

Create a print with searchable metadata, then find it again with the search API.

This guide walks through the two core workflows of the Prints API end to end:

  1. Create a print — upload ESC/POS bytes together with searchable metadata (label, deviceId, tag).
  2. Search prints — find prints back with field filters, tag queries, and a from/to date range.

You need an API token with the read and write scopes (see Authentication) and the slug of the workspace you are working in. The examples below use my-team as the slug and assume the token is exported as $VPRINTER_TOKEN.

Create a print

A print is created from raw ESC/POS bytes. There are two ingest endpoints:

  • POST /api/workspace/{slug}/prints/json — JSON body with the bytes base64-encoded in raw, metadata as sibling fields.
  • POST /api/workspace/{slug}/prints — the bytes as a binary request body, metadata as query parameters.

Metadata is what makes a print findable later, so attach it at ingest time:

FieldPurpose
labelHuman-readable name shown in the dashboard list (e.g. an order number).
deviceIdIdentifier of the device that produced the print (e.g. a kiosk or POS id).
tagFree-form key → value string map, queryable with tag queries. Up to 100 keys; keys and values up to 100 characters.
widthReceipt render width in monospace columns (24–80). Omit to use the workspace default.

JSON (base64) upload

The raw value below is a real, complete ESC/POS receipt (init → centered bold header → item rows → cut), so you can run the command as-is:

curl -X POST https://api.vprinter.dev/api/workspace/my-team/prints/json \
  -H "Authorization: Bearer $VPRINTER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "raw": "G0AbYQEbRQFWUFJJTlRFUiBDQUZFChtFADEyMyBQcmludCBTdHJlZXQKG2EALS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KQW1lcmljYW5vICAgICAgICAgICAgICAyICAgIDcuMDAKQ3JvaXNzYW50ICAgICAgICAgICAgICAxICAgIDMuNTAKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KG0UBVE9UQUwgICAgICAgICAgICAgICAgICAgICAgMTAuNTAKG0UAG2EBVGhhbmsgeW91IQobZAMdVgA=",
    "label": "order-1042",
    "deviceId": "kiosk-1",
    "width": 32,
    "tag": { "orderType": "delivery", "store": "gangnam" }
  }'

The stored print renders in the dashboard as a receipt preview, and the metadata travels with it:

A receipt preview next to its searchable metadata: label, deviceId, tags and width

The response is the created print:

{
  "id": 1042,
  "printKey": "pk_8f2c1a…",
  "label": "order-1042",
  "deviceId": "kiosk-1",
  "tag": { "orderType": "delivery", "store": "gangnam" },
  "width": 32,
  "quantity": null,
  "testPrint": false,
  "createdAt": "2026-06-12T09:30:00.000Z",
  "updatedAt": "2026-06-12T09:30:00.000Z"
}

Binary upload

The same print as a raw binary body. Metadata moves to query parameters; tags are repeated tag=key=value pairs (URL-encode the = inside the pair as %3D):

curl -X POST 'https://api.vprinter.dev/api/workspace/my-team/prints?label=order-1042&deviceId=kiosk-1&width=32&tag=orderType%3Ddelivery&tag=store%3Dgangnam' \
  -H "Authorization: Bearer $VPRINTER_TOKEN" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @receipt.bin

Generating the bytes

Any ESC/POS source works — a printer driver capture, an SDK, or react-thermal-printer, which composes the receipt as React components and renders it to the exact byte stream vprinter ingests:

import { Cut, Line, Printer, Row, Text, render } from 'react-thermal-printer';

const data = await render(
  <Printer type="epson" width={32}>
    <Text align="center" bold={true}>VPRINTER CAFE</Text>
    <Text align="center">123 Print Street</Text>
    <Line />
    <Row left="Americano  2" right="7.00" />
    <Row left="Croissant  1" right="3.50" />
    <Line />
    <Row left="TOTAL" right="10.50" />
    <Text align="center">Thank you!</Text>
    <Cut />
  </Printer>
);

await fetch('https://api.vprinter.dev/api/workspace/my-team/prints/json', {
  method: 'POST',
  headers: {
    authorization: `Bearer ${process.env.VPRINTER_TOKEN}`,
    'content-type': 'application/json',
  },
  body: JSON.stringify({
    raw: Buffer.from(data).toString('base64'),
    label: 'order-1042',
    deviceId: 'kiosk-1',
    width: 32,
    tag: { orderType: 'delivery', store: 'gangnam' },
  }),
});

Search prints

POST /api/workspace/{slug}/prints/search takes all filters in the JSON body. Every filter you pass is combined with AND; an empty body ({}) returns everything, newest first.

curl -X POST https://api.vprinter.dev/api/workspace/my-team/prints/search \
  -H "Authorization: Bearer $VPRINTER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "label": "order-1042" }'

Responses are paginated:

{
  "items": [ { "id": 1042, "label": "order-1042", "…": "…" } ],
  "total": 1,
  "page": 1,
  "pageSize": 100,
  "totalPage": 1,
  "hasNext": false,
  "hasPrev": false
}

String field filters

printKey, label and deviceId accept either a bare string — an exact match — or an { "op", "value" } object:

opMeaning
eqExact match (the default for a bare string).
neqNot equal.
containsCase-insensitive substring match.
{
  "label": { "op": "contains", "value": "order" },
  "deviceId": "kiosk-1"
}

Filter by tags

The tag filter queries the print's tag map. Its simplest form is a single condition:

{ "tag": { "op": "eq", "key": "orderType", "value": "delivery" } }

A condition has three parts:

PartMeaning
opeq, neq or contains — same semantics as the string field operators, applied to the tag's value.
keyThe tag key to look at (e.g. orderType).
valueThe value to compare against.

So the query above matches prints whose orderType tag is exactly delivery; { "op": "contains", "key": "store", "value": "gang" } matches prints whose store tag contains gang anywhere (case-insensitive), such as gangnam or Gangneung.

Combining conditions with and / or

Instead of a single condition, tag can be a group: an object with an and or or array of nested tag queries. Groups can contain conditions or further groups, up to 10 entries per group and 3 levels of nesting.

Match delivery orders from a store containing gang:

curl -X POST https://api.vprinter.dev/api/workspace/my-team/prints/search \
  -H "Authorization: Bearer $VPRINTER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tag": {
      "and": [
        { "op": "eq", "key": "orderType", "value": "delivery" },
        { "op": "contains", "key": "store", "value": "gang" }
      ]
    }
  }'

Both conditions must hold on the same print for it to match:

Three prints checked against an and-group tag query; only the print satisfying both conditions matches

Groups nest, so richer logic stays one query. Delivery orders that are either from the Gangnam store or handled by a courier whose name contains riders, excluding cancelled ones:

{
  "tag": {
    "and": [
      { "op": "eq", "key": "orderType", "value": "delivery" },
      { "op": "neq", "key": "status", "value": "cancelled" },
      {
        "or": [
          { "op": "eq", "key": "store", "value": "gangnam" },
          { "op": "contains", "key": "courier", "value": "riders" }
        ]
      }
    ]
  }
}

A few things to keep in mind:

  • A condition on a key the print does not have never matches — including with neq. { "op": "neq", "key": "status", "value": "cancelled" } matches prints whose status tag exists and is not cancelled, not prints without a status tag.
  • Keys are matched exactly (no contains on the key itself); operators apply to the tag value.
  • The tag filter combines with every other filter in the body with AND, like everything else.

Filter by date (from / to)

from and to bound the print's createdAt, both inclusive, as ISO 8601 timestamps. Pass either or both:

{
  "from": "2026-06-01T00:00:00Z",
  "to": "2026-06-30T23:59:59Z"
}

Offsets are honored, so 2026-06-01T09:00:00+09:00 and 2026-06-01T00:00:00Z are the same instant.

Pagination and ordering

page (1-based), pageSize (max 1000, default 100) and orderBy (id, createdAt or updatedAt with .asc/.desc) shape the result list. Putting it all together — page two of June's delivery orders, oldest first:

curl -X POST https://api.vprinter.dev/api/workspace/my-team/prints/search \
  -H "Authorization: Bearer $VPRINTER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tag": { "op": "eq", "key": "orderType", "value": "delivery" },
    "from": "2026-06-01T00:00:00Z",
    "to": "2026-06-30T23:59:59Z",
    "orderBy": "createdAt.asc",
    "page": 2,
    "pageSize": 50
  }'

On this page