SmartQRCode
Pricing
  1. Home
  2. /For business
  3. /QR code API
  4. /API reference
Version 1.3.0

QR code API reference

Every endpoint, parameter and response. Generated from the specification the API itself is tested against, so it cannot describe something that is not there.

See business plansTalk to us

Create and manage dynamic QR codes, and read their scan analytics.

Authentication

Every request takes a bearer token: Authorization: Bearer sk_live_.... Keys are created in the dashboard under API access and are shown once — we store only a SHA-256 hash, so a lost key is replaced rather than recovered.

Rate limits and quota

Responses carry X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. The limit is a monthly request quota and resets at the start of the next UTC month; X-RateLimit-Limit is the string unlimited on plans with no cap. There is also a short burst limit, which responds 429 with Retry-After in seconds.

Idempotency

POST accepts an Idempotency-Key header. Sending the same key with the same body replays the original response — including its status code — with Idempotent-Replay: true, rather than creating a second code. Sending the same key with a *different* body is a 409: reusing a key for a different request is always a client bug, and replaying the wrong response would hide it.

Keys are remembered for 24 hours. Retries are safe to send without a key too; they simply are not deduplicated.

Retargeting

Changing target_url on a dynamic code is the point of the product: the printed code keeps working and resolves somewhere new. Static and landing-page codes have no single target, so they reject a target_url update with a 409 instead of silently accepting one that could not take effect.

Batches

POST /api/v1/batches creates up to your plan's per-batch limit in one call. It costs one request per 100 rows (minimum one) against the monthly quota. A 201 means every row was processed inside the request; a 202 means the rest is being created in the background, usually within a few minutes. Poll GET /api/v1/batches/{id}, or subscribe to the bulk.completed webhook.

Paging

GET /api/v1/qr-codes accepts offset, and cursor for a walk that stays correct while codes are being created. Pass pagination.next_cursor back as cursor until it is null.

The machine-readable OpenAPI 3.1 document is at GET /api/v1/openapi and needs any valid key. Generate a client from it rather than from this page.

Endpoints

Every response is JSON. Errors carry a single error string, and every endpoint can return 401 for a missing key or 429 when a limit is hit.

get/api/v1/qr-codes

List QR codes

Your codes, newest first, excluding deleted ones. scan_count includes archived scans, so it never shrinks.

Parameters

limitquery · integer
Page size. Values above 100 are clamped to 100.
offsetquery · integer
Ignored when cursor is sent.
cursorquery · string
pagination.next_cursor from the previous page. Stable under concurrent creates, unlike offset, which shifts when a code is added between pages. With a cursor, total counts the codes from this page onwards.
folderquery · string
A folder id or a folder name. none returns only unfiled codes. A name that does not exist is a 400 rather than an empty page, because a singular filter that matches nothing is almost always a typo.
tagquery · string
A tag id or name. Repeat the parameter, or send a comma-separated list, to match codes carrying any of them. Unlike folder, an unknown tag returns an empty page rather than an error — polling for a tag that has not been used yet is legitimate.

Responses

200
A page of QR codes.
400
An unknown folder, or a `cursor` this API did not issue.
401
Missing or invalid API key.
403
API access is part of the Business plans (`code: business_plan_required`), or the plan does not include this feature.
429
Monthly quota or burst limit exceeded.
500
Server error.
post/api/v1/qr-codes

Create a dynamic QR code

Creates a redirect code. Send Idempotency-Key to make a retry safe. Codes created here are always dynamic redirects: a landing-page type needs content this endpoint does not accept yet, and defaulting to one would produce a code that scans to an empty page.

Headers and parameters

Idempotency-Keyheader · string
An opaque value you generate per logical create. A repeat with the same body replays the first response; a repeat with a different body is a 409.

Request body

target_urlstring · required
Required. Must be http or https.
namestring · optional
A label for your own reference.
campaign_typestring · optional
domain_idstring · optional
Optional. One of your verified custom domains, from the Domains page. Omit for the platform domain. A domain that is not yours, or not yet verified, is rejected with 400 rather than silently replaced — the hostname is baked into the printed image.
folderstring or null · optional
Optional. A folder id, or a folder name — a name that does not exist yet is created, so the first code of a campaign can bring the campaign into being in one call. Applied after the code is created, so a folder problem costs you the label and not the code.
tagsarray · optional
Optional. Tag ids or names; unknown names are created. Up to 20 per code.

