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 edits — Buy one code for $9 and manage it in the dashboard. Open →
- Bulk static codes with no tracking — Upload 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 …"
}
}/api/v1/codesList your dynamic codes
/api/v1/codesCreate a dynamic code
{ "destination": "https://example.com", "title": "Menu" }/api/v1/codes/:idGet a single code
/api/v1/codes/:idUpdate destination, title, or status
{ "destination": "https://new-url.com", "status": "paused" }/api/v1/codes/:idDelete a code and its scan history
/api/v1/codes/:id/statsAnalytics — scans by day, device, country, regions, geo map points, cities, last 24h. Filter with ?country=®ion=&city=
/api/v1/codes/:id/scans/exportPer-scan CSV export with geo columns — supports same filters as stats
/api/v1/codes/:id/image.pngStyled QR image (PNG) encoding the code short URL — uses stored qrStyle
/api/v1/codes/:id/image.svgStyled QR image (SVG) encoding the code short URL
/api/v1/codes/:id/image.pdfStyled QR image (PDF) for print workflows
/api/v1/codes/:id/imageStyled QR image — ?format=png|svg|pdf, ?size=128–4096, ?preset=minimal
/api/v1/qr/bulkServer-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" }/api/v1/qr/compositePlace 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" }/api/v1/codes/:id/schedulesList scheduled destination swaps
/api/v1/codes/:id/schedulesCreate a scheduled destination
{ "destination": "https://example.com/happy-hour", "startsAt": "2026-07-03T22:00:00.000Z", "endsAt": "2026-07-04T02:00:00.000Z" }/api/v1/codes/:id/schedules/:scheduleIdUpdate or disable a scheduled destination
{ "enabled": false }/api/v1/codes/:id/schedules/:scheduleIdDelete a scheduled destination
/api/v1/campaignsList campaigns
/api/v1/campaignsCreate a campaign
{ "name": "Summer push", "codeIds": ["..."] }/api/v1/campaigns/:id/statsRollup analytics + A/B breakdown with campaign map and per-placement geoPoints
/api/v1/webhooksList scan webhook endpoints
/api/v1/webhooksRegister a scan webhook URL
{ "url": "https://api.example.com/scans" }/api/v1/webhooks/:idEnable/disable or update webhook URL
{ "enabled": false }/api/v1/webhooks/:idRemove 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