# Errors

URL: https://bridge.wekoya.tech/docs/errors
Updated: 2026-11-08

> Every error carries a machine-readable type, so your code can branch on the reason rather than on the message.

Every error carries a machine-readable `type`, so your code can branch on the reason rather than on the message.
Images, music and long Gemini transcriptions can take longer than 20 seconds. Their reply then starts at once, with status 200 and a few leading spaces, to keep the connection open, so an error that comes after that arrives as `{"error": {…}}` in a 200 body. Check for `error` as well as the status.
Status | Type | What it means |
`400` | `invalid_request` | The body or query is malformed. The message names the field. |
`400` | `end_user_required` | Your account requires every request to name an end user, and this one did not. |
`400` | `context_length_exceeded` | The request is too long for the model. For decisions, shorten the state or ask fewer questions. |
`400` | `cache_too_small` | A context cache needs at least 1,024 tokens (more on some models). Short prompts are cached automatically. |
`400` | `cache_model_mismatch` | A cache works only with the model it was made for. Send that model, or "auto". |
`401` | `unauthorized` | The key is wrong, revoked or expired. |
`401` | `guest_key_revoked` | The key that made this guest key was revoked, so the guest key stopped too. Make a new one. |
`403` | `guest_key_not_allowed` | A guest key asked for something outside its uses. Make that call from your server, or allow it in uses. |
`403` | `origin_not_allowed` | A guest key made for certain websites was used from somewhere else. |
`429` | `guest_key_used_up` | A guest key has made all of its max_requests. Get a new one from your server. |
`402` | `insufficient_funds` | Your balance cannot cover the request. The reply names the amount needed. Top up to continue. |
`402` | `key_limit_exceeded` | This key has reached the spending cap set on it (a guest key's max_spend, or a key's monthly limit, which resets on the 1st). |
`402` | `app_budget_exceeded` | This app has reached the monthly budget its account set for it (an app is a key's app_id, or X-Bridge-App). An admin raises it under App budgets; it resets on the 1st. |
`403` | `not_a_member` | X-Wekoya-Org-Strict was sent and you are not in that company, or it is suspended or deleted. Nothing was done or charged. |
`403` | `key_owner_removed` | The person who made this company key has left the company. Make a new key, or have an admin make one the company owns. |
`402` | `end_user_budget_exhausted` | That end user's budget is spent. Top them up, or wait for their period to reset. Your balance is untouched. |
`403` | `insufficient_scope` | The key does not carry the scope for this route. |
`403` | `model_not_allowed` | The key or the end user is restricted to other models. The reply lists what is allowed. |
`403` | `end_user_suspended` | That end user is suspended. Resume them to allow requests. |
`400` | `invalid_provider_key` | The provider rejected the key you tried to save, so it was not stored. |
`503` | `byok_key_rejected` | Your own provider key was rejected (wrong, expired or revoked). Replace it. Wekoya charged nothing. |
`503` | `byok_provider_out_of_credit` | Your provider account is out of credit or over its spend limit. Fix it with the provider; your Wekoya balance was not used. |
`503` | `byok_model_unavailable` | Your provider account cannot run this model (not enabled, or not in the key's region). Enable it with the provider, or route the model elsewhere. Wekoya charged nothing. |
`503` | `byok_rate_limited` | Your provider rate-limited your key. Wait, or raise the limit with them. |
`503` | `byok_key_unreadable` | A stored key could not be decrypted. Save it again. Nothing was charged. |
`402` | `byok_budget_exhausted` | Every key that could serve this model has reached its monthly budget, and wallet fallback is off. Raise a budget, add a key, or allow the wallet. |
`402` | `byok_credits_exhausted` | The only key left is set to use promotional credit only, and that credit is spent or expired. |
`400` | `media_not_supported` | The model cannot read the audio, video or PDF you sent. The message names models that can. |
`400` | `unsupported_media` | That kind of attachment is not accepted: send base64 data or a YouTube link, as a PDF, image, audio or video. |
`400` | `content_policy` | The model declined the request under its safety rules. Rephrase it. |
`400` | `invalid_audio` | The audio could not be read: empty, damaged, or not an audio file. Nothing was charged. |
`400` | `unsupported_language` | The transcription language is not available. Use an ISO code such as "en", or "multi" for mixed languages. |
`400` | `invalid_voice` | There is no voice by that name. List them with GET /v1/audio/voices. |
`413` | `audio_too_long` | The recording is over 60 minutes. Split it into parts. Nothing was charged. |
`413` | `request_too_large` | Too large for one request: an audio file over 25 MB, speech text over 2,000 characters, or a decision request over 512 KB. |
`409` | `no_own_key` | The request (X-Bridge-Billing: own-keys) or a routing rule allows only your own keys, and none can serve this model. |
`409` | `ambiguous_provider_key` | You have more than one key for that provider. Name one as provider:label or by its id. |
`409` | `key_limit` | You already store the most provider keys allowed (10 per provider, 20 in all). Remove one first. |
`404` | `model_not_found` | No such model. Read the catalogue for the current list. |
`404` | `end_user_not_found` | No end user with that id. Create them first, or turn on auto-create. |
`429` | `end_user_rate_limited` | That end user passed their requests-per-minute cap. Retry after a short wait. |
`429` | `rate_limited` | Too many requests. Back off and retry, ideally with jitter. |
`409` | `workload_deployed` | A workload or configuration is serving a deployment. Deploy something else or delete the deployment first. |
`409` | `batch_not_finished` | The batch is still running. Results are ready once its status is completed, failed, cancelled or expired. |
`410` | `cache_expired` | The cache expired or was deleted. Make a new one. |
`400` | `budget_too_low` | A run's budget cannot cover the work it must do to report. The message gives the minimum. |
`429` | `too_many_runs` | Two evaluations or adaptations are already running on this account. |
`429` | `too_many_batches` | Five batches are already running on this account. Wait for one to end. |
`503` | `model_unavailable` | That model is not available right now. Retry, or fall back to another model. |
