QR Codes API Reference
Programmatically generate static and dynamic QR codes, customize dot palettes and embedded branding, re-target destination URLs post-print, and access destination version history.
Static QRs: Directly encode destination content into the QR matrix. 0 credits deducted, unlimited creation, free forever. Destination URLs cannot be edited post-print and scans are not tracked.
Dynamic QRs: Route through QRnaly managed shortlinks (qrnaly.com/q/{slug}). Consumes 1 Dynamic QR capacity. Enables real-time destination re-targeting and scan telemetry.
Editing a live dynamic QR destination URL or restoring a prior destination version consumes 1 Dynamic Update from your monthly plan allowance.
Exporting SVG/PNG/PDF, toggling pause/resume status, renaming, or updating folder assignment consumes 0 Dynamic Updates.
/api/v1/qrList Workspace QR Codes
Returns a paginated list of QR codes owned by the authenticated workspace, with optional folder filtering.
qr:readQuery Parameters
page(optional, integer, default: 1): Page index for pagination.limit(optional, integer, default: 20, max: 100): Number of QR records per page.folderId(optional, string): Filter results to a specific campaign folder.
Example cURL
curl -X GET "https://qrnaly.com/api/v1/qr?page=1&limit=20" \ -H "Authorization: Bearer qrs_live_your_api_key_here"
Successful Response (HTTP 200)
{
"data": [
{
"id": "qr_01j8m4k8...",
"workspaceId": "ws_01j8m1...",
"slug": "summer-festival",
"name": "Summer Festival Billboard",
"type": "url",
"folderId": "fol_01j8m2...",
"targetUrl": "https://example.com/summer-pass",
"status": "active",
"lifecycleStatus": "active",
"scanCount": 142,
"isDynamic": true,
"scanUrl": "https://qrnaly.com/q/summer-festival",
"design": { "fgColor": "#0f172a", "bgColor": "#ffffff" },
"createdAt": "2026-09-10T12:00:00.000Z",
"updatedAt": "2026-09-12T14:30:00.000Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 1,
"totalPages": 1
}
}/api/v1/qrCreate QR Code (Static or Dynamic)
Generates a new QR code with atomic quota verification and vector SVG generation. Supports Idempotency-Key header to prevent duplicates on network retry.
qr:writeIdempotency-Key (optional)Request Body Schema
targetUrl(required, string): Destination URL (must begin with http:// or https://).name(optional, string): Human-readable name (default: "API Generated QR").isDynamic(optional, boolean, default: true): If true, creates a managed shortlink QR. If false, creates pure static QR.type(optional, string, default: "url"): Content payload type (url,vcard,whatsapp,location).folderId(optional, string): Assigns the QR code to an existing campaign folder.design(optional, object): Color and styling configuration (fgColor,bgColor,dotType,cornerSquareType,brandingMode).
Example 1: Create Dynamic Trackable QR (cURL)
curl -X POST "https://qrnaly.com/api/v1/qr" \
-H "Authorization: Bearer qrs_live_your_api_key_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: req_summer_promo_001" \
-d '{
"name": "Summer Festival Billboard",
"targetUrl": "https://example.com/summer-pass",
"isDynamic": true,
"design": {
"fgColor": "#0f172a",
"bgColor": "#ffffff"
}
}'Example 2: Create Pure Static QR (cURL)
curl -X POST "https://qrnaly.com/api/v1/qr" \
-H "Authorization: Bearer qrs_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "Direct Guest WiFi QR",
"targetUrl": "WIFI:S:GuestNetwork;T:WPA;P:Secret123;;",
"isDynamic": false,
"design": {
"fgColor": "#1e293b",
"bgColor": "#ffffff"
}
}'TypeScript / Node.js Example
const response = await fetch('https://qrnaly.com/api/v1/qr', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.QRNALY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': 'req_order_8821'
},
body: JSON.stringify({
name: 'Order Confirmation #8821',
targetUrl: 'https://myshop.com/orders/8821',
isDynamic: true
})
});
const { data } = await response.json();
console.log('Shortlink URL:', data.scanUrl);
console.log('SVG QR:', data.svg);Python Example
import requests
url = "https://qrnaly.com/api/v1/qr"
headers = {
"Authorization": "Bearer qrs_live_your_api_key_here",
"Content-Type": "application/json"
}
payload = {
"name": "Warehouse Shelf B12",
"targetUrl": "https://erp.internal/bins/B12",
"isDynamic": True
}
res = requests.post(url, json=payload, headers=headers)
print("Created QR:", res.json()["data"]["scanUrl"])Successful Response (HTTP 201)
{
"data": {
"id": "qr_01j8m4k8...",
"workspaceId": "ws_01j8m1...",
"slug": "summer-promo",
"name": "Summer Festival Billboard",
"type": "url",
"targetUrl": "https://example.com/summer-pass",
"status": "active",
"lifecycleStatus": "active",
"scanCount": 0,
"isDynamic": true,
"scanUrl": "https://qrnaly.com/q/summer-promo",
"design": { "fgColor": "#0f172a", "bgColor": "#ffffff" },
"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" ...>...</svg>",
"createdAt": "2026-10-06T10:00:00.000Z",
"updatedAt": "2026-10-06T10:00:00.000Z"
},
"creditsDeducted": 1,
"balance": {
"remaining": 49,
"limit": 50
}
}Common Error Responses
HTTP 400 Bad Request(BAD_REQUEST):targetUrlis missing or fails URL security validation.HTTP 402 Payment Required(INSUFFICIENT_CREDITS): Workspace has 0 remaining dynamic capacity.HTTP 403 Forbidden(ACTIVE_LIMIT_REACHED): Workspace concurrency cap reached (50 on Pro, 500 on Business).
/api/v1/qr/:idGet QR Code by ID or Slug
Retrieves the complete configuration, design settings, routing target, and lifecycle status for a single QR code.
qr:read:id (UUID or slug)Example cURL
curl -X GET "https://qrnaly.com/api/v1/qr/qr_01j8m4k8" \ -H "Authorization: Bearer qrs_live_your_api_key_here"
Successful Response (HTTP 200)
{
"data": {
"id": "qr_01j8m4k8",
"workspaceId": "ws_01j8m1...",
"slug": "summer-festival",
"name": "Summer Festival Billboard",
"type": "url",
"folderId": "fol_01j8m2...",
"targetUrl": "https://example.com/summer-pass",
"status": "active",
"lifecycleStatus": "active",
"scanCount": 142,
"isDynamic": true,
"scanUrl": "https://qrnaly.com/q/summer-festival",
"design": { "fgColor": "#0f172a", "bgColor": "#ffffff" },
"createdAt": "2026-09-10T12:00:00.000Z",
"updatedAt": "2026-09-12T14:30:00.000Z"
}
}/api/v1/qr/:idUpdate QR Code Destination & Metadata
Updates the destination URL without changing the printed QR code. Also allows updating name, folder assignment, or styling parameters.
qr:writetargetUrl consumes 1 Dynamic Update. Other fields consume 0.targetUrl on a Static QR returns HTTP 400 (STATIC_QR_IMMUTABLE).Example cURL
curl -X PATCH "https://qrnaly.com/api/v1/qr/qr_01j8m4k8" \
-H "Authorization: Bearer qrs_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "Summer Festival Autumn Extension",
"targetUrl": "https://example.com/autumn-pass",
"folderId": "fol_01j8m2..."
}'Successful Response (HTTP 200)
{
"data": {
"id": "qr_01j8m4k8",
"name": "Summer Festival Autumn Extension",
"targetUrl": "https://example.com/autumn-pass",
"status": "active",
"updatedAt": "2026-10-06T10:15:00.000Z"
}
}/api/v1/qr/:idDelete QR Code
Soft-deletes the QR record and releases dynamic capacity back to the workspace. Scans to the shortlink will receive HTTP 404.
Example cURL
curl -X DELETE "https://qrnaly.com/api/v1/qr/qr_01j8m4k8" \ -H "Authorization: Bearer qrs_live_your_api_key_here"
/api/v1/qr/:id/pausePause QR Code
Halts public redirects for a dynamic QR code. Scanners are presented with a pause landing page. Consumes 0 Dynamic Updates.
curl -X POST "https://qrnaly.com/api/v1/qr/qr_01j8m4k8/pause" \ -H "Authorization: Bearer qrs_live_your_api_key_here"
/api/v1/qr/:id/resumeResume QR Code
Restores active redirection for a previously paused dynamic QR code. Consumes 0 Dynamic Updates.
curl -X POST "https://qrnaly.com/api/v1/qr/qr_01j8m4k8/resume" \ -H "Authorization: Bearer qrs_live_your_api_key_here"
/api/v1/qr/:id/duplicateDuplicate QR Code
Deep-clones the design palette, destination URL, and folder assignment into a new independent record named {Name} - Copy. Dynamic duplicates consume 1 dynamic slot.
curl -X POST "https://qrnaly.com/api/v1/qr/qr_01j8m4k8/duplicate" \ -H "Authorization: Bearer qrs_live_your_api_key_here"
/api/v1/qr/:id/historyList Destination History
Provides an audit log of all destination URL updates, version numbers, change reasons, and timestamps for a dynamic QR code.
curl -X GET "https://qrnaly.com/api/v1/qr/qr_01j8m4k8/history" \ -H "Authorization: Bearer qrs_live_your_api_key_here"
Successful Response (HTTP 200)
{
"data": [
{
"versionNumber": 2,
"destinationUrl": "https://example.com/autumn-pass",
"changeReason": "API destination update",
"createdAt": "2026-10-06T10:15:00.000Z"
},
{
"versionNumber": 1,
"destinationUrl": "https://example.com/summer-pass",
"changeReason": "Initial destination",
"createdAt": "2026-09-10T12:00:00.000Z"
}
]
}/api/v1/qr/:id/history/restoreRestore Destination Version
Rolls back the active destination URL to a previously recorded version number. Consumes 1 Dynamic Update.
curl -X POST "https://qrnaly.com/api/v1/qr/qr_01j8m4k8/history/restore" \
-H "Authorization: Bearer qrs_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"versionNumber": 1
}'Explore Complementary APIs
Combine QR codes with digital menus, campaign folders, and privacy-preserving scan telemetry.