Authentication
API keys, header shape, and the trust boundary between your server and ours.
Header shape
Every request to api.untangledapi.com carries the API key in the x-api-key header:
curl https://api.untangledapi.com/v1/extract/invoice \
-H "x-api-key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "content-type: application/json" \
-d '{ "document": { "text": "..." } }'Untangled does not accept Authorization: Bearer ... for API key auth on /v1/extract/* — that header is reserved for dashboard JWTs (your own end-user code never needs it).
Where keys come from
Keys are issued from the dashboard at /dashboard/keys. Each key is shown exactly once at creation time. After you close the reveal modal, the raw value is gone — we only retain a hashed copy plus a key_prefix (sk_live_xxxx) so you can identify the key in the dashboard.
If you lose a key, revoke it and create a new one. There is no recovery flow.
Where keys belong
- Server-side environment variables (
UNTANGLED_KEYin.env, GitHub Actions secrets, Vercel project env, etc.). - Never in client-side JavaScript bundles.
- Never in committed source files — even
.env.example. - Never in Slack, screenshots, or screen-share recordings.
The dashboard reveals each key on a non-dismissable modal with a copy button — that flow is intentional friction so you copy once into a secrets manager.
Rotation
Revoke from /dashboard/keys (the Revoke button on the row). The hash is invalidated server-side immediately; in-flight requests on that key return 401 unauthorized from then on. Issue a new key under a new name and ship the rotation.
Plan limits
Each plan has its own rate limit and HEU bucket. See Models for the per-plan numbers. Hitting the bucket cap returns 429 too_many_requests with a Retry-After header.
Errors
A bad key returns 401 unauthorized with the body { "error": "invalid_api_key" }. See Errors for the full code list.