Errors
Every error response uses the same shape:
{
"error": "Forbidden",
"code": "FORBIDDEN"
}error— human-readable message. Useful for logs; not safe to display to end users verbatim.code— optional machine-readable code. When present, branch on this.
HTTP status codes
| Status | Meaning | Action |
|---|---|---|
400 | Request body or parameters failed validation | Fix the request |
401 | Token missing, malformed, or revoked | Re-authenticate |
403 | Authenticated but not allowed | Check permissions / tier |
404 | Resource not found, or fingerprint has no Artifact yet | Verify the identifier |
204 | Success with no body (e.g. revoke key) | — |
2xx | Success | — |
5xx | Server fault — retry with backoff | Retry then escalate |
Error codes
BAD_REQUEST
Validation failed on the request body or path/query parameters. Common
causes: missing required field, fingerprint not matching
^0x[0-9a-f]{64}$, name outside 1–64 chars on POST /api/v1/api-keys.
MISSING_ORGANIZATION_ID
A required organizationId was omitted on a JWT-authenticated request.
Applies to:
GET /api/v1/api-keys(JWT caller must pass?organizationId=<uuid>)DELETE /api/v1/api-keys/{keyId}(same)
API-key callers don’t hit this — the organization is derived from the key itself and the query parameter is ignored.
UNAUTHORIZED
Authentication is required or the provided token is invalid. Possible causes:
- Missing
Authorizationheader - Wrong scheme (only
Beareris accepted) - JWT expired (re-login)
- API key revoked (mint a new one)
WORKSPACE_FROZEN— the key’s organization was frozen because its owner downgraded or canceled their Enterprise subscription. Keys resume working automatically when the owner re-subscribes.
FORBIDDEN
Authentication succeeded but the caller is not allowed to perform the operation. Common cases:
- Reading Artifacts from a private Mark you’re not a member of (caller is authenticated but not authorized for the resource)
- Creating an Artifact under a Mark you don’t have write access to
- Operating as a non-owner on org-level API key endpoints
API_KEY_ORG_MISMATCH
An API-key-authenticated request targeted a resource outside the key’s
own organization (cross-org mint, sibling-key revoke against another
org, etc.). Surfaces as 403. Use a JWT to act across organizations.
TIER_RESTRICTION
The operation is disabled on the caller’s current subscription tier. Common cases:
- Creating a private Mark on a tier that disallows it
- Hitting daily or lifetime Artifact caps for the Mark’s tier context
The remedy is either to upgrade the tier or wait until the cap resets (daily caps reset at the next UTC midnight). See Tiers & limits.
TIER_LIMIT_REACHED
A tier-driven quota was hit. Specifically:
POST /api/v1/api-keys— non-enterpriseorgs cannot mint keys at all, andenterpriseorgs are capped at 5 active keys.
Resolve by upgrading the organization to enterprise or revoking an
existing key first.
USAGE_UNIT_LIMIT_REACHED
The workspace has no free usage unit available for adding a new member. A workspace ships with 1 usage unit (consumed by the owner); additional usage units are purchased via the per-usage-unit Stripe subscription. See Tiers & limits.
Retry guidance
5xx— retry with exponential backoff (e.g. 1s, 2s, 4s, max 30s, cap at 5 attempts). Use jitter for fleets.4xx— do not retry without changing the request. A retry will produce the same response.429— not currently emitted; tier caps surface as403 TIER_RESTRICTIONor403 TIER_LIMIT_REACHEDinstead.