A QR code API lets your own software create, change and measure QR codes, so a code can be made the moment an order is placed, a ticket is sold or a product is added — without anybody opening a dashboard. If you are making a handful of codes, the dashboard is quicker. Once codes are a by-product of another system, an API is the only sensible way to make them.

This guide explains what such an API should offer, the choice between rendering a code and creating one, and the requests involved, using the D-QR REST API as the worked example. It is part of the guide to managing QR codes at scale.

Two kinds of endpoint, and why the difference matters

Most QR APIs offer one of two things, and they are not interchangeable.

Render an imageCreate a dynamic code
What the pattern encodesYour content, directlyA short link that redirects to your content
Change it after printingNeverAny time
Scan analyticsNoneEvery scan counted
Something stored on the provider’s sideNothingThe code and its scan history
D-QR endpointPOST /qrcodes/renderPOST /qrcodes

Render when the content will never change and you must not have a third party in the scan path — a Wi-Fi string, a vCard for one event. Create when you want the code to stay correct after it is printed, or you want to know whether it is being scanned. Static vs dynamic QR codes goes into the trade-off.

Authentication

Create an API credential on the developer page of your account. It has a client id and a secret; the secret is shown once. Send both on every request:

X-Client-ID: your-client-id
Authorization: Bearer your-client-secret

Requests are limited to 60 a minute per credential, and every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers so a client can slow down before it meets a 429 rather than after.

Creating a code

curl -X POST https://getdynamicqr.com/api/v1/qrcodes \
  -H "X-Client-ID: $CLIENT_ID" \
  -H "Authorization: Bearer $CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{"name": "Order 10482 – insert card", "qr_type": "url", "destination_url": "https://example.com/welcome?order=10482"}'

The response describes the new code, including its id, its short_url and its scan_url — the address the printed pattern encodes. Website, PDF, video and app codes take a destination_url; content types such as Wi-Fi, vCard, email, SMS and WhatsApp take their fields in a qr_meta object. A design_preset can style the code as it is created, so codes made by a script can wear the same brand as codes made by hand.

Getting the image

GET /qrcodes/{id}/image returns the code as SVG — the format to send to a printer, because it scales to any size without blurring. Store the id beside your own record (the order, the product, the ticket) so you can fetch the artwork again or change the code later.

Re-pointing a code

This is the request that justifies a dynamic code. When the destination changes, send only the field that changed:

curl -X PATCH https://getdynamicqr.com/api/v1/qrcodes/4821 \
  -H "X-Client-ID: $CLIENT_ID" \
  -H "Authorization: Bearer $CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{"destination_url": "https://example.com/recall-notice"}'

Every printed copy follows on its next scan. The same request with "is_active": false pauses a code — useful when a product is withdrawn — and the code can be switched back on later within your plan’s limits.

Many codes at once

POST /qrcodes/bulk takes an items array of up to 100 codes per request, optionally filed into a folder. Every row is validated first; the rows that fail come back with the reason and the rest are created, so one bad address does not cost the batch. It needs the bulk generation feature, which comes with the Pro plan. For a spreadsheet rather than a system, the bulk QR code generator does the same from a CSV upload.

Reading scans

GET /qrcodes/{id}/analytics returns the scan trend, devices, operating systems and top countries for a period, and GET /qrcodes/{id}/scans pages through individual scans. Both count people: link previews, crawlers and monitors are recorded separately and left out — see bot filtering.

If you would rather be told than ask, a code can carry a webhook URL, set in the dashboard on the Pro plan. Each human scan is POSTed to it, signed in an X-Webhook-Signature header (ts=…;h1=…, an HMAC of the timestamp and the body with the code’s own secret), and the last 50 delivery attempts are listed per code for debugging.

Errors worth handling

Where the full reference lives

Every endpoint is described in an OpenAPI 3.1 document at /api/v1/public/openapi.json, readable without credentials so your tooling can generate a client before you have integrated anything, and a Postman collection can be downloaded from the developer page. The API comes with the Pro plan.

Prefer to ask in a sentence than write a request? The same account can be driven by an AI assistant over MCP.