Responses

201
Created.
400
Missing or invalid `target_url`, an unknown or unverified `domain_id`, malformed JSON, or an over-long idempotency key.
401
Missing or invalid API key.
403
The plan's QR code limit has been reached (with `limit` and `used`), or API access is not on this plan (`code: business_plan_required`).
409
This `Idempotency-Key` was used with a different body, or a request with it is still in flight.
429
Monthly quota or burst limit exceeded.
503
A short code could not be allocated, or idempotency could not be guaranteed. Retry.
get/api/v1/qr-codes/{id}

Retrieve a QR code

Responses

200
The QR code.
401
Missing or invalid API key.
404
No such code on this account.
429
Monthly quota or burst limit exceeded.
patch/api/v1/qr-codes/{id}

Update a QR code

Retarget, rename, pause, refile or retag. Send only the fields you want to change; omitted fields are left alone. At least one recognised field is required.

Request body

target_urlstring · optional
Only valid on codes that have a target. Static and landing-page codes return 409.
namestring or null · optional
pausedboolean · optional
A paused code resolves to a 'paused' page instead of its target.
folderstring or null · optional
A folder id or name; an unknown name is created. Explicit null unfiles the code. Omitting the field leaves its folder alone — the distinction between null and absent is honoured.
tagsarray · optional
Replaces the code's tags with exactly this set, so [] removes them all. Unknown names are created.

Responses

200
The updated QR code.
400
A field had the wrong type, or no recognised field was supplied.
401
Missing or invalid API key.
404
No such code on this account.
409
This code type has no target to change.
429
Monthly quota or burst limit exceeded.
delete/api/v1/qr-codes/{id}

Delete a QR code

A soft delete: the code stops resolving and scans of the printed code reach a 'no longer active' page. Its scan history is retained and it can be restored from the dashboard.

Responses

200
Deleted.
401
Missing or invalid API key.
404
No such code on this account.
429
Monthly quota or burst limit exceeded.
get/api/v1/qr-codes/{id}/analytics

Scan analytics for a QR code

total_scans is the code's lifetime total including archived scans. The breakdowns cover the requested window only — the two are different periods on purpose, and labelled as such.

Parameters

periodquery · integer
Window in days for the breakdowns.

Responses

200
Scan analytics.
401
Missing or invalid API key.
404
No such code on this account.
429
Monthly quota or burst limit exceeded.
500
Server error.
get/api/v1/qr-codes/{id}/image

Download a QR code image

The code as a PNG or SVG, encoding exactly what the dashboard's image encodes — the scan URL on the code's own domain, or the payload itself for a static (Wi-Fi) code. Square modules in the code's own colours, error correction M, two-module quiet zone. The dashboard's styled rendering (rounded dots, logos, frames) is drawn in the browser and is not reproduced here.

Parameters

formatquery · string
sizequery · integer
PNG width and height in pixels; clamped to the range. Ignored for SVG.

Responses

200
The image.
400
`format` is not png or svg.
401
Missing or invalid API key.
403
API access is part of the Business plans (`code: business_plan_required`), or the plan does not include this feature.
404
No such code on this account.
409
The code has nothing to encode.
429
Monthly quota or burst limit exceeded.
503
The code's custom domain could not be resolved. Retry.
get/api/v1/batches

List batches

Your batches, newest first, created from the dashboard or the API.

Parameters

limitquery · integer
offsetquery · integer

Responses

200
A page of batches.
401
Missing or invalid API key.
403
API access is part of the Business plans (`code: business_plan_required`), or the plan does not include this feature.
429
Monthly quota or burst limit exceeded.
500
Server error.
post/api/v1/batches

Create a batch of dynamic QR codes

Stages every row, creates as many as fit in about 20 seconds, and returns. Rows are validated one by one: a bad destination fails that row with a reason and does not fail the batch. Rows past the account's QR code limit are skipped. Costs one request per 100 rows against the monthly quota, at least one.

Headers and parameters

Idempotency-Keyheader · string
As on POST /api/v1/qr-codes: a repeat with the same body replays the first response.

Request body

