Authentication
ThrustLab's /v1/ API uses bearer-token authentication with two interchangeable credentials.
API keys
Create: from the dashboard's API Keys page — there is no public endpoint for minting keys (a key can't be used to create another key).
The dashboard shows the raw key value exactly once. Store it immediately; it cannot be retrieved later. Only the first 8 and last 4 characters remain visible for identification in the dashboard afterward.
Use: every /v1/ request must include:
Authorization: Bearer key_...
List, retrieve, revoke: manage keys from the dashboard's API Keys page.
Rotation: create a new key, deploy it to your client, then revoke the old key. Dual-key rotation with a grace period is not currently supported — but the three-step manual flow takes under a minute.
Compromise: revoke the affected key immediately from the dashboard's API Keys page. Revocation is eventually consistent for in-flight requests; the next handshake after revocation is rejected.
Web session JWTs (first-party only)
The ThrustLab web app (/dashboard/*) authenticates against /v1/ using the same Authorization: Bearer header but with Django-issued JWTs. This path is only used by the first-party frontend; third-party integrations must use API keys.
Errors
All authentication failures return HTTP 401 with a Stripe-style error envelope:
code | Meaning |
|---|---|
missing_authorization | No Authorization header was sent |
malformed_authorization | Header present but not in Bearer <value> form |
invalid_credential_format | Bearer value is neither a JWT nor key_-prefixed |
invalid_api_key | API key not found, revoked, or owned by an inactive user |
invalid_jwt | JWT failed decode, signature check, or expiration |
invalid_jwt_subject | JWT decoded, but the sub claim does not resolve to an active user |
The same code (invalid_api_key) is returned for "doesn't exist", "revoked", and "owner deactivated" — this is deliberate, to prevent enumeration attacks.
Rate limits
See the Rate limiting section in the stability policy. Current limits: 1000 req/min per credential with a 50-request burst. /v1/health is exempt.