Developer API

Errors, limits and billing

Error codes, a debugging order, rate and spend limits, and how the balance is charged.

Error shape

Every error uses OpenAI's format:

{
  "error": {
    "message": "API key is missing the \"images\" scope (it has: chat, responses, embeddings). Grant it on the key, or create a new key with this scope.",
    "type": "permission_error",
    "code": "developer_api_scope_denied",
    "param": null,
    "detail": {
      "requiredScope": "images",
      "grantedScopes": ["chat", "responses", "embeddings"]
    }
  }
}
Read message and detail first. On 4xx responses those two fields say exactly what to do next: which scope is missing, which task to poll, which parameter is wrong. Don't guess from code alone.

Common error codes

codeHTTPMeaning
invalid_api_key401Wrong or revoked key. Check you copied all of it
api_key_disabled401The key was disabled
api_key_expired401The key expired
api_key_ip_not_allowed403Your egress IP is not on this key's IP allowlist
developer_api_scope_denied403The key lacks the scope this endpoint needs — see below
model_not_allowed403The key has a model allowlist that excludes this model
model_not_found404No such model, or your account cannot use it. Call GET /v1/models
insufficient_credits403Not enough balance. detail carries the amount needed and your balance
model_pricing_required503The model has no price configured — contact an administrator
rate_limit_exceeded429A rate or quota limit was hit; back off and retry
daily_spend_limit_exceeded429This key's daily spend cap was reached
monthly_spend_limit_exceeded429This key's monthly spend cap was reached
image_generation_timeout504Image wait timed out, but the task is still running — use detail.taskId
upstream_unavailable502 / 503The upstream model provider failed; retryable
bad_request400Bad parameters; message names the field

Scopes

Each key carries a set of scopes that decide which endpoints it can reach:

ScopeEndpoints
chat/v1/chat/completions
responses/v1/responses
embeddings/v1/embeddings
images/v1/images/generations, /v1/tasks (images)
videos/v1/videos, /v1/tasks (video)

New keys get all of the above by default. The audio scope has no endpoint behind it yet.

GET /v1/models is filtered by scope too — a chat-only key won't see image models in the list. So "my model isn't in the list" is usually a scope problem, not a missing model.

Limits

Each key can carry its own:

  • RPM — requests per minute
  • Daily request count
  • Daily spend cap / monthly spend cap
  • Model allowlist — only the listed models
  • IP allowlist — only calls from the listed addresses

Individual models may also carry daily quotas (request counts, image counts). Hitting one returns 429 rate_limit_exceeded; the message says which limit it was.

Billing

Calls are charged against your account balance — the same balance the built-in AI uses in the BotHub apps.

  • Chat / embeddings — per token, with separate input, output and cache-hit rates
  • Images — per image
  • Video — per the model's configured billing unit (duration and so on)

Incoming requests reserve a deposit first, then settle against actual usage once finished; anything beyond the deposit is still charged. That's why the balance sometimes dips and then partially returns — it is working as intended.

When the balance is short you get insufficient_credits, with the required amount and your current balance (in cents) in detail:

{
  "error": {
    "code": "insufficient_credits",
    "detail": { "requiredFen": 320, "balanceFen": 95 }
  }
}

The easiest place to check usage is the same screen where you created the key — "External Access" in the app lists each key's request count, token count and spend over the last 7 days.

Debugging order

Work through this list — the first two steps catch most problems:

  1. Does GET /v1/models work?
    • 401 → a key problem (truncated, revoked, expired)
    • It works but your model isn't listed → a scope or account permission problem
  2. Model is listed but the call fails? Check its endpoints field — an image model will never answer on /v1/chat/completions
  3. 403? Read message: it says whether the missing piece is a scope, the IP allowlist, or balance
  4. 429? Could be RPM, daily requests, a spend cap or a model quota; message says which. Back off and retry
  5. 504 on image generation? Nothing failed — fetch the result with detail.taskId via GET /v1/tasks/{id}, and raise your client timeout
  6. 502 / 503? Upstream provider trouble; retry after a backoff