Business Plan β Complete Guide
Everything you need to use every Business plan feature. From API keys to white-label β step-by-step.
Business Plan Overview
The Business plan unlocks the full Unqode SmartQR platform β from developer APIs and webhooks to white-labelled scan pages and geo-targeted redirects. This guide covers every feature and how to activate it.
API Access
The Unqode SmartQR REST API lets you create, update, delete, and fetch analytics for QR codes from any application or script. API access is exclusively available on the Business plan.
Step 1 β Generate an API key
Go to Dashboard β Settings β API Keys. Click Generate, give the key a name (e.g. "Zapier", "My App"), and copy the key immediately β it is shown only once.
Step 2 β Authenticate your requests
Pass your API key in the X-API-Key header on every request.
curl -X GET \ "https://brrtnzrdqgpmddvvppql.supabase.co/functions/v1/make-server-d9709a44/api/v1/qrcodes" \ -H "X-API-Key: qrk_your_key_here"
Rate limits
Business plan API keys are rate-limited to 120 requests per minute. If you exceed this, you'll receive a 429 Too Many Requests response with a Retry-After: 60 header.
Endpoints
/api/v1/qrcodesList all QR codes on your account.
Response
{ "data": [{ "id": "...", "name": "Summer Menu", "type": "url",
"shortCode": "summer-menu", "active": true,
"totalScans": 1247, "createdAt": "2026-05-12T10:30:00Z" }] }/api/v1/qrcodes/:idFetch a single QR code including full analytics.
Response
{ "data": { "id": "...", "name": "Summer Menu", "content": "https://example.com/menu",
"totalScans": 1247, "uniqueScans": 982, "scansByDay": [...] } }/api/v1/qrcodesCreate a new QR code.
Request body
{ "name": "New QR", "type": "url", "content": "https://example.com" }Response
{ "data": { "id": "...", "shortCode": "new-qr-a1b2c3", "active": true } }/api/v1/qrcodes/:idUpdate name, content, active status, or tags.
Request body
{ "content": "https://example.com/new-page", "active": true }Response
{ "data": { "id": "...", "updatedAt": "2026-07-05T10:00:00Z" } }/api/v1/qrcodes/:idPermanently delete a QR code.
Response
{ "data": { "deleted": true, "id": "..." } }/api/v1/analytics/:idGet full scan analytics for a QR code.
Response
{ "data": { "totalScans": 1247, "uniqueScans": 982,
"scansByDay": [...], "scansByCountry": [...],
"scansByDevice": [...], "scansByBrowser": [...] } }Full working example
// Node.js / JavaScript
const API_KEY = "qrk_your_key_here";
const BASE = "https://brrtnzrdqgpmddvvppql.supabase.co/functions/v1/make-server-d9709a44";
// Create a QR code
const res = await fetch(`${BASE}/api/v1/qrcodes`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": API_KEY,
},
body: JSON.stringify({
name: "Product Page",
type: "url",
content: "https://yoursite.com/product",
}),
});
const { data } = await res.json();
console.log("Created:", data.id, data.shortCode);
// Update its destination
await fetch(`${BASE}/api/v1/qrcodes/${data.id}`, {
method: "PATCH",
headers: { "Content-Type": "application/json", "X-API-Key": API_KEY },
body: JSON.stringify({ content: "https://yoursite.com/new-product" }),
});# Python
import requests
API_KEY = "qrk_your_key_here"
BASE = "https://brrtnzrdqgpmddvvppql.supabase.co/functions/v1/make-server-d9709a44"
HEADERS = {"X-API-Key": API_KEY, "Content-Type": "application/json"}
# List all QR codes
r = requests.get(f"{BASE}/api/v1/qrcodes", headers=HEADERS)
for qr in r.json()["data"]:
print(qr["name"], qr["totalScans"])
# Get analytics
r = requests.get(f"{BASE}/api/v1/analytics/YOUR_QR_ID", headers=HEADERS)
print(r.json()["data"]["totalScans"])Webhooks
Webhooks send a signed HTTP POST request to your server every time one of your QR codes is scanned. Use them to trigger fulfilment, update CRMs, log data to your own database, or fire any custom automation.
Setting up a webhook
- Go to Dashboard β Settings β Notifications.
- Paste your endpoint URL in the Webhook URL field (must be HTTPS).
- Click Save. A signing secret is automatically generated and shown in the Signing Secret box below.
- Copy the signing secret β you'll need it to verify incoming payloads.
2xx status within 10 seconds. Failed deliveries are retried up to 3 times with exponential backoff (0 s, 2 s, 8 s).Payload format
{
"event": "scan",
"qrId": "a1b2c3d4-...",
"shortCode": "summer-menu",
"qrName": "Summer Menu",
"type": "url",
"device": "iOS",
"os": "iOS 17.4",
"browser": "Safari",
"country": "United Kingdom",
"city": "London",
"isUnique": true,
"timestamp": "2026-07-05T14:23:11.000Z"
}Verifying the signature
Every webhook includes an X-Unqode-Signature header with the format t=<timestamp>,v1=<hex_signature>.
The signature is HMAC-SHA256(secret, "{t}.{rawBody}"). Verify it on your server to reject forged requests.
// Node.js β Express webhook handler
const crypto = require("crypto");
app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => {
const sig = req.headers["x-unqode-signature"] || "";
const [tPart, v1Part] = sig.split(",");
const t = tPart?.split("=")[1];
const v1 = v1Part?.split("=")[1];
const secret = process.env.WEBHOOK_SECRET; // your signing secret
const expected = crypto
.createHmac("sha256", secret)
.update(`${t}.${req.body}`)
.digest("hex");
if (expected !== v1) {
return res.status(401).send("Invalid signature");
}
// Signature valid β process the event
const event = JSON.parse(req.body);
console.log("Scan received:", event.qrName, "from", event.country);
res.sendStatus(200);
});# Python β Flask webhook handler
import hmac, hashlib, os
from flask import Flask, request, abort
app = Flask(__name__)
@app.route("/webhook", methods=["POST"])
def webhook():
sig_header = request.headers.get("X-Unqode-Signature", "")
parts = dict(p.split("=", 1) for p in sig_header.split(","))
t, v1 = parts.get("t"), parts.get("v1")
secret = os.environ["WEBHOOK_SECRET"].encode()
expected = hmac.new(secret, f"{t}.{request.data.decode()}".encode(),
hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, v1 or ""):
abort(401)
event = request.get_json(force=True)
print("Scan:", event["qrName"], "from", event["country"])
return "", 200Rotating your signing secret
If your secret is ever compromised, go to Settings β Notifications β Signing secret β Rotate. A new secret is generated immediately. Update your server before rotating β old signatures stop being valid right away.
Geo-targeting
Geo-targeting lets you redirect scanners to different URLs based on the country they're scanning from. This is ideal for multi-region campaigns, localised landing pages, or country-specific pricing.
How it works
- Open a QR code of type Website URL.
- Scroll to the Geo-targeting section.
- Add rules: choose a country and enter the destination URL for that country.
- Set a Fallback URL β this is used for countries without a specific rule.
- Save. Changes take effect immediately.
Example use cases
Rule priority
Rules are matched top-to-bottom. The first matching country rule wins. Visitors from countries without a rule are sent to the Fallback URL. If no fallback is set, they go to the main QR URL.
Retargeting Pixels
Add Facebook, Google, or TikTok pixels to any QR code. When someone scans the code, the pixel fires before they're redirected β adding them to your ad retargeting audience automatically.
Facebook Pixel
- Go to Facebook Events Manager and copy your Pixel ID.
- In QR code editor β Retargeting Pixels β Add pixel β select Facebook.
- Paste your Pixel ID and save.
The pixel fires a PageView event on every scan. You can then create Custom Audiences in Ads Manager based on this traffic.
Google Analytics (GA4)
- In Google Analytics 4, go to Admin β Data Streams β copy your Measurement ID (starts with
G-). - In QR code editor β Retargeting Pixels β Add pixel β select Google.
- Paste the Measurement ID (e.g.
G-XXXXXXXXXX) and save.
TikTok Pixel
- In TikTok Ads Manager β Assets β Events β Web Events β copy your Pixel ID.
- Add pixel β select TikTok β paste Pixel ID β save.
How the redirect works with pixels
When a pixel is attached to a URL QR code, the scan sequence is:
The intermediate page loads and fires the pixel, then immediately redirects via JavaScript. The user sees no visible delay.
White-label
Remove all Unqode SmartQR branding from your scan pages and replace it with your own brand identity. This applies to Landing Page, Coupon, and Feedback QR types β any type that renders a hosted HTML page.
What you can customise
Setup
Go to Dashboard β Settings β White-label. Fill in your brand details and click Save White-label. A live preview is shown at the bottom of the page before you save.
Custom Domain
Serve your QR scan links from your own subdomain instead of smartqr.unqode.com. For example: go.yourcompany.com/r/your-code.
Step 1 β Add a CNAME record
In your DNS provider (Cloudflare, Route53, Namecheap, etc.), add the following record:
| Type | Name / Host | Value / Target | TTL |
|---|---|---|---|
| CNAME | go (or qr, scan, linksβ¦) | smartqr.unqode.com | 300 |
Replace go with your preferred subdomain. Apex domains (e.g. yourcompany.com with no subdomain) are not supported β use a subdomain.
Step 2 β Verify DNS propagation
DNS changes take up to 24 hours. Check propagation at dnschecker.org before notifying us.
Step 3 β Notify us to activate
Email hello@unqode.com with:
- Your account email
- Your full custom subdomain (e.g.
go.yourcompany.com) - A screenshot from dnschecker.org showing the CNAME is live
We'll provision an SSL certificate and activate routing β typically within the same business day.
A/B Split URL Testing
Use Smart Routing's random-split rule on a URL QR code to split scanner traffic between two destinations. Use it to test landing pages, offers, or copy β and see which version drives better results.
Setting up an A/B test
- Create (or edit) a Website URL QR code and open its Smart Routing section.
- Add a rule, check Random split β A/B testing, and set the percentage β e.g. 50% sends half of traffic to this rule's URL. Enter your variant URL (URL B).
- Add a second rule with no conditions checked, pointing at your control URL (URL A) β this is the fallback every non-matching scan lands on.
- Save. Each scan independently rolls the dice against your percentage.
Combining with other conditions
Because random split is just another Smart Routing condition, you can combine it with device, country, time, or scan-count rules β e.g. only A/B test iOS visitors, or only during a campaign's active hours.
Bulk Import & Export
Create hundreds of QR codes in one go by uploading a CSV file. You can also export all your QR codes and their scan data to CSV for analysis in Excel, Google Sheets, or any BI tool.
Bulk import via CSV
- Go to Dashboard β QR Codes.
- Click Import CSV in the top-right toolbar.
- Upload a CSV file with the columns below.
- Review the import preview and confirm. Up to 500 QR codes per file.
CSV column reference
| Column | Required | Example | Notes |
|---|---|---|---|
| name | Yes | Summer Promo | Display name for the QR code |
| type | No | url | Defaults to url if omitted |
| content | Yes | https://example.com | The URL or content to encode |
| displayUrl | No | example.com | Human-readable label (shown in dashboard) |
Example CSV
name,type,content,displayUrl Summer Promo,url,https://yoursite.com/summer,yoursite.com/summer Product A QR,url,https://yoursite.com/product-a,yoursite.com/product-a WiFi Guest,wifi,WIFI:T:WPA;S:GuestNetwork;P:password123;;,GuestNetwork Contact Card,vcard,BEGIN:VCARD\nVERSION:3.0\nFN:Jane Smith\nEND:VCARD,Jane Smith
Bulk export
Go to Dashboard β QR Codes, select the QR codes you want to export (or select all), and click Export CSV. The export includes name, type, shortCode, totalScans, uniqueScans, createdAt, and status.
Analytics & Reporting
Business plan accounts have unlimited analytics history β all scan data is retained and queryable with no time window restriction. Free plan is limited to 7 days; Pro to 1 year.
Metrics explained
Accessing analytics via API
Use the GET /api/v1/analytics/:id endpoint to pull raw analytics data into your own dashboards or data warehouse. See the API Access section for authentication details.
Weekly digest emails
Enable Weekly Digest in Settings β Notifications. You can also trigger it manually at any time by clicking Send Weekly Digest Now β useful for sending a report to a stakeholder before your automated schedule runs.
Priority support for Business plan
Business plan users get priority responses β typically within 4 business hours. Include your account email and a description of the issue.