TracePass v1 uses one auth mechanism: a static API key passed as a Bearer token in the standardAuthorizationheader. Every write also accepts anIdempotency-Keyfor safe retries. Limits are per plan, per UTC day — available on every plan including Free, with per-day call caps that scale with the plan.
API keys
Mint keys at Developer → API keys in the dashboard. Keys are workspace-scoped: every key is tied to one workspace and inherits its plan, limits, and audit log. Keys carry the tp_prefix followed by an opaque random suffix — there's no separate live / test prefix, and no env-namespaced sandbox. Test against your Free or Basic workspace if you need a non-production environment.
Pass the key as a Bearer token on every request:
curl -sS https://app.tracepass.eu/api/v1/products \
-H "Authorization: Bearer tp_REDACTED_xxxxxxxxxxxx"Idempotency-Key
Every POST, PATCH, and DELETE on the v1 surface accepts an Idempotency-Keyheader. Send a UUID v4 (or any opaque string ≤ 255 chars) per logical operation; the platform stores the first response for 24 hours and replays it if the same key + same workspace shows up again. Network retries become safe — you won't double-create a passport because your HTTP client retried on a transient 5xx.
curl -sS https://app.tracepass.eu/api/v1/passports \
-H "Authorization: Bearer tp_REDACTED_xxxxxxxxxxxx" \
-H "Idempotency-Key: 7b4f1e2c-9a3d-4e5b-8c1a-2d3e4f5a6b7c" \
-H "Content-Type: application/json" \
-d '{ "productId": "...", "gs1": { "gtin": "...", "serialNumber": "..." } }'Reusing the same key with a different request body returns422 Unprocessable Entity with error: "Idempotency-Key has already been used with a different request body. Use a new key for the new request, or reuse the original body." — the platform doesn't silently overwrite, because that's almost always a client bug. Generate a fresh key for genuinely new operations.
Rate limits
Two ceilings apply per UTC day, per workspace:
1. v1 write budget — `maxV1WritesPerDay`
Counts every POST / PATCH / DELETEon the v1 surface. Reads aren't budgeted on this counter.
2. v1 passport-read budget — `maxV1PassportsPerDay`
Counts every GETon the passport endpoints (single read + paginated list). Separate from the write budget so an ERP pushing updates doesn't starve your read quota and vice versa.
| Plan | Writes / day | Passport reads / day |
|---|---|---|
| Free | 100 | 100 |
| Basic | 200 | 200 |
| Starter | 350 | 350 |
| Growth | 500 | 500 |
| Scale | 1,000 | 1,000 |
| Pro | 2,000 | 2,000 |
| Enterprise | Unlimited (negotiated) | Unlimited |
When you hit either ceiling the response is 429 Too Many Requests with a body like { "error": "API rate limit: 500 writes/day via /api/v1. Currently 500 today; requested 1. Retry tomorrow (UTC) or upgrade your plan." }. The window resets at 00:00 UTC; we don't support rolling windows because they make the limit harder to reason about downstream.
A separate quota — maxDpps — caps total active DPPs in your workspace and is enforced via a 402 response with an overage_required body when the plan supports per-passport overage. See the Create a passport endpoint for the overage flow.
What we don't support (yet)
OAuth 2.0 client-credentials, scoped sub-keys, and IP allow-listing are all on the roadmap but not shipped. If you need any of them today, mint a new API key per integration so you can revoke at the integration level — that's the workaround.