QUICKCHART DYNAMIC QR API

Create once. Update anytime.

Create a permanent scan link, turn it into a QR image, and change the destination without reprinting. All existing QuickChart API keys have access.

Create a code

Send your existing key in the Authorization header. Keep it on your server.

curl https://qr.quickchart.io/api/codes \
  -H "Authorization: Bearer $QUICKCHART_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Summer menu",
    "targetUrl": "https://example.com/menu",
    "campaign": "Summer 2026",
    "tags": ["menu", "in-store"],
    "externalId": "menu-2026",
    "appearance": {"size": 512, "dark": "175e35", "light": "ffffff"}
  }'

A successful response returns HTTP 201 and {"success":true,"code":{...}}. The code includes its id, scanUrl, imageUrl, destination, appearance, tags, timestamps, and status. Print the image containing scanUrl. Linking directly to the destination produces a static code.

Manage codes

Method Endpoint Purpose
GET /api/codes List your codes
POST /api/codes Create a code
GET /api/codes/:id Read a code
PATCH /api/codes/:id Update destination, name, appearance, tags, campaign, or external ID
GET /api/codes/:id/image?format=svg Download PNG or SVG
POST /api/codes/:id/pause Stop redirects temporarily
POST /api/codes/:id/activate Resume redirects
POST /api/codes/:id/archive Hide from the main list; keep redirects
POST /api/codes/:id/restore Restore an archived code to the main list
DELETE /api/codes/:id Permanently disable a code; cannot be undone
curl -X PATCH https://qr.quickchart.io/api/codes/CODE_ID \
  -H "Authorization: Bearer $QUICKCHART_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"targetUrl":"https://example.com/new-menu"}'

Destinations must be public HTTP or HTTPS URLs, at most 4,096 characters after URL encoding. Updates take effect on subsequent scans. Redirect responses are never cached. Codes do not expire automatically when a subscription ends. Pausing, deleting, or an abuse takedown can stop a code.

The account limit is one million undeleted codes; archived and paused codes count. An externalId must be unique within your account, including previously deleted codes. After an uncertain create response, search for that external ID before retrying.

List and search

Supported query parameters: q (name, destination, external ID, or code ID), status=active|paused, campaign, tag, archived=true, and limit (1–100, default 25). Pass the returned nextCursor as cursor for another page. A null cursor means the end.

Appearance

Images use the existing QuickChart QR renderer. Store renderer options in appearance: size, margin, dark/light colors, error correction, logo URL and size, caption options, dot styles, and finder styles/colors. Use centerImageUrl for a public logo URL. Size must be 100–3000 pixels. PNG and SVG downloads use the same saved options. Codes with a logo must use PNG; the renderer does not support embedded logos in SVG. Replacing appearance replaces the saved options; changing the destination leaves them intact. Always scan-test before printing.

Scan analytics

curl 'https://qr.quickchart.io/api/analytics?days=30&codeId=CODE_ID' \
  -H "Authorization: Bearer $QUICKCHART_API_KEY"

Use days=1|7|30|60 (default 7). Omit codeId for account totals. Optional filters: campaign, tag, includeBots=true. Add format=csv for export. Campaign and tag filters reflect the labels at scan time.

Results include total scans, observed daily unique scans, scans by UTC day, last scan, top codes, and country/region/city, device, browser, operating system, referrer, and destination-host breakdowns. Previous-period comparison is available for windows up to 30 days; the total history window is 60 days.

A scan is a visit to the redirect link. Opening the link directly also counts; generating or downloading an image does not. Known bots are excluded by default, but bot detection is imperfect. Counts may be sampled and delayed. Daily unique scans count observed devices per code per UTC day; they are not a count of distinct people across codes or days. When summary.sampled is true, dailyUniqueScans counts only devices observed in the sample and may undercount. Total scans are adjusted for sampling; daily uniques are not extrapolated. The same flag is included in previous. Location is approximate. No tracking cookies or raw scanner IPs are stored. Referrers are reduced to hostnames and destination query strings are omitted from scan analytics.

Errors

Errors return JSON: {"success":false,"error":"..."}. HTTP 400 means invalid input, 401 invalid authentication, 403 denied access, 404 an unavailable code, 409 a conflicting external ID or code limit, 413 an oversized request, and 503 a temporarily unavailable dependency. Retry temporary failures with backoff. Never expose API keys in client-side JavaScript or URLs.

Open the QR dashboard · Contact support