Errors
The error envelope and every machine code with its HTTP status, what it means, and what your client should do about it.
View as MarkdownEvery error is JSON with the same two-field envelope: a stable machine code for your code to branch on, and a human sentence for logs and messages.
{
"error": "insufficient_credits",
"detail": "This generation costs 35 credits but your balance is 12."
}
error values are stable identifiers — match on them, not on detail, which can change wording at any time.
curl -s https://api.figgshield.ai/api/generations/create/ \
-X POST \
-H "Authorization: Bearer $FIGGSHIELD_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "model": "kling-video", "prompt": "..." }' | jq -r .error
Machine codes
| Code | HTTP | Meaning | What to do |
|---|---|---|---|
validation_error | 400 | The request body is malformed or a value is out of range — bad params for the model, a top-up under $50, a key name over 64 characters. | Fix the request. detail names the offending field. Do not retry unchanged. |
invalid_api_key | 401 | The API key is unknown or revoked, or the Authorization/X-API-Key header is malformed. | Check the key was copied in full (figg_ + 40 hex). If revoked, create a new key in Account → API keys. Do not retry with the same key. |
insufficient_credits | 402 | Your balance cannot cover the generation’s cost — including the case where an automatic top-up was attempted and its payment failed. | Top up, enable auto top-ups, or wait for the next monthly grant. |
subscription_required | 402 | The account has no active subscription — required for generations and top-ups. | Subscribe via POST /api/billing/checkout/ or in the app, then retry. |
admin_required | 403 | A non-staff account called a staff-only endpoint such as GET /api/admin/metrics/. | Not retryable — the endpoint requires a staff account. |
not_found | 404 | No such resource, or it belongs to another account — objects are owner-scoped, so someone else’s generation UUID also returns this. | Check the UUID and the account the key belongs to. |
parallel_limit_reached | 409 | As many generations already in flight as your plan allows. | Poll until one finishes, then retry. jobs in the usage summary shows in-flight versus limit. |
rate_limited | 429 | Too many requests. | Back off exponentially and retry. Polling generation detail more often than every 2 seconds serves no purpose anyway. |
model_unavailable | 503 | The requested model (Kling or Nano Banana 2) is offline or its provider is not responding. | Check GET /api/models/ for status; retry later. Nothing was charged. |
Over MCP, the same conditions surface as tool errors — for example a generate_video call returns an insufficient_credits or subscription_required error rather than an HTTP status.
Handling guidance
- 4xx except 409/429 — a client-side problem; retrying the identical request will fail identically. Fix the request, the key, the balance or the subscription first.
- 409 and 429 — transient by design; retry after a delay (poll for a free slot on 409, exponential backoff on 429).
- 503
model_unavailable— transient on the provider side; no charge was made. Retry later. - Failed generations are not errors at request time. A job that is accepted (
201) but later endsfailedreports its reason inerror_messageon the generation object, and its credits are refunded automatically.