DPP Agent docs

Public API overview

DPP Agent exposes a small, REST-style HTTP API for creating, reading, and managing Digital Product Passports across every industry the EU's ESPR roadmap touches — textile, electronics, batteries, cosmetics, tyres, construction, furniture, and more.

This reference is generic across industries. Endpoint signatures are identical regardless of category; only the keys inside dpp_data differ. See the per-category schemas (espr-base, tex.*, bat.*, ict.*, cos.*, con.*, tyr.*) for the structured fields each sector uses.

Base URLs

Layer URL Notes
Resolver (public DPP read) https://{slug}.dpp.dppagent.com Consumer-scan endpoint. Custom-tier brands replace with their own domain via CNAME.
Management API https://dppagent.com/api/v1 Authoring + admin endpoints used by integrations and tenant dashboards.
Static docs https://docs.dppagent.com This reference.

The resolver is read-only and CDN-cached. The management API is authored writes and authenticated reads.

Authentication

Three styles, picked per endpoint.

1. None (public scan). Every consumer-scan endpoint under the resolver host is unauthenticated. Response shape negotiated via Accept header per EN 18216 §5.

2. Bearer token. Every authoring endpoint under /api/v1/ requires Authorization: Bearer <token>. Tenants generate their tokens under Settings → API in the dashboard.

GET /api/v1/dpps/abc-123
Authorization: Bearer dpp_live_a8b1c2d3e4...

Tokens are tenant-scoped. They never let a caller read another tenant's data even if the request body claims otherwise. Rotate tokens at any time — old tokens are invalidated immediately.

3. Supabase session (browser-only). The dashboard UI signs in operators through Supabase. This is an implementation detail — external integrators always use Bearer tokens.

Conventions

  • Format: requests + responses are JSON unless stated otherwise. Content-Type: application/json; charset=utf-8.
  • Identifiers: every DPP carries an opaque UUID (id) and a canonical passport URL (passport_id). Pass either when reading.
  • Datetimes: ISO 8601 with timezone offset (2026-06-26T13:42:05.000Z).
  • Country / currency: ISO 3166-1 alpha-2 (SE, DK, FR), ISO 4217 (EUR, SEK).
  • Pagination: list endpoints accept ?limit= (max 100, default
    1. and ?cursor= (opaque). Responses include next_cursor when more rows exist.

Versioning

The API is on v1. Backwards-incompatible changes ship behind a new major version (v2, v3 …) — never inside v1. Additive changes (new fields, new endpoints, new optional parameters) ship without a version bump.

Error format

Errors return a non-2xx HTTP status and a JSON body with a stable shape:

{
  "error": "validation_failed",
  "message": "gtin must be 13 or 14 digits",
  "details": {
    "field": "gtin",
    "value": "0073-bad-input"
  }
}

Error codes you'll meet most often:

Code HTTP Meaning
authentication_required 401 Bearer token missing
authentication_invalid 401 Token rejected — rotate it
forbidden 403 Token is valid but scoped to a different tenant
not_found 404 DPP, tenant, or endpoint doesn't exist
validation_failed 400 Required field missing or malformed
conflict 409 GTIN / batch / serial already in use
quota_exceeded 429 Plan quota or rate-limit hit
internal_error 500 Bug on our side — capture the response and ping support

Rate limits

Default limits per tenant:

  • Resolver reads: unlimited, CDN-cached. Burst-tolerant.
  • Authoring writes: 60 requests per minute, 5 000 per day.
  • AI Suggest / extraction: 30 requests per minute, 1 000 per day.
  • Bulk imports: 5 concurrent jobs.

The X-RateLimit-Remaining, X-RateLimit-Limit, and X-RateLimit-Reset headers are present on every authenticated response. Hitting the cap returns 429 quota_exceeded with a Retry-After header in seconds.

Custom-tier plans bump these limits. Talk to support if you need more.

CORS

The resolver allows requests from any origin (Access-Control-Allow-Origin: *) for cross-site validators, scanner apps, and external integrations. The management API allows requests only from the tenant's own domain and dashboards.

Caching

Resolver responses set Cache-Control based on DPP status:

Status Max-age
active, replaced 5 minutes (CDN), 30 seconds (browser)
draft 10 seconds
withdrawn, archived 10 seconds
Not found 10 seconds

QR codes and label SVGs cache for 1 day — they only change when the underlying template or DPP data changes.

Sandbox

Each tenant has a sandbox mode toggle on Settings → API. Sandbox tokens write to an isolated, ephemeral dataset and never appear on public resolver URLs. Same surface, same error codes — just no real-world consequences.

Status & uptime

status.dppagent.com shows live status of the resolver, management API, and dashboard. Incidents post there before they post in chat.

Next

  • Resolver — public DPP scan endpoint
  • DPPs — create, read, update, delete passports
  • Tenants — manage your brand profile + custom domains
  • Certifications — register certs that auto-apply to matching DPPs
  • Suppliers — supplier registry with journey-block overlay
  • Files — attach DoP, SDS, technical files at tenant or per-DPP scope
  • QR & Labels — generate codes and label SVGs
  • Validate — system conformance + ESPR Base coverage checker
  • Errors — full error code catalogue