Fundamentals

QR code API: creating and updating dynamic codes programmatically

Paolo Matias Tonello8 min read

Manual generation stops working the moment codes belong to records rather than campaigns. If every new order, asset, tenant or shipment needs its own code, the generator has to live behind an API call in the code path that creates the record.

When you actually need the API

  • One code per database row: orders, assets, rentals, machines, patients' consent forms
  • Multi-tenant products where each customer gets their own tracked code
  • Shipping and logistics labels generated at print time
  • Internal tools that must repoint hundreds of codes when a URL structure changes

If codes are created by a marketing team a handful at a time, the dashboard and the CSV import are faster than any integration. The API earns its place when a machine, not a person, decides that a code should exist.

Authentication and keys

API access is authenticated with a secret key sent as a bearer token. Treat it as a server-side credential: it can create and repoint codes, so it never belongs in browser code, a mobile app bundle or a public repository.

  • Create one key per integration so you can revoke a single consumer
  • Store keys in your secret manager or environment variables, never in source
  • Rotate on staff changes; revocation is immediate
  • Rate limits are per key, so a runaway job cannot starve your other integrations

Creating a dynamic code

A create call takes a name, the destination URL, and optionally the design to apply. It returns the code's id and its short link — that short link is the value you persist next to your record and render or print.

curl -X POST https://www.qreator.tech/api/public/v1/codes \
  -H "Authorization: Bearer $QREATOR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "asset-A1043",
    "target_url": "https://example.com/assets/A1043"
  }'

Updating a destination

Repointing is a single update on the existing code. The short link, the printed artwork and the physical label all stay exactly as they are; only the redirect target changes, and it takes effect on the next scan.

curl -X PATCH https://www.qreator.tech/api/public/v1/codes/$CODE_ID \
  -H "Authorization: Bearer $QREATOR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "target_url": "https://example.com/assets/A1043/manual" }'

This is what makes a URL migration survivable. When your site restructures, a script walks your own records, computes the new URL for each one, and PATCHes every code — thousands of printed labels follow along without a reprint.

Scan webhooks instead of polling

Polling an analytics endpoint to find out whether a code was scanned is wasteful and always late. A webhook pushes each scan to your endpoint as it happens, which is what you need for real-time flows: mark an asset as inspected, notify a rep that a prospect opened the brochure, or trigger a Zapier or Make automation.

  1. Register your endpoint URL and receive a signing secret.
  2. Verify the signature header on every request before trusting the body — an unverified webhook endpoint is a public write API.
  3. Respond 2xx quickly and process asynchronously; slow endpoints get retried.
  4. Make handling idempotent: retries mean the same delivery can arrive twice.

Privacy of what you receive

Scan events carry coarse context — approximate country, device type, referrer, timestamp — deliberately, not raw identifiers. If you enrich those events with your own customer data on arrival, that combination becomes personal data under your own privacy notice, so treat the webhook sink with the same care as any other customer-data pipeline.

Author

Paolo Matias TonelloFounder, Qreator

Founder of MT Digital Services LLC and builder of Qreator. Writes about QR codes, print production and privacy-friendly analytics.

Put it into practice