Skip to main content

PoLI endpoints

What is PoLI?

PoLI (Person of Legal Interest) is a concept established under EU Battery Regulation 2023/1542. Certain entities — market surveillance authorities, customs authorities, the European Commission, and other bodies with a statutory right of access — are entitled to view non-public fields in a Digital Product Passport that are not accessible to the general public.

These restricted fields may include detailed supply chain traceability data, raw material sourcing documentation, and internal test results that manufacturers are required to record but not required to publish openly.

The Traceable PoLI API allows qualifying entities to formally request and receive access to these restricted fields through a structured, audited workflow.

PoLI account required

To use these endpoints, your organisation must have a registered Traceable account with PoLI access enabled. Contact support@traceable.digital to register as a PoLI entity.


POST /api/poli/access

Submit an access request from a PoLI entity to view restricted DPP fields for a specific product.

Authentication

Required. Include your API key as a bearer token:

Authorization: Bearer trc_live_{your_key}

Request body

Content-Type: application/json

FieldTypeRequiredDescription
productSlugstringYesThe slug of the product whose restricted fields you are requesting access to
requestingEntitystringYesFull legal name of the requesting authority or organisation
legalBasisstringYesCitation of the specific legal provision granting the right of access (e.g., article number and regulation)
contactEmailstringYesEmail address for correspondence about this request. Must be a valid email.
jurisdictionstringYesISO 3166-1 alpha-2 country code of the requesting authority's jurisdiction (e.g., DE, NL, FR)

Example request body:

{
"productSlug": "swiftvolt-48v-100ah-ev-pack",
"requestingEntity": "Netherlands Authority for Consumers and Markets (ACM)",
"legalBasis": "EU Battery Regulation 2023/1542, Article 74(1) — Market Surveillance Authorities",
"contactEmail": "dpp-access@acm.nl",
"jurisdiction": "NL"
}

Response — 201 Created

{
"requestId": "poli_req_01HXYZ9KP2MNTV3QW8JBDCF4A",
"status": "pending",
"estimatedReviewTime": "72 hours"
}
FieldTypeDescription
requestIdstringUnique identifier for this access request. Store this — you will need it to check status via /api/poli/verify.
statusstringAlways pending on creation
estimatedReviewTimestringIndicative time for the manufacturer to review and action the request

Response — 400 Bad Request

Returned when the request body fails validation:

{
"error": "Request body validation failed",
"code": "VALIDATION_ERROR",
"details": {
"fields": {
"jurisdiction": "Must be a valid ISO 3166-1 alpha-2 country code",
"contactEmail": "Must be a valid email address"
}
}
}

Response — 401 Unauthorized

{
"error": "Authentication required",
"code": "UNAUTHORIZED",
"details": {}
}

Response — 404 Not Found

{
"error": "Product not found",
"code": "PRODUCT_NOT_FOUND",
"details": {}
}

Response — 409 Conflict

Returned if a pending access request from the same entity already exists for this product:

{
"error": "An active access request already exists for this product",
"code": "DUPLICATE_REQUEST",
"details": {
"existingRequestId": "poli_req_01HABC..."
}
}

Examples

curl

curl -X POST https://app.traceable.digital/api/poli/access \
-H "Authorization: Bearer ${TRACEABLE_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"productSlug": "swiftvolt-48v-100ah-ev-pack",
"requestingEntity": "Netherlands Authority for Consumers and Markets (ACM)",
"legalBasis": "EU Battery Regulation 2023/1542, Article 74(1) — Market Surveillance Authorities",
"contactEmail": "dpp-access@acm.nl",
"jurisdiction": "NL"
}'

JavaScript (Node.js)

interface PoliAccessRequest {
productSlug: string;
requestingEntity: string;
legalBasis: string;
contactEmail: string;
jurisdiction: string;
}

interface PoliAccessResponse {
requestId: string;
status: 'pending';
estimatedReviewTime: string;
}

async function submitPoliAccessRequest(
request: PoliAccessRequest
): Promise<PoliAccessResponse> {
const apiKey = process.env.TRACEABLE_API_KEY;
if (!apiKey) {
throw new Error('TRACEABLE_API_KEY environment variable is not set');
}

const response = await fetch('https://app.traceable.digital/api/poli/access', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(request),
});

