Skip to main content

DPP endpoints

Traceable exposes DPP data through two complementary systems, each serving a different purpose.

Two access methods

MethodURL patternResponseUse case
GS1 Digital Link resolver/01/{GTIN}[/21/{serial}][/10/{batch}]HTML (DPP viewer)QR codes on physical batteries
JSON data API/api/dpp/{slug}JSON / JSON-LDMachine-readable integration

The GS1 Digital Link format is what EU Battery Regulation 2023/1542 requires to be encoded in the data carrier (QR code) on the physical battery. The JSON API is for programmatic access to the underlying data.

Both methods resolve to the same underlying DPP. A battery without a GTIN assigned in Traceable will only have a slug-based URL — the GS1 resolver requires a GTIN.


GET /01/:gtin

GET /01/:gtin/21/:serial

GET /01/:gtin/10/:batch

Resolves a GTIN to the corresponding DPP and renders the battery passport viewer inline. The GS1 URI remains in the browser URL bar — there is no redirect to a slug-based URL.

This is the endpoint that QR codes on physical batteries should encode. It implements the GS1 Digital Link standard (ISO/IEC 18975).

Path structure

SegmentApplication IdentifierDescription
/01/{GTIN}AI 01GTIN (required). 8, 12, 13, or 14 digits with a valid GS1 check digit.
/21/{serial}AI 21Individual serial number (optional)
/10/{batch}AI 10Batch or lot number (optional)

Examples

https://app.traceable.digital/01/09506000134352
https://app.traceable.digital/01/09506000134352/21/ABC123
https://app.traceable.digital/01/09506000134352/21/ABC123/10/BATCH-2026-04

Validation

The GTIN is validated using the standard GS1 modulo-10 check digit algorithm before the database lookup. Requests with an invalid check digit return a 404 immediately — no database query is made.

Supported formats:

FormatDigitsExample
GTIN-8801234565
GTIN-1212012345678905
GTIN-13130123456789012
GTIN-141401234567890128

Response

  • 200 OK — HTML page rendering the DPP viewer for the resolved product. The DPP data is embedded in the page and in the HTML <head> as JSON-LD.
  • 404 Not Found — GTIN not found in the Traceable registry, GTIN check digit is invalid, or the matched product's DPP is not published.

This endpoint returns HTML, not JSON. To retrieve machine-readable DPP data for a product you know by GTIN, resolve the GTIN first to get the slug, then use the JSON API.

When generating the QR code URI for a battery product in Traceable, the platform uses this format when a GTIN is assigned:

https://app.traceable.digital/01/{GTIN}/21/{serialNumber}

If no GTIN has been assigned, the platform falls back to the slug-based URL:

https://app.traceable.digital/dpp/{slug}

The platform's QR code generator in the Operator Portal handles this automatically and displays a "GS1 Compliant" badge when the GTIN-based format is used.


JSON data API

GET /api/dpp/:slug

Retrieve the complete public DPP data for a battery product as JSON.

Path parameters

ParameterTypeRequiredDescription
slugstringYesThe URL-safe product identifier assigned at DPP creation. Example: swiftvolt-48v-100ah-ev-pack

Authentication

None required for public fields. To access restricted supply chain fields via an approved PoLI token, include both the accessToken query parameter and the Authorization: Bearer {apiKey} header.

Optional query parameters

ParameterTypeDescription
accessTokenstringA 24-hour access token obtained from an approved PoLI access request (GET /api/poli/verify). When present and valid, the response also includes a restrictedFields object containing detailed supply chain data not returned in the standard public response.

When an accessToken is provided:

  • The Authorization: Bearer {apiKey} header must also be present.
  • The response includes the standard public fields plus a restrictedFields object (raw material sourcing by mine/country, full supplier audit references, internal test documentation references).
  • If the token has expired (tokens are valid for 24 hours), the endpoint returns 401 Unauthorized. Call GET /api/poli/verify again with the original requestId to obtain a fresh token.
  • If the token does not match the requested product slug, the endpoint returns 403 Forbidden.

For most PoLI integrations the restricted fields are already returned directly in the GET /api/poli/verify response — a separate DPP call with an accessToken is only needed when re-fetching updated values after the initial approval. See PoLI endpoints for the full token lifecycle.

curl "https://app.traceable.digital/api/dpp/swiftvolt-48v-100ah-ev-pack?accessToken=pat_eyJ..." \
-H "Authorization: Bearer ${TRACEABLE_API_KEY}"

Response — 200 OK

Returns the full DPP object for the requested product.

FieldTypeDescription
idstringInternal DPP record identifier
slugstringURL-safe product identifier. Immutable after publish.
productNamestringFull commercial product name
batteryCategorystringOne of: EV_BATTERY, LMT_BATTERY, INDUSTRIAL_BATTERY, SLI_BATTERY, PORTABLE_BATTERY
statusstringpublished — only published DPPs are returned by this endpoint
versionintegerVersion number, incremented each time the DPP is updated and republished
manufacturerobjectManufacturer name, country, registration number, and contact details
carbonFootprintobject | nullCarbon footprint data (present for EV and Industrial batteries; null for others)
recycledContentobjectRecycled content percentages for cobalt, lithium, nickel, lead
performanceobjectCapacity, energy density, cycle life, round-trip efficiency
hazardousSubstancesarrayList of hazardous substances above threshold, with CAS numbers and concentrations
supplyChainobjectSupply chain due diligence summary and responsible sourcing information
complianceobjectRegulatory compliance declarations and certification references
publishedAtstringISO 8601 timestamp when the DPP was first published
updatedAtstringISO 8601 timestamp of the most recent update
createdAtstringISO 8601 timestamp when the DPP record was created

