Developers
Webhooks
Receive scan and lifecycle events, verified with an HMAC-SHA256 signature.
Webhooks push events to your endpoint as they happen: scan.recorded, qrcode.created, qrcode.destination_updated, qrcode.paused, and qrcode.expired. Configure endpoints in Dashboard → Webhooks (Business and Enterprise).
Delivery
Events are POSTed as JSON with retries on failure (exponential backoff, up to 24 hours). Deliveries include an idempotency key so replays are safe to deduplicate.
POST /your/endpoint HTTP/1.1
Content-Type: application/json
X-Cue-Signature: t=1751500800,v1=5f8c2a...e91b
X-Cue-Event: scan.recorded
{
"id": "evt_2mq93k",
"type": "scan.recorded",
"createdAt": "2026-07-03T08:00:00Z",
"data": {
"qrcodeId": "qr_8fk2m1",
"country": "GB",
"device": "mobile",
"unique": true
}
}Verifying signatures
Every delivery is signed with your endpoint's secret using HMAC-SHA256. The X-Cue-Signature header carries a timestamp and signature. Recompute the HMAC over `timestamp + "." + rawBody` and compare with a constant-time check; reject anything older than five minutes to prevent replays.
import { createHmac, timingSafeEqual } from "node:crypto"
function verify(header, rawBody, secret) {
const { t, v1 } = Object.fromEntries(
header.split(",").map((part) => part.split("="))
)
const expected = createHmac("sha256", secret)
.update(t + "." + rawBody)
.digest("hex")
return timingSafeEqual(Buffer.from(expected), Buffer.from(v1))
}