QRtistry

QRtistry REST API lets Agency subscribers provision dynamic QR codes, pull print assets, export analytics, schedule destination swaps, and receive signed scan webhooks — for agencies, ops teams, and developers automating rollouts.

Agency feature

API reference

Manage dynamic codes and campaigns from your own apps. Generate an API key from the dashboard. Try the interactive playground.

Who is the API for?

The REST API is an Agency feature for teams managing dynamic codes at volume — create, update, export, and report programmatically instead of one code at a time in the dashboard.

Agencies

Roll out dynamic codes for many clients, pull branded print assets, and ship monthly scan reports without clicking through the dashboard for every placement.

Marketing & ops teams

Provision codes from a CMS, CRM, or internal tool when a campaign goes live — then pause or redirect when it ends.

Developers

Wire QR creation, analytics, and scan events into an existing product with REST endpoints and signed webhooks.

No-code integrators

Route scan.created events to Zapier, Make, or n8n for Slack alerts, spreadsheet rows, and CRM updates.

Common workflows

Provision codes at scale

Create dynamic codes from a client list, event spreadsheet, or merchant onboarding flow. Store the returned id and shortUrl in your own database.

POST /api/v1/codes · POST /api/v1/qr/bulk

Pull branded assets for print

Fetch PNG, SVG, or PDF at print resolution — or composite a QR onto a poster template for signage automation.

GET /api/v1/codes/:id/image.pdf · POST /api/v1/qr/composite

Report to clients automatically

Pull per-code stats, geo breakdowns, and CSV exports — or rollup campaign analytics for A/B placement compare.

GET /api/v1/codes/:id/stats · GET /api/v1/campaigns/:id/stats

React to scans in real time

Register a webhook URL and receive signed POST payloads on every scan — no polling required.

POST /api/v1/webhooks

Operate codes without reprinting

Update destinations, pause codes, or schedule happy-hour swaps from a cron job or admin script.

PUT /api/v1/codes/:id · POST /api/v1/codes/:id/schedules

Group placements into campaigns

Organize table tents, window signs, and receipts under one campaign and compare rollup performance.

POST /api/v1/campaigns · GET /api/v1/campaigns/:id/stats

Integration patterns

  • Agency CMS. Client approved → POST /codes → store shortUrl → fetch image.pdf → deliver print files plus analytics link.
  • Scan-driven ops. Scan happens → webhook → Zapier → Slack + Google Sheets + CRM activity.
  • Scheduled retail. Friday cron updates destination or schedule → Monday cron pulls stats → email store manager.

Webhook setup for Zapier, Make, and n8n is documented on the integrations guide.

When not to use the API

The API manages tracked dynamic short links. Static codes and casual one-off use cases are simpler without it:

  • One-off static QR (URL, WiFi, phone)Use the free generator — no API or account required. Open →
  • Single dynamic code with manual editsBuy one code for $9 and manage it in the dashboard. Open →
  • Bulk static codes with no trackingUpload a CSV on the bulk page and download a ZIP. Open →

Agency includes 10 active dynamic codes; additional codes are $9 each. Rate limit: 60 requests/minute per API key. Bulk API accepts up to 200 rows per request.

Authentication

Include your API key in the Authorization header:

Authorization: Bearer qr_live_…

Base URL: https://qrtistry.com

Rate limit: 60 requests/minute per API key. Response headers include X-RateLimit-Remaining.

Scan webhooks

On every scan, QRtistry POSTs a JSON payload to your registered URLs. Verify authenticity with HMAC-SHA256:

