QR scan tracking
A QR element in a template can be marked trackable in the editor. For every item rendered from such a template the platform issues a short URL on its redirect domain, encodes that URL in the printed QR code and records scans of it.
Tokens and destinations
When an item becomes READY, the QR destination is resolved from the item's variables (for example https://example.com/offer?code={{ code }}) and stored together with an unguessable short token. The destination must be an absolute http or https URL; otherwise no token is issued and the QR code encodes the raw expression result. Items show the result under qr:
{
"shortUrl": "https://pstb.dy/r/Kx7mQ2pLw9ZbRt",
"scanCount": 3,
"firstScannedAt": "2026-11-02T09:14:31Z",
"lastScannedAt": "2026-11-05T18:02:10Z"
}A repaired item keeps its token; the destination is refreshed from the new variables. Items without a trackable QR element have qr: null.
Scans
The redirect service answers a scan with a 302 to the stored destination, sets no cookies and records the scan asynchronously: timestamp, a user agent class (mobile, desktop, bot, unknown) and the coarse country reported by the CDN. Bots and link previews are redirected like anyone else, but their scans are flagged and never counted. Scans are rate limited per address and per token.
GET /v1/items/{id}/scanslists the scans of an item, newest first.GET /v1/items/{id}carries the counters;GET /v1/postflows/{id}/statssums them per Postflow (scans.itemsScanned,scans.scans).- The webhook event
qr.scannedis published for every human scan withscan.firstScanandscan.scanCount, so an endpoint can act on the first scan only or on every scan.
Scans are recorded a minute or so after they happen; counters and webhooks follow the recording.
Retention
Scan events follow the retention period of the item: after anonymisation the events are deleted and only the counters remain. The short URL keeps redirecting for as long as the destination exists, since printed cards outlive the data behind them.