if (response.status === 409) {
const data = await response.json();
throw new Error(
`Duplicate request. Existing request ID: ${data.details?.existingRequestId}`
);
}

if (response.status === 401) {
throw new Error('Invalid or missing API key');
}

if (response.status === 404) {
throw new Error(`Product not found: ${request.productSlug}`);
}

if (!response.ok) {
const data = await response.json().catch(() => ({}));
throw new Error(`PoLI access request failed: ${data.error ?? response.statusText}`);
}

return response.json() as Promise<PoliAccessResponse>;
}

// Usage
const result = await submitPoliAccessRequest({
productSlug: 'swiftvolt-48v-100ah-ev-pack',
requestingEntity: 'Netherlands Authority for Consumers and Markets (ACM)',
legalBasis: 'EU Battery Regulation 2023/1542, Article 74(1) — Market Surveillance Authorities',
contactEmail: 'dpp-access@acm.nl',
jurisdiction: 'NL',
});

console.log(`Request submitted: ${result.requestId}`);
// Store result.requestId for subsequent status checks

GET /api/poli/verify

Check the status of a previously submitted PoLI access request. If the request has been approved, this endpoint returns a short-lived access token and the restricted field data.

Authentication

Required. Must be the same API key that was used to submit the original request.

Query parameters

ParameterTypeRequiredDescription
requestIdstringYesThe requestId returned by POST /api/poli/access

Response — 200 OK

{
"requestId": "poli_req_01HXYZ9KP2MNTV3QW8JBDCF4A",
"status": "approved",
"accessToken": "pat_eyJhbGciOiJIUzI1NiJ9...",
"accessTokenExpiresAt": "2025-04-08T12:00:00Z",
"restrictedFields": {
"supplyChain": {
"rawMaterialSources": [
{
"material": "Cobalt",
"country": "DRC",
"mineOperator": "Glencore PLC",
"dueDiligenceAuditDate": "2024-09-01",
"auditBody": "RCS Global"
}
],
"internalAuditReportUrl": "https://storage.traceable.digital/docs/swiftvolt-audit-2024.pdf"
},
"testResults": {
"safetyTestingBody": "UL Solutions",
"safetyStandard": "IEC 62619:2022",
"testReportReference": "UL-2024-87341-R",
"passedAt": "2024-11-12T00:00:00Z"
}
}
}
FieldTypeDescription
requestIdstringThe request identifier
statusstringpending — awaiting manufacturer review; approved — access granted; rejected — access denied by manufacturer
accessTokenstring | nullShort-lived token (valid for 24 hours) for accessing restricted fields. Present only when status is approved.
accessTokenExpiresAtstring | nullISO 8601 expiry time for the access token. Null when not approved.
restrictedFieldsobject | nullThe restricted DPP field data. Present only when status is approved. Structure varies by battery category.

Pending example:

{
"requestId": "poli_req_01HXYZ9KP2MNTV3QW8JBDCF4A",
"status": "pending",
"accessToken": null,
"accessTokenExpiresAt": null,
"restrictedFields": null
}

Rejected example:

{
"requestId": "poli_req_01HXYZ9KP2MNTV3QW8JBDCF4A",
"status": "rejected",
"accessToken": null,
"accessTokenExpiresAt": null,
"restrictedFields": null
}
Rejection reason

Rejection reasons are communicated out-of-band to the contactEmail specified in the original request, not via the API response.

Response — 401 Unauthorized

Returned if the API key used to verify does not match the key that submitted the request:

{
"error": "Access denied: this request was submitted by a different API key",
"code": "FORBIDDEN",
"details": {}
}

Response — 404 Not Found

{
"error": "Access request not found",
"code": "REQUEST_NOT_FOUND",
"details": {}
}

Access token usage

The accessToken returned when a request is approved is a short-lived JWT valid for 24 hours. After expiry, call GET /api/poli/verify again — a new token will be issued as long as the approval remains active.

Use the token in subsequent DPP requests to access restricted fields:

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

The full restricted field data is also returned directly in the restrictedFields object of the verify response, so for many use cases you do not need to make a separate DPP request.