Reference

REST API

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.

cURL
# No auth. application/ld+json out.
curl https://dppautomate.com/api/public/v1/passports/DPP-1717-AB12CD

Authentication

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:

Header
Authorization: Bearer ep_live_sk_...
Heads up - Never expose a master key in client-side code - it can run your whole workspace. Keep it server-side or in a secrets manager. If it leaks, rotate or revoke it from the dashboard; the old key stops working immediately.

Permissions

Each key carries a set of permissions. The required permission is listed on every endpoint below.

  • read - all GET endpoints.
  • write - POST/PUT/PATCH that create or mutate.
  • delete - DELETE and 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)

GET/api/public/v1/passports/:dppUidpublicResolve a published passport as redacted JSON-LD. No auth. 404 if not published.

Passports

GET/passportsreadList, search, filter, paginate (status, category, search, favorite, format).
POST/passportswriteCreate a passport from sections and/or top-level shortcuts.
GET/passports/:idreadRetrieve one passport (?format=jsonld for JSON-LD).
PATCH/passports/:idwriteUpdate any section or status (PUT is an alias).
DELETE/passports/:iddeleteDelete a passport.
POST/passports/:id/archivewriteArchive a passport.
POST/passports/:id/restorewriteRestore an archived passport.
POST/passports/:id/favoritewriteToggle the favourite flag.
GET/passports/:id/qrreadQR code for the public page as svg / png / json.
GET/passports/statsreadAggregate passport statistics.
GET/passports/searchreadFull-text search (q=...).
GET/passports/recentreadRecently updated passports.
GET/passports/categoriesreadCategory breakdown with counts.
GET/passports/favoritesreadFavourited passports.
GET/passports/exportreadExport as json | jsonld | csv | excel | pdf | qr.
POST/passports/importwriteBulk import a passports array.

Generation (AI)

POST/passports/generatewriteGenerate a passport from a product image. Review -> draft, Auto -> active; create:false previews without saving.

Drafts (review queue)

GET/draftsreadList drafts awaiting review.
POST/drafts/:id/approvewritePromote a draft to an active passport.
POST/drafts/:id/rejectwriteReject (archive) a draft (optional { reason }).

Learnings

GET/learningsreadList learnings (include_inactive=true to include disabled).
POST/learningswriteAdd a learning { instruction, section?, productCategory? }.
PATCH/learnings/:idwriteEdit text and/or activate/deactivate { instruction?, active? }.
DELETE/learnings/:iddeleteDelete a learning.

Workspace

GET/workspacereadIdentity, AI mode, role, entitlement summary.
GET/workspace/modereadRead the AI mode.
PUT/workspace/modewriteSet the AI mode { mode: 'review' | 'auto' } (PATCH alias).

API keys

GET/api-keysreadList keys (secrets are never returned again).
POST/api-keyswriteCreate a key { name, permissions } - secret returned once.
GET/api-keys/:idreadRead one key's metadata.
DELETE/api-keys/:iddeleteDelete a key.
POST/api-keys/:id/rotatewriteRotate with an optional grace period.
POST/api-keys/:id/revokedeleteImmediately revoke a key.

Organization & integrations

GET/organizationreadRead the organization profile + stats.
POST/organizationwriteCreate the organization profile.
PATCH/organizationwriteUpdate profile fields (PUT alias).
GET/integrationsreadList connected integrations.
POST/integrationswriteConnect or configure an integration.

Account

GET/notificationsreadList / filter / mark / delete notifications.
GET/settingsreadRead notification + regional settings.
PATCH/settingswriteUpdate settings (PUT alias).
GET/teamreadTeam members, invites and stats.
GET/billingreadSubscription, usage, invoices (read-only by design).
GET/deadlinesreadCompliance deadlines (write/complete supported).
GET/activitiesreadThe activity feed.

AI helpers

POST/ai/analyze-imagewriteAnalyse an image into a passport WITHOUT saving.
POST/ai/chatwriteChat with the assistant using workspace context.
GET/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
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
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:

JSON
{
  "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.

TierRequests / min
Sandbox60
Starter120
Operator600
Scale1,200
Enterprise6,000

Errors

The API uses conventional HTTP status codes. Errors carry a uniform JSON envelope with a stable machine code:

JSON
{
  "error": {
    "message": "API key does not have write permission",
    "code": "FORBIDDEN",
    "status": 403
  }
}
400BAD_REQUESTInvalid parameters or body.
401UNAUTHORIZEDMissing or invalid API key.
402CAPACITY_REACHEDPassport capacity reached, or no usable plan (WORKSPACE_NEEDS_PLAN). Manage billing in the dashboard.
403FORBIDDENThe key lacks the required permission.
404NOT_FOUNDResource does not exist or is not active.
429RATE_LIMITEDRate limit exceeded - back off and retry after the window resets.
500INTERNAL_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.