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
Base URL: https://qr.ignlab.net
- All responses are JSON except
/api/qr, which returns an SVG image. - CORS is open (
Access-Control-Allow-Origin: *), so you can call it from the browser. - Auth model: creating a dynamic code is open (rate-limited to 60 per hour per IP). Reading analytics, updating, and deleting require the
tokenreturned at creation. Keep it secret — it's the only key to a code. - Scanner IP addresses are hashed, never stored in the clear.
Generate a QR image
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).
| Param | Default | Description |
|---|---|---|
| data required | — | The text/URL to encode (max ~900 bytes). |
| ecc | M | Error correction level: L, M, Q, H. |
| fg | 000000 | Foreground color, 6-digit hex (no #). |
| bg | ffffff | Background color, 6-digit hex. |
| scale | 8 | Pixels per module (1–40). SVG scales, so this mainly sets the intrinsic size. |
| margin | 4 | Quiet-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
This QR is served by the endpoint above and points back to this page — scan it.
Create a dynamic code
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):
| Field | Default | Description |
|---|---|---|
| target required | — | Destination URL (must start with http:// or https://). |
| title | — | Private 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
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
Change the destination, label, or enable/disable the code. Send the token in the body.
| Field | Description |
|---|---|
| token required | The management token for this code. |
| target | New destination URL. |
| title | New private label. |
| active | true/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
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
{ "ok": true, "time": "2026-07-03T07:00:17+00:00" }
Errors
Errors return a JSON body with an error code and appropriate HTTP status:
| Status | error | Meaning |
|---|---|---|
| 400 | — | Missing/oversized data on /api/qr. |
| 401 | unauthorized | Wrong or missing token. |
| 404 | not_found | Unknown code or route. |
| 422 | invalid_target | Target is not a valid http(s) URL. |
| 429 | rate_limited | More than 60 links created from your IP in an hour. |
| 500 | server_error | Unexpected error. |
Building a WordPress or Shopify integration? These endpoints already power the official IgnLab plugins — grab them instead of starting from scratch.