QR API

qr.ignlab.net/docs
← Back to the tool

QR API reference

A small REST API to generate QR images and create dynamic, trackable QR codes. No account or API key required — dynamic codes are secured by a per-code management token returned when you create them.

Basics QR image Create dynamic Read + analytics Update Delete Health Errors

Basics

Base URL: https://qr.ignlab.net

Generate a QR image

GET/api/qr

Returns a scalable SVG QR code. No token needed — great for embedding directly in an <img> tag (works in email, AMP and no-JS pages).

ParamDefaultDescription
data requiredThe text/URL to encode (max ~900 bytes).
eccMError correction level: L, M, Q, H.
fg000000Foreground color, 6-digit hex (no #).
bgffffffBackground color, 6-digit hex.
scale8Pixels per module (1–40). SVG scales, so this mainly sets the intrinsic size.
margin4Quiet-zone width in modules (0–20).

Embed it directly:

<img src="https://qr.ignlab.net/api/qr?data=https://ignlab.net/&fg=6c63ff&ecc=H"
     width="240" height="240" alt="QR code">
Live example QR pointing at these docs

Live example
This QR is served by the endpoint above and points back to this page — scan it.

Create a dynamic code

POST/api/links

Creates a permanent short link (/r/CODE) you can point a printed QR at, then repoint and track later. Encode the returned short_url into your QR image.

Body (JSON):

FieldDefaultDescription
target requiredDestination URL (must start with http:// or https://).
titlePrivate label to help you recognise the code.
curl -X POST https://qr.ignlab.net/api/links \
  -H "Content-Type: application/json" \
  -d '{"target":"https://ignlab.net/","title":"Spring poster"}'

201 Response:

{
  "code": "AbCd12",
  "token": "0f9a...c1",                       // keep this secret
  "short_url": "https://qr.ignlab.net/r/AbCd12",
  "manage_url": "https://qr.ignlab.net/manage/#AbCd12:0f9a...c1",
  "target": "https://ignlab.net/",
  "title": "Spring poster"
}

Pair this with the image endpoint: /api/qr?data=<short_url>. The printed QR never changes; you change where it points.

Read a code + analytics

GET/api/links/{code}?token={token}

Returns the code's current target plus scan analytics.

curl "https://qr.ignlab.net/api/links/AbCd12?token=0f9a...c1"
{
  "code": "AbCd12",
  "target": "https://ignlab.net/",
  "title": "Spring poster",
  "active": true,
  "scan_count": 42,
  "short_url": "https://qr.ignlab.net/r/AbCd12",
  "created_at": "2026-07-03 07:00:17",
  "updated_at": "2026-07-03 09:12:00",
  "analytics": {
    "daily":   [ { "d": "2026-07-03", "n": 42 } ],   // last 30 days
    "devices": [ { "device": "mobile", "n": 30 }, { "device": "desktop", "n": 12 } ],
    "recent":  [ { "ts": "2026-07-03 09:12:00", "device": "mobile", "referer": null } ]
  }
}

Update a code

POST/api/links/{code}

Change the destination, label, or enable/disable the code. Send the token in the body.

FieldDescription
token requiredThe management token for this code.
targetNew destination URL.
titleNew private label.
activetrue/false — disable to make the code return "inactive".
curl -X POST https://qr.ignlab.net/api/links/AbCd12 \
  -H "Content-Type: application/json" \
  -d '{"token":"0f9a...c1","target":"https://ignlab.net/pricing"}'

Responds with the same shape as Read (including refreshed analytics).

Delete a code

DELETE/api/links/{code}?token={token}

Permanently deletes the code and its scan history. The short link stops working.

curl -X DELETE "https://qr.ignlab.net/api/links/AbCd12?token=0f9a...c1"
{ "deleted": true, "code": "AbCd12" }

Health check

GET/api/health
{ "ok": true, "time": "2026-07-03T07:00:17+00:00" }

Errors

Errors return a JSON body with an error code and appropriate HTTP status:

StatuserrorMeaning
400Missing/oversized data on /api/qr.
401unauthorizedWrong or missing token.
404not_foundUnknown code or route.
422invalid_targetTarget is not a valid http(s) URL.
429rate_limitedMore than 60 links created from your IP in an hour.
500server_errorUnexpected error.

Building a WordPress or Shopify integration? These endpoints already power the official IgnLab plugins — grab them instead of starting from scratch.