rowsarray · required
In print order. Also capped by your plan's per-batch limit.
namestring · optional
domain_idstring · optional
Optional. One of your verified custom domains. Every code in the batch is printed on it. A domain that is not yours or not live is a 400, never a silent fall back to the platform domain.
designobject · optional
Optional. foregroundColor and backgroundColor (hex) are what the image endpoint and ZIP use.

Responses

201
Every row was processed inside the request.
202
Accepted; the remaining rows are being created in the background. `Location` points at the batch.
400
Malformed JSON, no rows, or an unknown or unverified `domain_id`.
401
Missing or invalid API key.
403
More rows than the plan's per-batch limit (`batch_limit_exceeded`), the account is at its QR code limit (`qr_limit_reached`), or the plan does not include bulk or API access.
409
This `Idempotency-Key` was used with a different body, or is still in flight.
413
More than 25,000 rows, or a Content-Length over 3,500,000 bytes. Split the rows into sequential batches.
429
Monthly quota or burst limit exceeded.
get/api/v1/batches/{id}

Retrieve a batch and its rows

The batch's counts, and a page of its rows in the order you sent them — each created row with its code id, short code and scan URL. Filter by status to fetch only the failures.

Parameters

idpath · string · required
limitquery · integer
offsetquery · integer
statusquery · string

Responses

200
The batch.
400
An unknown `status` filter.
401
Missing or invalid API key.
403
API access is part of the Business plans (`code: business_plan_required`), or the plan does not include this feature.
404
No such batch on this account.
429
Monthly quota or burst limit exceeded.
get/api/v1/folders

List folders

Your folders, alphabetical, with a live code count on each. There is no create endpoint, deliberately. Folders are created by naming one on a code — POST /api/v1/qr-codes with "folder": "Piccadilly" files the code and brings the folder into existence in a single call — so this route exists for discovery, which is the thing you cannot otherwise do. Renaming and deleting stay in the dashboard: both change a scheme a whole team shares, and neither belongs in a script a cron might run twice.

Responses

200
Your folders.
401
Missing or invalid API key.
429
Monthly quota or burst limit exceeded.
503
Your folders could not be read. Never returned as an empty list, so a sync job cannot mirror a read failure as a deletion.
get/api/v1/tags

List tags

Your tags, alphabetical, with a live code count on each. Read-only for the same reason as folders: a tag is created by naming it on a code.

Responses

200
Your tags.
401
Missing or invalid API key.
429
Monthly quota or burst limit exceeded.
503
Your tags could not be read.
Ready when you are

Keys are created in the dashboard, in about a minute

Business plans include the API, webhooks and a monthly request quota. Tell us the call volume you expect and we will point you at the right tier.

See business plansTalk to us
SmartQRCode

Dynamic QR codes you can edit after printing, with scan analytics on every one. From a single table tent to a warehouse of asset tags. Pay once or subscribe.

Create a QR codeTalk about Business

QR code types

  • Website QR code
  • Menu QR code
  • WiFi QR code
  • PDF QR code
  • Business card QR code
  • WhatsApp QR code
  • Google review QR code
  • Event QR code
  • Location QR code

More QR codes

  • Text QR code
  • Image QR code
  • Video QR code
  • Social media QR code
  • App download QR code
  • Google Form QR code
  • Business profile QR code
  • All QR code types

Features

  • Dynamic QR codes
  • QR codes with tracking
  • QR code with logo
  • Custom QR code design
  • QR codes that never expire
  • One-time payment QR code
  • No-subscription QR codes
  • Unlimited-scan QR codes

Business

  • QR codes for business
  • Bulk QR code generator
  • QR code API
  • QR code webhooks
  • Custom scan domains
  • White label QR codes
  • Team accounts and roles
  • QR code management platform

Solutions

  • Restaurants
  • Retail
  • Events
  • Healthcare
  • Real estate
  • Hotels
  • All use cases

Resources

  • Guides
  • Compare QR generators
  • Static vs dynamic
  • QR code cost
  • Buy a QR code
  • Cheap QR codes
  • Pricing
  • Help centre
  • About us
  • Contact us
GDPR compliantSSL securedPrivacy first
Terms of servicePrivacy policySecurity·© 2026 SmartQRCode

QR Code is a registered trademark of DENSO WAVE INCORPORATED.