Error format
Every error has the same shape, whatever the route:| Field | Meaning |
|---|---|
code | A stable, machine-readable reason. Branch on this, not on the message |
message | A short explanation for people |
details | Present on some errors: the invalid fields, the allowed apps or workspaces, the rate-limit group |
request_id | The id of this request, also sent as X-Request-Id. Quote it when you contact support |
422 invalid_request with details listing each problem:
Status codes
| Status | Codes you may see | What to do |
|---|---|---|
400 | bad_request, invalid_json, invalid_body, model_required | Fix the request |
401 | invalid_key | Check the key; create a new one if it was revoked or expired |
402 | insufficient_credits | Top up the balance, or ask the person to |
403 | insufficient_scope, key_spend_limit, ip_not_allowed, app_not_allowed, model_not_allowed, workspace_not_allowed, plan_required, account_unavailable | Change the key’s permissions or limits, or the plan |
404 | not_found, app_not_found, task_not_found, file_not_found, deployment_not_found, webhook_not_found | The thing does not exist or this key cannot see it |
409 | conflict, domain_taken, app_not_deployed | The current state does not allow it; read it and try again |
413 | payload_too_large | Send a smaller body (see below) |
422 | invalid_request, invalid_domain, invalid_url | Fix the fields listed in details |
429 | rate_limited, too_many_failed_attempts | Wait for Retry-After seconds, then retry |
500 | internal_error | Retry later; report the request_id if it persists |
502, 503, 504 | upstream_error, upstream_unavailable, upstream_timeout | A Jobbit service is busy or restarting; retry with backoff |
Rate limits
Limits are counted per person, so all of one person’s keys share them. They depend on the plan and on the kind of request:| Group | Routes | Free | Go | Plus, Pro, Max |
|---|---|---|---|---|
| Read | GET routes | 120 / min | 300 / min | 600 / min |
| Write | Changes: deploy, env, DNS, webhooks, cancel | 20 / min | 60 / min | 120 / min |
| Inference | Model calls | 20 / min | 120 / min | 300 / min |
| Agent tasks | Creating agent tasks | 5 / min | 20 / min | 60 / min |
| Uploads | File and project uploads | 5 / hour | 20 / hour | 60 / hour |
GET /v1/plan shows the limits of your plan under api_limits.
Every answer tells you where you stand:
| Header | Meaning |
|---|---|
RateLimit-Limit | Requests allowed in the window for this group |
RateLimit-Remaining | Requests left |
RateLimit-Reset | Seconds until the limit is full again |
Retry-After | On 429 only: seconds to wait before retrying |
429 from the token budget has "details": {"group": "tokens"}.
Request sizes
| Route | Largest body |
|---|---|
| Most routes | 1 MB |
| Chat, audio and decisions | 25 MB (gzip accepted) |
| Automation packages | 20 MB |
POST /v1/files | 100 MB |
Retrying safely
- Retry
429,502,503and504with exponential backoff, and always honourRetry-After. - Do not retry
4xxerrors other than429without changing the request. - Creating an agent task is safe to retry with an
idempotency_key: the same key returns the same task instead of starting a second one. - Webhook deliveries can arrive more than once. Each event has a stable
id, so ignore ids you have already handled.