Skip to main content

Overview

Webhooks push events to your HTTPS endpoint as they happen. Endpoints are managed entirely via the API (/v1/webhooks); there is no dashboard UI. Endpoints carry a source (api by default; integration platforms like Zapier, Make and n8n set their own when they register endpoints on your behalf). Caps are counted per source, so integration-managed endpoints never crowd out your own. Sign each endpoint’s secret into your server and verify every delivery before processing. Respond with a 2xx status within 10 seconds; run any heavy processing asynchronously after sending the response.

Event types

Event envelope

Every delivery sends a JSON body with this shape:

Scan event privacy

Scan events (qr.scanned) never include IP addresses or precise location. The payload carries only coarse, aggregate-grade fields: qr_code_id, scanned_at, country, city, device, os, browser, referrer, language. Example qr.scanned data object:

Verifying signatures

Every delivery includes a QRKit-Signature header:
The v1 value is HMAC-SHA256(secret, "{t}.{raw_request_body}") computed over the raw (unparsed) request body. Always verify against the raw bytes before JSON-parsing. Reject deliveries where t differs from your server clock by more than 5 minutes to prevent replay attacks. Use a constant-time comparison to avoid timing side-channels. During the 24-hour window after calling rotate-secret, deliveries carry two v1= signatures (new secret first, then old). Verifying against either one passes — this lets you roll your secret without any downtime. Additional headers on every delivery:

Delivery & retries

A delivery succeeds when your endpoint returns any 2xx status within 10 seconds. Failed deliveries (non-2xx, timeout, or connection error) are retried on this schedule: After 7 failed attempts (~33 hours total) the delivery is marked failed with no further retries. Delivery semantics:
  • At-least-once — the same event may be delivered more than once. Deduplicate by the event id field (also in the QRKit-Event-Id header).
  • Ordering not guaranteed — process events idempotently. If you need authoritative object state, re-fetch via the REST API or the events archive.
Auto-disable: An endpoint with sustained failures is automatically disabled and the workspace owner is emailed. Re-enable it once your server is healthy:
Permanent unsubscribe: Respond 410 Gone to any delivery to immediately disable the endpoint with no further retries.

Secret rotation

Rotate your endpoint secret without downtime:
The response returns the new secret once — store it immediately. The old secret continues to sign deliveries for 24 hours, so you can update your server before the old key expires.

Testing

Send a ping event through the real delivery pipeline to verify your endpoint is reachable:
The response includes the full delivery result (status code, response body, latency). Inspect past delivery attempts for any endpoint:

Event archive

QRKit stores all events for 30 days regardless of whether any webhook endpoints are registered. Use the archive to recover events your endpoint missed.
The archive only lists events — it does not re-trigger deliveries. To replay an event to your endpoint, re-fetch the object via the REST API and process it in your application.