Help CenterBusiness Documentation

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.

REST API
Manage QR codes programmatically
Webhooks
Real-time scan events to your server
Geo-targeting
Redirect by visitor country
Retargeting Pixels
FB, Google, TikTok pixel support
White-label
Your brand on every scan page
Custom Domain
Your own subdomain for QR links
A/B Testing
Split traffic between two URLs
Bulk Import
Create hundreds of QRs via CSV
πŸ’‘Upgrade any time from Dashboard β†’ Settings β†’ Billing. If you have questions about your plan, email hello@unqode.com.

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.

⚠️Store your API key securely. Anyone with the key has full access to your QR codes. Never commit it to a public Git repository.

Step 2 β€” Authenticate your requests

Pass your API key in the X-API-Key header on every request.

bash
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

GET/api/v1/qrcodes

List 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" }] }
GET/api/v1/qrcodes/:id

Fetch a single QR code including full analytics.

Response

{ "data": { "id": "...", "name": "Summer Menu", "content": "https://example.com/menu",
  "totalScans": 1247, "uniqueScans": 982, "scansByDay": [...] } }
POST/api/v1/qrcodes

Create a new QR code.

Request body

{ "name": "New QR", "type": "url", "content": "https://example.com" }

Response

{ "data": { "id": "...", "shortCode": "new-qr-a1b2c3", "active": true } }
PATCH/api/v1/qrcodes/:id

Update 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" } }
DELETE/api/v1/qrcodes/:id

Permanently delete a QR code.

Response

{ "data": { "deleted": true, "id": "..." } }
GET/api/v1/analytics/:id

Get full scan analytics for a QR code.

Response

{ "data": { "totalScans": 1247, "uniqueScans": 982,
  "scansByDay": [...], "scansByCountry": [...],
  "scansByDevice": [...], "scansByBrowser": [...] } }

Full working example

javascript
// 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
# 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

  1. Go to Dashboard β†’ Settings β†’ Notifications.
  2. Paste your endpoint URL in the Webhook URL field (must be HTTPS).
  3. Click Save. A signing secret is automatically generated and shown in the Signing Secret box below.
  4. Copy the signing secret β€” you'll need it to verify incoming payloads.
ℹ️Webhooks are only delivered for Business plan accounts. Your endpoint must respond with a 2xx status within 10 seconds. Failed deliveries are retried up to 3 times with exponential backoff (0 s, 2 s, 8 s).

Payload format

json
{
  "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.

javascript
// 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
# 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 "", 200

Rotating 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

  1. Open a QR code of type Website URL.
  2. Scroll to the Geo-targeting section.
  3. Add rules: choose a country and enter the destination URL for that country.
  4. Set a Fallback URL β€” this is used for countries without a specific rule.
  5. Save. Changes take effect immediately.
ℹ️Country detection is based on the scanner's IP address using a real-time geolocation lookup. Accuracy is typically 95%+ at country level. VPN users may be geolocated to the VPN server's country.

Example use cases

Restaurant chain β€” UK visitors β†’ uk.restaurant.com, US visitors β†’ us.restaurant.com
E-commerce β€” EU visitors β†’ GDPR-compliant checkout, US visitors β†’ standard checkout
Events β€” Local language pages per country, with English as fallback
Compliance β€” Redirect certain countries to a restricted-access notice page

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.

πŸ’‘Pixels only fire on URL-type QR codes with a direct redirect. They don't fire on HTML page types (Landing Page, Coupon, Feedback) because the pixel script is embedded in those pages natively.

Facebook Pixel

  1. Go to Facebook Events Manager and copy your Pixel ID.
  2. In QR code editor β†’ Retargeting Pixels β†’ Add pixel β†’ select Facebook.
  3. 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)

  1. In Google Analytics 4, go to Admin β†’ Data Streams β†’ copy your Measurement ID (starts with G-).
  2. In QR code editor β†’ Retargeting Pixels β†’ Add pixel β†’ select Google.
  3. Paste the Measurement ID (e.g. G-XXXXXXXXXX) and save.

TikTok Pixel

  1. In TikTok Ads Manager β†’ Assets β†’ Events β†’ Web Events β†’ copy your Pixel ID.
  2. 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:

1QR scanned
2Intermediate page loads
3Pixel fires
4User redirected to destination

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

Brand name
Replaces the QR code name on Landing Page scan pages with your company name.
Brand logo
Your logo appears at the top of Feedback and Landing Page scan pages (max 500 KB, PNG/JPG).
Accent colour
Buttons, links, and highlights on all scan pages use your brand colour.
Hide powered-by badge
Removes the "Powered by Unqode SmartQR" footer from all scan pages.

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.

ℹ️White-label settings apply globally to all your QR codes. You cannot set different branding per QR code β€” it's a single account-wide brand identity.

Custom Domain

Serve your QR scan links from your own subdomain instead of smartqr.unqode.com. For example: go.yourcompany.com/r/your-code.

⚠️Custom domain activation is a manual process handled by our team. Allow 1 business day after you notify us.

Step 1 β€” Add a CNAME record

In your DNS provider (Cloudflare, Route53, Namecheap, etc.), add the following record:

TypeName / HostValue / TargetTTL
CNAMEgo (or qr, scan, links…)smartqr.unqode.com300

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

  1. Create (or edit) a Website URL QR code and open its Smart Routing section.
  2. 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).
  3. 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.
  4. Save. Each scan independently rolls the dice against your percentage.
πŸ’‘The split is determined randomly per scan using the percentage you set. For statistically meaningful results, aim for at least 200 scans per variant before drawing conclusions.

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

  1. Go to Dashboard β†’ QR Codes.
  2. Click Import CSV in the top-right toolbar.
  3. Upload a CSV file with the columns below.
  4. Review the import preview and confirm. Up to 500 QR codes per file.

CSV column reference

ColumnRequiredExampleNotes
nameYesSummer PromoDisplay name for the QR code
typeNourlDefaults to url if omitted
contentYeshttps://example.comThe URL or content to encode
displayUrlNoexample.comHuman-readable label (shown in dashboard)

Example CSV

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

Total scans
Every time a scanner loads the redirect URL, a scan is counted β€” including repeat visits from the same device.
Unique scans
Scans from distinct IP addresses. A single phone scanning the same QR code 10 times counts as 1 unique scan.
Scans by device
Breakdown by Android, iOS, Desktop, and Other β€” detected from the User-Agent header.
Scans by country
Detected via real-time IP geolocation. Includes city-level data where available.
Scans by OS
Operating system and version (iOS 17.4, Android 14, Windows 10, macOS, etc.).
Scans by browser
Chrome, Safari, Firefox, Edge, Samsung Browser, etc.
Scans by hour
UTC hour-of-day distribution across all scans. Useful for identifying peak scan times.
Scans by day of week
Day-of-week distribution across all scans (UTC).

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.

ℹ️Automated weekly digest scheduling runs based on when you enabled the toggle. Manual sends via the button are immediate and do not affect the automatic schedule.

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.