X-QRtistry-Event: scan.created
X-QRtistry-Signature: <hmac-sha256 of raw body using your whsec_ secret>
{
  "event": "scan.created",
  "timestamp": "2026-07-02T22:00:00.000Z",
  "scanCount": 42,
  "code": {
    "id": "clx…",
    "title": "Menu",
    "destination": "https://example.com",
    "campaignId": null,
    "shortUrl": "https://qrtistry.com/r/clx…"
  },
  "scan": {
    "device": "mobile",
    "os": "iOS",
    "browser": "Safari",
    "country": "US",
    "city": "Chicago",
    "region": "IL",
    "latitude": 41.88,
    "longitude": -87.63,
    "timezone": "America/Chicago",
    "ip": "203.0.113.1",
    "userAgent": "Mozilla/5.0 …"
  }
}
GET/api/v1/codes

List your dynamic codes

POST/api/v1/codes

Create a dynamic code

{ "destination": "https://example.com", "title": "Menu" }
GET/api/v1/codes/:id

Get a single code

PUT/api/v1/codes/:id

Update destination, title, or status

{ "destination": "https://new-url.com", "status": "paused" }
DELETE/api/v1/codes/:id

Delete a code and its scan history

GET/api/v1/codes/:id/stats

Analytics — scans by day, device, country, regions, geo map points, cities, last 24h. Filter with ?country=&region=&city=

GET/api/v1/codes/:id/scans/export

Per-scan CSV export with geo columns — supports same filters as stats

GET/api/v1/codes/:id/image.png

Styled QR image (PNG) encoding the code short URL — uses stored qrStyle

GET/api/v1/codes/:id/image.svg

Styled QR image (SVG) encoding the code short URL

GET/api/v1/codes/:id/image.pdf

Styled QR image (PDF) for print workflows

GET/api/v1/codes/:id/image

Styled QR image — ?format=png|svg|pdf, ?size=128–4096, ?preset=minimal

POST/api/v1/qr/bulk

Server-side CSV/JSON bulk export as ZIP (up to 200 rows)

{ "rows": [{ "url": "https://menu.example.com", "label": "Table A" }], "preset": "restaurant", "size": 1024, "format": "png" }
POST/api/v1/qr/composite

Place a styled QR on a background image for signage

{ "codeId": "CODE_ID", "backgroundUrl": "https://cdn.example.com/poster.png", "x": 120, "y": 480, "size": 400, "format": "pdf" }
GET/api/v1/codes/:id/schedules

List scheduled destination swaps

POST/api/v1/codes/:id/schedules

Create a scheduled destination

{ "destination": "https://example.com/happy-hour", "startsAt": "2026-07-03T22:00:00.000Z", "endsAt": "2026-07-04T02:00:00.000Z" }
PUT/api/v1/codes/:id/schedules/:scheduleId

Update or disable a scheduled destination

{ "enabled": false }
DELETE/api/v1/codes/:id/schedules/:scheduleId

Delete a scheduled destination

GET/api/v1/campaigns

List campaigns

POST/api/v1/campaigns

Create a campaign

{ "name": "Summer push", "codeIds": ["..."] }
GET/api/v1/campaigns/:id/stats

Rollup analytics + A/B breakdown with campaign map and per-placement geoPoints

GET/api/v1/webhooks

List scan webhook endpoints

POST/api/v1/webhooks

Register a scan webhook URL

{ "url": "https://api.example.com/scans" }
PUT/api/v1/webhooks/:id

Enable/disable or update webhook URL

{ "enabled": false }
DELETE/api/v1/webhooks/:id

Remove a webhook endpoint

Examples

curl -X POST https://qrtistry.com/api/v1/codes \
  -H "Authorization: Bearer qr_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"destination":"https://menu.example.com","title":"Table tent"}'
curl -H "Authorization: Bearer qr_live_YOUR_KEY" \
  "https://qrtistry.com/api/v1/codes/CODE_ID/image.pdf?size=2048&preset=restaurant" \
  --output menu-qr.pdf
curl -X POST https://qrtistry.com/api/v1/qr/bulk \
  -H "Authorization: Bearer qr_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"csv":"url,label\nhttps://menu.example.com,Table A","preset":"restaurant","size":1024}' \
  --output qrtistry-bulk.zip