Response — 404 Not Found

Returned when the slug does not match any product, or the product's DPP is not published.

{
"error": "DPP not found or not published",
"code": "PRODUCT_NOT_FOUND",
"details": {}
}

Response — 429 Too Many Requests

{
"error": "Rate limit exceeded",
"code": "RATE_LIMITED",
"retryAfter": 23
}

Examples

curl

curl -s https://app.traceable.digital/api/dpp/swiftvolt-48v-100ah-ev-pack | jq .

JavaScript (Node.js / browser fetch)

async function fetchDpp(slug: string): Promise<DppObject> {
const response = await fetch(
`https://app.traceable.digital/api/dpp/${encodeURIComponent(slug)}`
);

if (response.status === 404) {
throw new Error(`DPP not found for slug: ${slug}`);
}

if (response.status === 429) {
const data = await response.json();
throw new Error(`Rate limited. Retry after ${data.retryAfter} seconds.`);
}

if (!response.ok) {
const data = await response.json().catch(() => ({}));
throw new Error(`Failed to fetch DPP: ${data.error ?? response.statusText}`);
}

return response.json();
}

Python (requests)

import requests

def fetch_dpp(slug: str) -> dict:
url = f"https://app.traceable.digital/api/dpp/{slug}"
response = requests.get(url, timeout=10)

if response.status_code == 404:
raise ValueError(f"DPP not found or not published for slug: {slug}")

if response.status_code == 429:
retry_after = response.json().get("retryAfter", 60)
raise RuntimeError(f"Rate limited. Retry after {retry_after}s.")

response.raise_for_status()
return response.json()

GET /api/dpp/:slug/jsonld

Retrieve a DPP in JSON-LD format for semantic web interoperability.

Path parameters

ParameterTypeRequiredDescription
slugstringYesThe URL-safe product identifier

Authentication

None required.

Response — 200 OK

Returns a JSON-LD document representing the DPP. The Content-Type is application/ld+json.

The @id of the returned document is the canonical URI for the product:

  • If the product has a GTIN assigned: https://app.traceable.digital/01/{GTIN}/21/{serial} (GS1 Digital Link)
  • If no GTIN: https://app.traceable.digital/dpp/{slug}

The document uses:

  • @context: A combination of https://schema.org and the Traceable custom vocabulary at https://vocab.traceable.digital/v1
  • @type: ["schema:Product", "traceable:BatteryPassport"]

Response — 404 Not Found

{
"error": "DPP not found or not published",
"code": "PRODUCT_NOT_FOUND",
"details": {}
}

Example JSON-LD response (product with GTIN)

{
"@context": {
"schema": "https://schema.org/",
"traceable": "https://vocab.traceable.digital/v1#",
"xsd": "http://www.w3.org/2001/XMLSchema#"
},
"@type": ["schema:Product", "traceable:BatteryPassport"],
"@id": "https://app.traceable.digital/01/09506000134352/21/SN-2026-00421",
"schema:name": "SwiftVolt 48V 100Ah EV Pack",
"schema:identifier": "09506000134352",
"schema:manufacturer": {
"@type": "schema:Organization",
"schema:name": "SwiftVolt Energy Systems GmbH",
"schema:addressCountry": "DE",
"schema:vatID": "DE298471625",
"schema:email": "compliance@swiftvolt.de"
},
"traceable:batteryCategory": "EV_BATTERY",
"traceable:version": 3,
"traceable:status": "published",
"traceable:carbonFootprint": {
"@type": "traceable:CarbonFootprint",
"traceable:totalKgCO2ePerKwh": 61.4,
"traceable:lifecycleStages": {
"traceable:rawMaterialExtraction": 28.2,
"traceable:manufacturing": 18.6,
"traceable:distribution": 2.1,
"traceable:usePhase": 7.3,
"traceable:endOfLife": 5.2
},
"traceable:verifiedBy": "TÜV Rheinland",
"traceable:verifiedAt": {
"@type": "xsd:dateTime",
"@value": "2025-01-15T00:00:00Z"
}
},
"traceable:recycledContent": {
"traceable:cobaltPercent": 16.0,
"traceable:lithiumPercent": 6.0,
"traceable:nickelPercent": 6.0,
"traceable:leadPercent": 0.0
},
"traceable:performance": {
"traceable:nominalCapacityKwh": 4.8,
"traceable:ratedVoltageV": 48,
"traceable:cycleLifeAtEightyPercent": 2000,
"traceable:roundTripEfficiencyPercent": 96.2
},
"schema:datePublished": {
"@type": "xsd:dateTime",
"@value": "2025-02-01T10:14:22Z"
},
"schema:dateModified": {
"@type": "xsd:dateTime",
"@value": "2025-03-18T08:45:11Z"
}
}

For full details on consuming JSON-LD responses, see the JSON-LD format data model page and the Parse JSON-LD output integration example.