DPP / Label Provider Integration Guide
Step-by-step walkthrough for Digital Product Passport (DPP) providers and label providers who want to retrieve product data, QR codes, supply chain structure, and certificate information from the Retraced Public API.
Is this guide for you?
This guide is for partners who need to work with Retraced product data to power physical or digital label experiences, including:
- Digital Product Passport providers — building or hosting a DPP destination that consumers scan to
- Label providers — printing or encoding Retraced QR codes onto physical garment labels
- QR code integrators — forwarding Retraced QR codes to their own label management or EPC systems
- Partners building their own DPP experience — assembling product, supply chain, material, and certificate data from Retraced to power a custom consumer-facing page
If you need Life Cycle Assessment (LCA) data such as energy sources and per-supplier ESG data points, see the LCA Provider Guide instead.
Setup
BASE_URL="https://publicapi.retraced.com/api/v2"
# API key provided by the brand you are integrating with
API_KEY="your-api-key"
All examples use curl. The API key is passed via the companyapikey header.
Important: If your API key contains
$characters, use single quotes around its value to prevent the shell from interpreting it as a variable:-H 'companyapikey: $2b$10$...' # correct — single quotes -H "companyapikey: $2b$10$..." # wrong — shell expands $2b to empty string → 401
All responses use the standard envelope: { "metadata": { "success": true }, "data": ... }. Errors return metadata.success: false plus a machine-readable code field.
Overview
A typical DPP / label provider workflow involves the following steps:
- Fetch the product — retrieve the style, variant, or SKU you need
- Get the QR code — read
qrCodeUrl(the printable QR image) and check the tracing story is active - Fetch supply chain data — if building your own DPP experience, retrieve facility-level tracing data
- Fetch certificates — retrieve supplier and product certificates
- Fetch material composition — fibre breakdown and countries of origin (mandatory DPP content under ESPR)
- Assemble and cache — compose your DPP page or label payload
The example below uses: Summer Dress 2024 (style style_01KMZMMMW8JA3S1RVX1PS8E19S), one variant in Blue (variant_01KN6YZNVKNBN1TJ4MR9T7FFD0), and one SKU in size S (sku_01KN6Z1JB710ANAN120JH5BBB0).
Step 1 — Fetch the product
The /styles endpoint is unified: it returns styles, variants, and SKUs depending on the level query parameter and the parent filter you provide. Choose the level that matches your use case:
| Level | When to use |
|---|---|
style |
High-level product data — useful when your DPP covers a whole product line |
variant |
Colour / size grouping — useful when labels are per colour-way |
sku |
Individual physical item — recommended for label providers who need exact barcode or EAN matching |
1a. List all styles
curl "$BASE_URL/styles?level=style&page=1&limit=50" \
-H "companyapikey: $API_KEY"
Response (200):
{
"metadata": {
"success": true,
"pagination": { "page": 1, "limit": 50, "total": 7, "totalPages": 1 }
},
"data": [
{
"id": "style_01KMZMMMW8JA3S1RVX1PS8E19S",
"forCompanyId": "G3JITT4AM9L",
"name": "Summer Dress 2024",
"codes": [{ "codeId": "ERP_ID", "codeValue": "DRS-2024-001" }],
"description": "Lightweight summer dress in organic cotton",
"gender": "female",
"styleLevelId": "APPAREL_END_CONSUMER_FINISHED_GOODS",
"styleTypeId": "Y0RL9LGNUWOL9RXB07",
"isStoryActive": true,
"isArchived": false,
"qrCodeUrl": "https://cdn.retraced.com/qr_01KMZMMN2A4B6C8D0E2F4G6H8J.svg",
"weight": null,
"createdAt": "2026-03-30T15:08:48.904Z",
"updatedAt": "2026-03-30T15:08:49.545Z"
}
]
}
STYLE_ID="style_01KMZMMMW8JA3S1RVX1PS8E19S"
1b. List variants for the style
curl "$BASE_URL/styles?level=variant&styleId=$STYLE_ID&page=1&limit=50" \
-H "companyapikey: $API_KEY"
Response (200):
{
"metadata": {
"success": true,
"pagination": { "page": 1, "limit": 50, "total": 1, "totalPages": 1 }
},
"data": [
{
"id": "variant_01KN6YZNVKNBN1TJ4MR9T7FFD0",
"forCompanyId": "G3JITT4AM9L",
"name": "Summer Dress 2024 — Blue",
"codes": [{ "codeId": "ERP_ID", "codeValue": "DRS-2024-001-BLU" }],
"isStoryActive": true,
"isArchived": false,
"qrCodeUrl": "https://cdn.retraced.com/qr_01KN6YZP3K5M7N9P1Q3R5S7T9V.svg",
"weight": null,
"isWeightAvailable": false,
"createdAt": "2026-04-02T11:24:17.139Z",
"updatedAt": "2026-04-02T11:24:39.088Z"
}
]
}
VARIANT_ID="variant_01KN6YZNVKNBN1TJ4MR9T7FFD0"
1c. List SKUs for the variant
curl "$BASE_URL/styles?level=sku&variantId=$VARIANT_ID&page=1&limit=50" \
-H "companyapikey: $API_KEY"
Response (200):
{
"metadata": {
"success": true,
"pagination": { "page": 1, "limit": 50, "total": 7, "totalPages": 1 }
},
"data": [
{
"id": "sku_01KN6Z1JB710ANAN120JH5BBB0",
"forCompanyId": "G3JITT4AM9L",
"name": "Summer Dress 2024 — Blue — S",
"codes": [{ "codeId": "EAN_GTIN_13", "codeValue": "4006381333931" }],
"isStoryActive": true,
"isArchived": false,
"qrCodeUrl": "https://cdn.retraced.com/qr_01KN6Z1JC92R4T6V8W0X2Y4Z6A.svg",
"weight": null,
"isWeightAvailable": false,
"createdAt": "2026-04-02T11:25:19.000Z",
"updatedAt": "2026-04-02T11:25:52.000Z"
}
]
}
Product images: on list queries,
include=imagesreturns photos at variant and SKU level only — style lists ignore it, but every list result carriesfeatureImageUrl(the product's first image). Fetching a single product withGET /styles/{id}returns the fullimagesarray at every level, noincludeneeded. Each image entry carries a CDN URL you can embed in your DPP page.
Step 2 — Get the QR code
Every style, variant, and SKU exposes a qrCodeUrl field:
"qrCodeUrl": "https://cdn.retraced.com/qr_01KN6Z1JC92R4T6V8W0X2Y4Z6A.svg"
qrCodeUrl is the printable QR code image — a publicly accessible SVG hosted on Retraced's CDN. It is the ready-to-print artwork, not the page the consumer lands on.
The QR code itself encodes the Retraced forwarding URL (on the rtrcd.com short domain). When a consumer scans the printed label, that URL redirects them to the consumer-facing DPP page for the product. If you need the encoded destination as a string (e.g. to write it to an NFC tag instead of printing the QR), decode the SVG's QR content with any QR library — do not attempt to construct the destination URL from the image filename, as the URL format is managed by Retraced and can differ per environment and product generation.
The QR is stable once generated. Retraced generates a product's QR code once and does not regenerate it, so
qrCodeUrl(and the destination the QR encodes) stays the same over the product's life — it does not change when the brand later edits supply chain or material data. This makes a fetch-once-and-cache approach safe, and it means you can print the QR before the tracing story is switched on: the printed label keeps working whenisStoryActiveflips totruelater.
How to use it:
| Scenario | What to do |
|---|---|
| Printing physical labels | Place the SVG from qrCodeUrl directly into your label artwork |
| EPC / NFC tags | Decode the QR image and write the encoded URL as the NDEF record URI |
| Digital labels or hang-tags | Embed the SVG and/or link to the decoded destination |
| Building your own DPP experience | Ignore the Retraced QR entirely and generate your own — see Step 3 |
Note:
qrCodeUrlmay benullif no QR code has been generated for the product yet. Also checkisStoryActive: truebefore printing — the QR image can exist while the brand's tracing story is still switched off, in which case the destination shows no meaningful data.
Filter to DPP-ready products
isStoryActive signals that the brand has attached tracing data and activated the consumer-facing story. It is filterable server-side:
curl "$BASE_URL/styles?level=sku&variantId=$VARIANT_ID&isStoryActive=true&page=1&limit=100" \
-H "companyapikey: $API_KEY"
Boolean filters accept
trueorfalse. PassisStoryActive=trueorisStoryActive=falseto filter either way; any other value (e.g.1,yes) is rejected with a400. To get products regardless of story status, omit the parameter entirely.
After filtering, still verify qrCodeUrl is non-null on each item before sending it to print.
Inspect the tracing story (optional)
To see which tracing setup powers the consumer story, request include=tracingStory:
curl "$BASE_URL/styles/$STYLE_ID?include=tracingStory" \
-H "companyapikey: $API_KEY"
The product response then carries a tracingStory object (or null if none is attached):
"tracingStory": {
"id": "trcstory_01KMZMMN5B7C9D1E3F5G7H9J1K",
"tracingType": "SUPPLY_CHAINS",
"tracingId": "supplychain_01KMZMMN6C8D0E2F4G6H8J0K2M",
"isActive": true,
"tracingName": "Summer Dress 2024 — Supply Chain",
"createdAt": "2026-03-30T15:08:49.000Z",
"updatedAt": "2026-03-30T15:08:49.000Z"
}
tracingType tells you what kind of tracing backs the story: SUPPLY_CHAINS, SUPPLY_CHAIN_MAPPINGS, CASCADE_MAPPINGS, TRACING_PURCHASE_ORDERS, or TRACING_SALES_ORDERS. For most DPP integrations you don't need to branch on this — isStoryActive on the product is the go/no-go signal, and Step 4 returns the resolved supply chain regardless of type.
Step 3 — Build your own DPP experience (optional)
If you want to host your own consumer-facing DPP page rather than forwarding consumers to the Retraced-hosted destination, you can assemble the full product experience yourself using:
- Product data from Step 1 (name, codes, description, images, gender, weight)
- Supply chain data from Step 4
- Certificate data from Step 5
- Material composition from Step 6
In this case you generate your own QR code pointing at your DPP destination, and use the Retraced API only as the data source.
Step 4 — Fetch supply chain data
Retrieve the full supplier network for a product. The supply chain endpoint takes a product ID (style, variant, or SKU) and returns all mapped facilities grouped by production process and tier.
If the product you query has no supply chain of its own, the platform automatically falls back to the closest ancestor's active supply chain — so querying a SKU returns the style's chain when the brand mapped at style level. You do not need to retry with the parent ID.
curl "$BASE_URL/supply-chains/$STYLE_ID" \
-H "companyapikey: $API_KEY"
Response (200):
{
"metadata": { "success": true },
"data": {
"productId": "style_01KMZMMMW8JA3S1RVX1PS8E19S",
"productName": "Summer Dress 2024",
"nodesByProductionProcesses": [
{
"productionProcessId": "MANUFACTURING",
"productionProcessName": "Manufacturing",
"tier": "T2",
"nodes": [
{
"tier": "T2",
"companyId": "G3JITT4AM9L",
"companyName": "Developers' CMT & Fabric",
"country": "DK",
"coordinates": { "latitude": 55.681986, "longitude": 12.600743 },
"address": {
"line1": "Ekvipagemestervej 10",
"line2": null,
"city": "København",
"zipCode": "1438",
"country": "DK"
},
"facilityProcesses": ["Cut make trim (CMT)"],
"productionProcess": "Manufacturing"
}
]
},
{
"productionProcessId": "SOURCING_AND_IMPORT",
"productionProcessName": "Sourcing and import",
"tier": "T1",
"nodes": [
{
"tier": "T1",
"companyId": "PZ86G3I3SXB",
"companyName": "Creative Sourcing Co. Ltd.",
"country": "CN",
"coordinates": { "latitude": 31.322372, "longitude": 120.722366 },
"address": {
"line1": "Jiangsu",
"line2": null,
"city": null,
"zipCode": null,
"country": "CN"
},
"facilityProcesses": ["Sourcing agency"],
"productionProcess": "Sourcing and import"
}
]
}
]
}
}
Reading the response:
nodesByProductionProcesses— production process groups, each with atierand a list of facilitynodestier—T1is closest to the finished product, higher numbers are further upstreamcoordinates/address—nullwhen not geo-located / not fully entered; handle both on your map view- An empty
nodesByProductionProcessesarray is a valid 200 — the product (and its ancestors) have no active mapped supply chain. A404 not_foundmeans the product ID itself doesn't exist.
Collect the companyId values — you will need them to match certificates in Step 5:
COMPANY_IDS=("G3JITT4AM9L" "PZ86G3I3SXB")
Step 5 — Fetch certificates
Certificates in Retraced are held at the company level — each certificate belongs to the supplier company that holds it. To find certificates relevant to a product, list the certificates visible to your API key and match them to the supplier companyId values you collected from the supply chain response in Step 4.
Certificate types
| Type | Description |
|---|---|
COMPANY |
Company-level certification (e.g. Fair Trade, SA8000) |
SCOPE |
Scope certificate (e.g. GOTS Scope Certificate) |
MEMBERSHIP |
Industry body or standard membership |
PRODUCT |
Product-level certificate attached to a specific product |
TRANSACTION |
Transaction certificate for a specific order or batch |
For DPP use cases the most relevant types are COMPANY, SCOPE, and PRODUCT. Note that TRANSACTION certificates are access-restricted: fetching one by ID returns 403 forbidden unless your company created it or owns it.
Certificate statuses
status reflects the review state of the certificate: DRAFT, REQUESTED, APPROVED, REJECTED, ACKNOWLEDGED, or NOT_VERIFIABLE. For consumer-facing DPP display, use APPROVED or ACKNOWLEDGED only. DRAFT certificates are visible only to their creator.
5a. List certificates
curl "$BASE_URL/certificates?page=1&limit=100&status=APPROVED" \
-H "companyapikey: $API_KEY"
Supported query parameters:
| Param | Notes |
|---|---|
page |
1-based page number. Default 1. |
limit |
Page size. Default 20, max 500. |
sort |
Sort column: name, companyName, status, updatedAt, expirationDate, type, documentNumber, licenseNumber, issueDate, issuedBy. |
order |
asc or desc (default desc). |
status |
One of the statuses above. Filter server-side to avoid paging through non-public records. |
type |
One of the certificate types above. |
companyId |
Exact match on the supplier company that holds the certificate. Most useful in DPP flows (one call per supplier collected in Step 4). |
standardId |
Exact match on the standard id. |
filter |
URL-encoded JSON blob for fine-grained filtering. Supported keys: name, companyName, status, type, explanation, issuedBy, documentNumber, licenseNumber, facilityProcesses, standardIds, companyId. Example: filter=%7B%22companyId%22%3A%22PZ86G3I3SXB%22%7D. |
Response (200):
{
"metadata": {
"success": true,
"pagination": { "page": 1, "limit": 100, "total": 2, "totalPages": 1 }
},
"data": [
{
"id": "cert_01KP2Q4R6S8T0V2W4X6Y8Z0A2B",
"name": "GOTS Scope Certificate — Developers' CMT & Fabric",
"type": "SCOPE",
"companyId": "G3JITT4AM9L",
"companyName": "Developers' CMT & Fabric",
"companyOfficialName": "Developers' CMT & Fabric ApS",
"documentNumber": "CU1234567GOTS",
"licenseNumber": null,
"issueDate": "2025-01-15T00:00:00.000Z",
"expirationDate": "2026-01-14T23:59:59.000Z",
"issuedBy": "CCPB S.r.l.",
"explanation": "GOTS v6.0 scope certificate covering cut-make-trim processes",
"status": "APPROVED",
"fileUrl": "documents/G3JITT4AM9L/cert_01KP2Q4R6S8T0V2W4X6Y8Z0A2B.pdf",
"fileContentType": "application/pdf"
},
{
"id": "cert_01KP2Q5S7T9V1W3X5Y7Z9A1B3C",
"name": "Fair Trade Certified — Creative Sourcing Co. Ltd.",
"type": "COMPANY",
"companyId": "PZ86G3I3SXB",
"companyName": "Creative Sourcing Co. Ltd.",
"companyOfficialName": "Creative Sourcing Co. Ltd.",
"documentNumber": null,
"licenseNumber": "FT-CN-1122",
"issueDate": "2024-06-01T00:00:00.000Z",
"expirationDate": "2026-05-31T23:59:59.000Z",
"issuedBy": "Fairtrade International",
"explanation": null,
"status": "APPROVED",
"fileUrl": null,
"fileContentType": "application/pdf"
}
]
}
fileUrlin list responses is not downloadable. In the list,fileUrlis the raw storage object name (ornullwhen no file is attached) — the underlying bucket is private, so this value cannot be fetched directly. Treat it as a has-a-document indicator. To actually download the certificate document, fetch the certificate by ID (below), which returns a signed URL.
5b. Match certificates to supply chain suppliers
The companyId query param filters by a single supplier. For a full supply chain, make one call per supplier and merge the results:
# COMPANY_IDS collected from Step 4
COMPANY_IDS=("G3JITT4AM9L" "PZ86G3I3SXB")
for CID in "${COMPANY_IDS[@]}"; do
curl -s -G "$BASE_URL/certificates" \
--data-urlencode "companyId=$CID" \
--data "status=APPROVED" \
--data "limit=500" \
-H "companyapikey: $API_KEY"
done
Alternatively, fetch approved certificates in one call and filter client-side — useful when the supplier set is large or you want to cache a single response:
ALL_CERTS=$(curl -s "$BASE_URL/certificates?page=1&limit=500&status=APPROVED" \
-H "companyapikey: $API_KEY")
echo "$ALL_CERTS" | python3 -c "
import sys, json
data = json.load(sys.stdin)
company_ids = {'G3JITT4AM9L', 'PZ86G3I3SXB'}
relevant = [c for c in data['data'] if c['companyId'] in company_ids]
print(json.dumps(relevant, indent=2))
"
5c. Get a single certificate (with a downloadable file URL)
curl "$BASE_URL/certificates/$CERT_ID" \
-H "companyapikey: $API_KEY"
Returns the same certificate shape, but here fileUrl is a signed download URL valid for 1 hour. Fetch the document promptly after the call — for DPP pages, request a fresh signed URL on demand rather than caching fileUrl.
Error cases:
| Status | Code | Meaning |
|---|---|---|
404 |
certificate_not_found |
Certificate doesn't exist or isn't visible to your API key (includes other companies' DRAFT certificates) |
403 |
forbidden |
TRANSACTION certificate you neither created nor own |
Pagination
The certificates endpoint uses 1-based pagination with page (starting at 1) and limit. If metadata.pagination.totalPages is greater than 1, fetch subsequent pages:
# Page 1: records 1–100
curl "$BASE_URL/certificates?page=1&limit=100" -H "companyapikey: $API_KEY"
# Page 2: records 101–200
curl "$BASE_URL/certificates?page=2&limit=100" -H "companyapikey: $API_KEY"
Step 6 — Fetch material composition
Fibre composition and countries of origin are mandatory DPP content for textiles under ESPR. The Public API exposes them as material headers (a named composition, e.g. "Shell") and material lines (the individual fibres, organized as a tree):
# Headers for the product (styleId accepts style, variant, or SKU IDs — inherits from parent)
curl "$BASE_URL/material-headers?styleId=$STYLE_ID&page=1&limit=50" \
-H "companyapikey: $API_KEY"
# Lines for a header, with raw material catalog data and country details resolved
curl "$BASE_URL/material-lines?materialHeaderId=$MATERIAL_HEADER_ID&include=rawMaterials,countriesOfOrigin&page=1&limit=50" \
-H "companyapikey: $API_KEY"
Lines carry percentage (relative to siblings at the same tree level), countriesOfOrigin (ISO alpha-2 codes), and rawMaterial details including isRecycled / isSynthetic flags. The full model — tree reconstruction, inheritance, percentages — is covered with response examples in the Materials Guide and the LCA Provider Guide (Step 4).
Recommended integration flow
- Fetch products — use
level=skuwith the EAN/barcode to find the exact physical item, orlevel=stylefor a full product range scan; addisStoryActive=trueto fetch only DPP-ready products - Read
qrCodeUrl— if your platform prints the Retraced QR code, place the SVG into your label artwork; decode it if you need the destination URL for NFC - Verify before printing —
isStoryActivemust betrueandqrCodeUrlnon-null; a missing or inactive story means a dead consumer experience - Fetch supply chain — call
GET /api/v2/supply-chains/{id}with the product ID (any level) to get facility-level tracing data for your DPP page - Collect supplier company IDs — extract
companyIdfrom all supply chain nodes - Fetch and match certificates — call
GET /api/v2/certificates?status=APPROVED&companyId={supplierId}once per supplier, or fetch all approved certificates and filter client-side; fetch by ID when you need the actual document - Fetch material composition — headers and lines for the fibre breakdown and countries of origin
- Compose your DPP payload — combine product metadata, supply chain nodes, certificates, and materials into your DPP data model
- Cache appropriately — product and supply chain data are stable; refresh on a daily schedule or when the brand notifies you of updates (
updatedAfterUnixMson/stylessupports incremental pulls). Never cache signed certificatefileUrls — they expire after 1 hour.
Full collection script
#!/usr/bin/env bash
set -euo pipefail
BASE_URL="https://publicapi.retraced.com/api/v2"
API_KEY="your-api-key"
STYLE_ID="style_01KMZMMMW8JA3S1RVX1PS8E19S"
api_get() { curl -s "$BASE_URL$1" -H "companyapikey: $API_KEY"; }
echo "=== Step 1: Fetch style ==="
STYLE=$(api_get "/styles/$STYLE_ID")
echo "$STYLE" | python3 -m json.tool
QR_URL=$(echo "$STYLE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['data'].get('qrCodeUrl') or '')")
STORY_ACTIVE=$(echo "$STYLE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['data'].get('isStoryActive'))")
echo "QR code image: $QR_URL (story active: $STORY_ACTIVE)"
echo "=== Step 4: Supply chain ==="
SUPPLY_CHAIN=$(api_get "/supply-chains/$STYLE_ID")
echo "$SUPPLY_CHAIN" | python3 -m json.tool
COMPANY_IDS=$(echo "$SUPPLY_CHAIN" | python3 -c "
import sys, json
sc = json.load(sys.stdin)['data']
ids = sorted({n['companyId'] for g in sc['nodesByProductionProcesses'] for n in g['nodes'] if n['companyId']})
print('\n'.join(ids))
")
echo "Supplier company IDs: $COMPANY_IDS"
echo "=== Step 5: Certificates ==="
ALL_CERTS=$(api_get "/certificates?page=1&limit=500&status=APPROVED")
echo "$ALL_CERTS" | python3 -c "
import sys, json
data = json.load(sys.stdin)
company_ids = set('''$COMPANY_IDS'''.split())
relevant = [c for c in data['data'] if c['companyId'] in company_ids]
print(json.dumps(relevant, indent=2))
"
echo "=== Step 6: Material composition ==="
HEADERS=$(api_get "/material-headers?styleId=$STYLE_ID&page=1&limit=50")
echo "$HEADERS" | python3 -m json.tool
HEADER_IDS=$(echo "$HEADERS" \
| python3 -c "import sys, json; d=json.load(sys.stdin); print('\n'.join(h['id'] for h in d['data']))")
for HEADER_ID in $HEADER_IDS; do
api_get "/material-lines?materialHeaderId=$HEADER_ID&include=rawMaterials,countriesOfOrigin&page=1&limit=50" \
| python3 -m json.tool
done
echo "=== Done ==="
Quick reference
| Data | Endpoint | Notes |
|---|---|---|
| List styles | GET /api/v2/styles?level=style |
Add nameOrCode to search, isStoryActive=true for DPP-ready only |
| List variants | GET /api/v2/styles?level=variant&styleId= |
|
| List SKUs | GET /api/v2/styles?level=sku&variantId= |
Use EAN code to locate exact SKU |
| Get single product | GET /api/v2/styles/{id} |
Returns qrCodeUrl and the full images array (any level, no include needed); include=tracingStory for story details |
| Supply chain | GET /api/v2/supply-chains/{id} |
Accepts style, variant, or SKU ID; inherits from ancestors |
| List certificates | GET /api/v2/certificates |
Top-level filters: status, type, companyId, standardId; fileUrl not downloadable here |
| Get certificate | GET /api/v2/certificates/{id} |
fileUrl is a 1-hour signed download URL |
| Material headers | GET /api/v2/material-headers?styleId= |
Accepts style, variant, or SKU ID |
| Material lines | GET /api/v2/material-lines?materialHeaderId= |
include=rawMaterials,countriesOfOrigin |
Known limitations and caveats
qrCodeUrlis the QR image, not the destination. It points at the printable SVG on Retraced's CDN. The consumer-facing destination is what the QR encodes — decode the image if you need it as a string, and don't derive it from the image filename.Certificates are not filterable by product.
GET /api/v2/certificatesaccepts server-side filtering by supplier (companyId) and by the keys inside thefilterJSON blob, but not by product ID or supply chain relationship. To scope certificates to a specific product, collect suppliercompanyIdvalues from the supply chain response and either call/certificates?companyId=…once per supplier or match client-side.Certificate list
fileUrlis a raw storage name. OnlyGET /certificates/{id}returns a downloadable (signed, 1-hour) URL.Boolean filters on
/stylesaccept onlytrueorfalse.isStoryActive=false,isArchived=false, etc. filter for thefalsevalue; any other value (e.g.1,yes) is rejected with a400. Omit the parameter to skip the filter.qrCodeUrlmay be null. Not every product has a generated QR code. Combine a non-nullqrCodeUrlwithisStoryActive: trueas your print gate.
Related Reading
- Products Guide — the Style → Variant → SKU hierarchy, codes, filters, and field inheritance
- Materials Guide — full material composition model with response examples
- LCA Provider Guide — supply chain + ESG + materials collection walkthrough
- API Reference — interactive endpoint and schema documentation
- All integration guides