Developers
API & integrations reference
Everything you need to call the Business API, manage keys, and receive webhooks.
Authentication
The Business API authenticates every request with an API key. Send it in the X-Api-Key header, or as a Bearer token in the Authorization header.
Keys are prefixed with qrg_ and are shown only once at creation. Store them securely; you cannot retrieve a key again later.
Requests without a valid key return 401. A key without the required permission gets 403 with the error insufficient_scope. Resources outside your workspace return 404, as if they did not exist.
Base URL
All Business API endpoints live under the /v1 prefix.
For example, list your QR codes at https://qr-global.com/api/v1/qr-codes.
- Resolved base URL
- https://qr-global.com
Endpoints
Every endpoint lives under /api/v1 and needs a key with the listed permission.
| Method | Path | Permission | What it does |
|---|---|---|---|
| GET | /qr-codes | qr:read | List QR codes (filters: type, search, folder_id, tag, archived) |
| POST | /qr-codes | qr:write | Create a QR code |
| POST | /qr-codes/bulk | qr:write | Create up to 100 QR codes at once |
| GET | /qr-codes/{id} | qr:read | Get one QR code |
| PUT | /qr-codes/{id} | qr:write | Update a QR code, its folder and tags |
| DELETE | /qr-codes/{id} | qr:write | Delete a QR code |
| GET | /qr-codes/{id}/image | qr:read | Render the image (PNG or SVG) |
| GET | /qr-codes/{id}/stats | analytics:read | Scan statistics |
| GET | /qr-codes/{id}/scans | analytics:read | Scan log |
| GET | /folders | qr:read | List folders |
| GET | /tags | qr:read | List tags |
| GET | /webhooks | webhooks:manage | List webhook subscriptions |
| POST | /webhooks | webhooks:manage | Subscribe to events |
| DELETE | /webhooks/{id} | webhooks:manage | Unsubscribe |
A machine-readable description (OpenAPI 3.1) for Postman, code generators and no-code tools: Download openapi.json
API keys
Create and revoke keys on the API keys page in your dashboard.
Each key belongs to your workspace and inherits your plan's rate limit.
Revoking a key takes effect immediately.
Permissions (scopes)
When you create a key, give it full access or only the permissions an integration needs. A key without a permission gets 403 with error insufficient_scope and required_scope in the response.
qr:read— Read QR codes- List and view QR codes, their images, folders and tags.
qr:write— Manage QR codes- Create QR codes (also in bulk), edit, move between folders, tag and delete them.
analytics:read— Read analytics- Scan statistics and the scan log of each QR code.
webhooks:manage— Manage webhooks- Subscribe endpoints to events and unsubscribe them (Zapier, Make).
Keys created before permissions were introduced keep full access. Full access also covers permissions added later.
Examples
Copy-paste curl commands to get started. Replace YOUR_API_KEY with a key from the API keys page.
List QR codes
curl -sS -H "X-Api-Key: YOUR_API_KEY" -H "Accept: application/json" \ "https://qr-global.com/api/v1/qr-codes"
Create a QR code
Send the QR type and content; the server generates and stores the code.
curl -sS -X POST "https://qr-global.com/api/v1/qr-codes" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"type":"url","content":"https://example.com","display_name":"Example link"}'Render an image
Fetch a ready PNG or SVG file — pass ?format=png
curl -sS "https://qr-global.com/api/v1/qr-codes/123/image?format=png&size=512" \ -H "X-Api-Key: YOUR_API_KEY" -o qr.png # SVG (vector, no size limit on scale): curl -sS "https://qr-global.com/api/v1/qr-codes/123/image?format=svg" \ -H "X-Api-Key: YOUR_API_KEY" -o qr.svg
Sample webhook payload
{
"event": "qr.scan.created",
"timestamp": "2026-04-03T12:00:00+00:00",
"data": {
"qr_code_id": 7,
"qr_code_uuid": "9b2f0c1e-4d4a-4f7e-9a51-2a7c3c1d8e10",
"type": "url",
"scan_id": 42,
"country": "UA",
"device_type": "mobile",
"scanned_at": "2026-04-03T12:00:00+00:00"
}
}Scan analytics
GET /qr-codes/{id}/stats returns totals, unique visitors, top countries, devices, browsers and scans per day. GET /qr-codes/{id}/scans returns the scan log, newest first, 50 per page (per_page up to 100).
Both accept from and to (a date like 2026-10-01 or a full timestamp) and timezone (UTC by default). A date without a time covers the whole day in that timezone.
Only your plan's history window is available: older scans are deleted. Visitor IP addresses and user agents are never returned.
Scan statistics for a period
curl -sS "https://qr-global.com/api/v1/qr-codes/123/stats?from=2026-10-01&to=2026-10-31&timezone=Europe/Kyiv" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Accept: application/json"
Scan log, second page
curl -sS "https://qr-global.com/api/v1/qr-codes/123/scans?per_page=100&page=2" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Accept: application/json"
Folders and tags
GET /folders and GET /tags list your workspace's folders and tags. Pass folder_id and tags (tag slugs) when you create or update a QR code: folder_id null takes the code out of its folder, and tags replaces the whole set.
Filter the QR code list with ?folder_id= or ?tag=.
Move a QR code to a folder and tag it
curl -sS -X PUT "https://qr-global.com/api/v1/qr-codes/123" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"folder_id": 4,
"tags": [
"campaign",
"priority"
]
}'Bulk creation
POST /qr-codes/bulk creates up to 100 QR codes in one request. It needs a plan with bulk creation, like CSV import in the dashboard, and respects your limit of active QR codes.
Each item is processed on its own: the response lists every item with status created (and the new code) or failed (with error and errors). Don't resend the whole batch, only the failed items.
Create two QR codes
curl -sS -X POST "https://qr-global.com/api/v1/qr-codes/bulk" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"codes": [
{
"type": "url",
"content": "https://example.com/spring",
"display_name": "Spring flyer",
"tags": [
"campaign"
]
},
{
"type": "url",
"content": "https://example.com/menu",
"display_name": "Table menu",
"folder_id": 4
}
]
}'Webhook subscriptions (REST hooks)
Zapier, Make and your own services can subscribe to events through the API: POST /webhooks with url and events, then DELETE /webhooks/{id} to unsubscribe. These are the same endpoints you see on the Webhooks page.
The response to POST contains secret, shown only once: use it to verify the X-Webhook-Signature header. If you don't send your own secret (16+ characters), we generate one.
Events: qr.scan.created, subscription.updated, payment.succeeded, lead.captured, rsvp.received, feedback.received, poll.voted. Subscribing needs a plan with webhooks; unsubscribing always works. A workspace can have up to 25 endpoints.
Subscribe to scans
curl -sS -X POST "https://qr-global.com/api/v1/webhooks" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"url": "https://hooks.zapier.com/hooks/catch/123/abc/",
"events": [
"qr.scan.created"
]
}'Unsubscribe
curl -sS -X DELETE "https://qr-global.com/api/v1/webhooks/42" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Accept: application/json"
Webhooks
Webhooks push events to your endpoint as they happen, so you don't have to poll.
Configure endpoints on the Webhooks page in your dashboard.
Each delivery is signed and retried on failure with exponential backoff.
The scan event fires when someone scans one of your QR codes.
Inspect delivery attempts, payloads, and responses in the delivery log.
Return a 2xx status to acknowledge a delivery; any other status is treated as a failure.
Conversion tracking
Conversions tell an A/B test which destination brings orders or sign-ups, not just scans. With auto-optimization on, traffic shifts to the variant that converts best.
Add the script to the page a visitor sees after converting: order confirmation, thank-you or success page. It works on any domain and needs no API key.
Snippet
<script src="https://qr-global.com/c.js" async></script>
- Every scan adds a signed qrg_v parameter to the destination URL, so the conversion is tied to the QR code and variant.
- The script keeps the token in a first-party cookie for 30 days, so the conversion still counts if the visitor browses other pages first.
- Each scan counts once: reloading the thank-you page doesn't add conversions.
- Works for QR codes that redirect to an http(s) page.
Exports
Export your QR codes, scans, locations, and activity as CSV from the Exports page.
Exports use your dashboard session, not an API key — open them while signed in.
Tips & common errors
- 401 Unauthorized — the API key is missing or invalid. Check the X-Api-Key header.
- 403 Forbidden — the key lacks the required permission (insufficient_scope) or your plan does not include the feature (api_access_required, bulk_not_available, webhooks_not_available).
- 404 Not Found — the resource does not exist or belongs to another workspace.
- 429 Too Many Requests — you hit your plan's per-minute limit. Wait the number of seconds in the Retry-After header.
- Some features (like webhooks) depend on your plan. Upgrade if an endpoint returns a feature error.
- No webhook deliveries yet? Trigger a scan on one of your QR codes to generate one.
- Failed webhook deliveries retry automatically; you can also retry them manually from the delivery log.
- Team members act within your workspace; keys and data are scoped to the workspace owner.