Errors
The error envelope, every error code, and how rate limiting behaves.
Errors
Every error response uses one stable envelope:
{
"error": {
"code": "tier_not_found",
"message": "Tier plan 9c1f... does not match a live plan in this organization."
}
}Branch your handling on code - it is part of the API's stability contract. message is human-readable context and may change wording over time. Every response, including errors, carries an X-Request-Id header; include it when contacting support.
Error codes
| Code | Status | Meaning |
|---|---|---|
unauthorized | 401 | Missing or malformed Authorization header. Send Authorization: Bearer fw_live_.... |
invalid_api_key | 401 | The key doesn't match any active key. |
api_key_revoked | 401 | The key exists but has been revoked. |
insufficient_scope | 403 | The key lacks the scope this endpoint requires. |
invalid_request | 400 | Malformed JSON, a failed validation (the message names the field), or a bad cursor/limit. |
not_found | 404 | No end user with that ID in your organization. |
tier_not_found | 422 | A tierPlanId doesn't match a live plan in your organization (archived plans count as not found). |
grant_target_not_found | 422 | A grant's targetId doesn't exist in your organization. |
live_paid_subscription | 409 | The end user has a live paid Stripe subscription on a requested plan. Cancel it in Stripe first; nothing was written. |
rate_limited | 429 | Too many requests - see below. |
server_error | 500 | Something went wrong on our side. Safe to retry; include the X-Request-Id if it persists. |
Validation failures on POST /end-users happen before any write - a request that fails with tier_not_found, grant_target_not_found, or live_paid_subscription leaves no partial account behind.
Rate limits
Each API key may make 120 requests per minute, measured over a sliding 60-second window. When you exceed it:
- The response is
429with coderate_limited. - The
Retry-Afterheader gives the number of seconds until capacity frees up.
Back off and retry after that interval. If you need sustained higher throughput, batch your work (for example, provisioning accepts plans and grants in a single call) or contact support.