Product Passport API reference
Create, update and publish structured product passports with stable public URLs. Supporting QR-image and campaign-link utilities remain available for labels and marketing uses.
Building a product catalogue? Start with the Product Passport API. The QR endpoints below are optional supporting utilities.
Product passport API
Authenticated accounts can create and maintain textile product passports through the same API. Send the account API key as X-API-Key or Authorization: Bearer ….
Lists the account catalogue. Every item includes its stable public URL and a weighted readiness object with score, status and missing information.
Creates a textile model, batch or item passport. Core fields cover identity, composition, origin, facilities, responsible operators, lifecycle information and product classification.
{
"category": "textile",
"passport_level": "model",
"product_name": "Organic cotton overshirt",
"brand": "North Studio",
"sku": "NS-OC-01",
"materials": "80% organic cotton; 20% recycled cotton",
"origin_country": "Portugal",
"manufacturer": "Example Manufacturer",
"responsible_operator": "North Studio Europe Ltd.",
"care_instructions": "Wash at 30°C; line dry",
"published": true
}
Lists evidence attached to a passport. Upload with a multipart POST to the same endpoint using title, evidence_type, optional issuer/date metadata, and either file or source_url.
Readiness scores identify missing information; they are not legal certification. Requirements remain specific to the product category, delegated act and market role.
Supporting QR API 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 supporting 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=123b28&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 campaign link
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 an integration? Use the passport endpoints for catalogue records and stable public pages; the supporting endpoints can generate branded QR images and trackable campaign links.