The DPPAutomate REST API generates, manages, resolves and exports EU Digital Product Passports. Every endpoint accepts and returns JSON (the public regulatory endpoint returns JSON-LD). There is no SDK - talk to the API directly, or hand a master key to an LLM and let it drive. The full machine-readable contract lives at /api/openapi.json.
Two layers
The surface is split into two layers for two audiences:
Layer 1 - public regulatory. Base https://dppautomate.com/api/public/v1. Unauthenticated. Resolves a published passport to redacted JSON-LD - what QR codes, crawlers and notified bodies fetch.
Layer 2 - management API. Base https://dppautomate.com/api/v1. Authenticated with a per-workspace master key. Everything else: CRUD, AI generation, drafts, learnings, workspace mode, account resources.
Public endpoint
The one Layer-1 endpoint takes no authorization and is edge-cached with open CORS. It returns application/ld+json redacted to the passport's data access level (owner ids and confidential sections are never exposed), or 404 if nothing is published for the identifier.
# No auth. application/ld+json out.
curl https://dppautomate.com/api/public/v1/passports/DPP-1717-AB12CDAuthentication
Layer-2 requests use bearer-token authentication. Create a master key in the dashboard under Settings > API Keys - the secret starts with ep_live_sk_ and is shown once. Send it on every request:
Authorization: Bearer ep_live_sk_...Permissions
Each key carries a set of permissions. The required permission is listed on every endpoint below.
read- allGETendpoints.write-POST/PUT/PATCHthat create or mutate.delete-DELETEand key revocation.- An
admin(or*) key satisfies every permission.
Endpoints
The full surface, grouped by resource. Path parameters are written as :id; Layer-2 paths are relative to https://dppautomate.com/api/v1. The badge after each path is the required permission.
Public (Layer 1, no auth)
/api/public/v1/passports/:dppUidpublicResolve a published passport as redacted JSON-LD. No auth. 404 if not published.Passports
/passportsreadList, search, filter, paginate (status, category, search, favorite, format)./passportswriteCreate a passport from sections and/or top-level shortcuts./passports/:idreadRetrieve one passport (?format=jsonld for JSON-LD)./passports/:idwriteUpdate any section or status (PUT is an alias)./passports/:iddeleteDelete a passport./passports/:id/archivewriteArchive a passport./passports/:id/restorewriteRestore an archived passport./passports/:id/favoritewriteToggle the favourite flag./passports/:id/qrreadQR code for the public page as svg / png / json./passports/statsreadAggregate passport statistics./passports/searchreadFull-text search (q=...)./passports/recentreadRecently updated passports./passports/categoriesreadCategory breakdown with counts./passports/favoritesreadFavourited passports./passports/exportreadExport as json | jsonld | csv | excel | pdf | qr./passports/importwriteBulk import a passports array.Generation (AI)
/passports/generatewriteGenerate a passport from a product image. Review -> draft, Auto -> active; create:false previews without saving.Drafts (review queue)
/draftsreadList drafts awaiting review./drafts/:id/approvewritePromote a draft to an active passport./drafts/:id/rejectwriteReject (archive) a draft (optional { reason }).Learnings
/learningsreadList learnings (include_inactive=true to include disabled)./learningswriteAdd a learning { instruction, section?, productCategory? }./learnings/:idwriteEdit text and/or activate/deactivate { instruction?, active? }./learnings/:iddeleteDelete a learning.Workspace
/workspacereadIdentity, AI mode, role, entitlement summary./workspace/modereadRead the AI mode./workspace/modewriteSet the AI mode { mode: 'review' | 'auto' } (PATCH alias).API keys
/api-keysreadList keys (secrets are never returned again)./api-keyswriteCreate a key { name, permissions } - secret returned once./api-keys/:idreadRead one key's metadata./api-keys/:iddeleteDelete a key./api-keys/:id/rotatewriteRotate with an optional grace period./api-keys/:id/revokedeleteImmediately revoke a key.Organization & integrations
/organizationreadRead the organization profile + stats./organizationwriteCreate the organization profile./organizationwriteUpdate profile fields (PUT alias)./integrationsreadList connected integrations./integrationswriteConnect or configure an integration.Account
/notificationsreadList / filter / mark / delete notifications./settingsreadRead notification + regional settings./settingswriteUpdate settings (PUT alias)./teamreadTeam members, invites and stats./billingreadSubscription, usage, invoices (read-only by design)./deadlinesreadCompliance deadlines (write/complete supported)./activitiesreadThe activity feed.AI helpers
/ai/analyze-imagewriteAnalyse an image into a passport WITHOUT saving./ai/chatwriteChat with the assistant using workspace context./ai/contextreadRead the grounding context the assistant uses.Examples
Generate a passport from an image
The agentic entry point. Returns { passport, mode, status, created }; status is draft in Review mode, active in Auto mode, or preview when create:false.
curl https://dppautomate.com/api/v1/passports/generate \
-X POST \
-H "Authorization: Bearer $DPP_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "image": "data:image/png;base64,<...>" }'List passports
Paginated, filterable index. Supports status, category, search, favorite, page and per_page.
curl "https://dppautomate.com/api/v1/passports?status=active&per_page=25" \
-H "Authorization: Bearer $DPP_API_KEY"The response is paginated under meta with cursor links:
{
"data": [
{
"id": "...",
"object": "digital_product_passport",
"status": "active",
"identification": {
"productName": "Merino Wool Beanie",
"productCategory": "Textiles & Apparel",
"dppUid": "DPP-1717-AB12CD"
},
"sustainability": { "sustainabilityScore": 82, "recyclabilityClass": "B" }
}
],
"meta": { "total": 42, "page": 1, "per_page": 25, "total_pages": 2 },
"links": { "self": "...", "next": "...", "prev": null }
}Rate limits
Layer-2 requests are rate limited per key over a rolling 60-second window, by billing tier. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. Exceeding the ceiling returns 429 with a Retry-Afterheader. Layer 1 is unauthenticated and edge-cached, so it isn't counted here.
| Tier | Requests / min |
|---|---|
| Sandbox | 60 |
| Starter | 120 |
| Operator | 600 |
| Scale | 1,200 |
| Enterprise | 6,000 |
Errors
The API uses conventional HTTP status codes. Errors carry a uniform JSON envelope with a stable machine code:
{
"error": {
"message": "API key does not have write permission",
"code": "FORBIDDEN",
"status": 403
}
}BAD_REQUESTInvalid parameters or body.UNAUTHORIZEDMissing or invalid API key.CAPACITY_REACHEDPassport capacity reached, or no usable plan (WORKSPACE_NEEDS_PLAN). Manage billing in the dashboard.FORBIDDENThe key lacks the required permission.NOT_FOUNDResource does not exist or is not active.RATE_LIMITEDRate limit exceeded - back off and retry after the window resets.INTERNAL_ERRORUnexpected error on our side; safe to retry.OpenAPI & llms.txt
The reference above is the human view. The canonical, machine-readable sources of truth are:
- /api/openapi.json - the full OpenAPI 3.1 spec covering both layers, every schema, and every error code.
- /llms.txt - a concise operator guide written for AI agents, with an agent quickstart recipe.
MCP server. MCP-capable agents can connect to the Streamable HTTP endpoint at /api/mcp (JSON-RPC 2.0, stateless), authenticated with the same Authorization: Bearer ep_live_sk_... master key. It exposes tools to list, search, read, create and generate passports, score compliance readiness, and read workspace stats.
Webhooks. Register HTTPS endpoints under /api/v1/webhooks to receive a signed POST on passport lifecycle events (created, published, archived, deleted, draft approved/rejected). Each delivery carries an X-DPP-Signature header (Stripe-style HMAC-SHA256); verify it with the endpoint signing secret shown once at creation.
New to the API? Start with the Quickstart. Need help integrating? Contact support.