Errors and limits

How to read BeefAPI HTTP errors and what to do when a request fails.

Read the HTTP status first, then the JSON body. Copy the request id from the error message when you ask for help.

Model calls use the error object below. Account endpoints under /api use { "success": false, "message": "..." } instead. How to send a request is in API reference.

Error body

A failed model call returns JSON of this form:

{
  "error": {
    "message": "Invalid token (request id: ...)",
    "type": "new_api_error",
    "code": ""
  }
}

Read error.message first. When the failure has a named reason, error.code is a string such as model_not_found, insufficient_user_quota, or key_site_mismatch. It can be empty, as in the missing-key example above.

Messages returned from global.beefapi.com are always in English, regardless of the Accept-Language header or your account language setting. Match on error.code and the HTTP status in code, not on the message text.

The message includes a request id. Keep that value.

HTTP status

StatusMeaning
401Missing or invalid API key (model calls), or missing system access token (account calls)
402The key or account has no credit left (insufficient_user_quota)
403The credential was accepted, but this request is not allowed (key_site_mismatch, access_denied, or no credit)
404The model ID is not in the set available to this key (model_not_found)
429Too many requests for the current limit, or the upstream channel is busy (upstream_crowded)
502The upstream channel is temporarily unavailable (upstream_unavailable)
5xxThe model did not return a response, or the service was unavailable (upstream_error)

Upstream failures

BeefAPI does not forward raw error text from model providers. When a provider request fails, error.message is a short neutral sentence plus the request id, and error.code is one of:

CodeMeaningWhat to do
upstream_crowdedThe channel serving this model is busy or rate limitedRetry with backoff, or choose another available model
upstream_unavailableThe channel credential or account was rejected by the providerRetry shortly; BeefAPI has recorded the failure
upstream_rejectedThe provider rejected the request for a reason that is not about its shapeRetry once; if it persists, send us the request id
upstream_errorThe provider returned an invalid or empty responseRetry with backoff; if it persists, send us the request id

The only provider text kept verbatim is a 400 / 413 / 422 describing your own request (for example an unsupported parameter or an oversized input), because you can fix that yourself. Everything else is available to support through the request id.

Insufficient USD credit is a separate failure. Look for insufficient_user_quota in error.code, then add credit on Billing.

401 Unauthorized

Missing or wrong API key:

{
  "error": {
    "message": "Invalid token (request id: ...)",
    "type": "new_api_error",
    "code": ""
  }
}

Check:

  1. The value is the full sk-... key copied from API keys, not typed by hand.
  2. OpenAI-compatible calls send Authorization: Bearer sk-....
  3. Anthropic-compatible calls send x-api-key: sk-... plus anthropic-version.
  4. The OpenAI base URL is https://global.beefapi.com/v1 (with /v1). The Anthropic base URL is https://global.beefapi.com (no /v1).
  5. Shell environment variables still pointing at another provider are not overriding the key or base URL.

Account calls without a system access token return 401 with { "success": false, "message": "Unauthorized, not logged in and no access token provided" }. Those calls also need New-Api-User set to your user ID from Account settings.

403 Forbidden

The key or token was recognized, but the request is not allowed. The account may be blocked, or this key may not be permitted to make that call.

key_site_mismatch

API keys are bound to the site that issued them. A key created on global.beefapi.com only works against https://global.beefapi.com/v1; a key created on the Chinese site only works there. Using a key on the wrong host returns:

{
  "error": {
    "message": "This API key was issued for beefapi.com and cannot be used on global.beefapi.com. Send requests to https://beefapi.com/v1 or create a new key on this site (request id: ...)",
    "type": "new_api_error",
    "code": "key_site_mismatch"
  }
}

Fix: either point the client at the API base named in the message, or create a new key on API keys of this site. Credit is not shared between the two sites.

Do not retry a 403 in a tight loop. Confirm the key on API keys, then send one test request.

404 and model_not_found

This is the usual cause: the model string is not in the set available to this API key. A typo has the same result.

{
  "error": {
    "message": "The model \"gpt-5-6-sol\" does not exist or you do not have access to it.",
    "type": "invalid_request_error",
    "code": "model_not_found"
  }
}

Fix:

  1. Copy the model ID from GET /v1/models using that same key. See API reference.
  2. Compare it with the model field you sent. Hyphens, dots, and suffixes must match exactly.
  3. Public prices on Pricing list catalog names. Your key may not include every public name.

429 Too Many Requests

Requests beyond your limit return 429. This is a request limit, not a missing-credit error.

Wait, then try again. If the response includes Retry-After, wait at least that long. Send fewer requests at the same time, then send one request to confirm the path still works.

Insufficient credit

When remaining USD credit cannot cover the request, the body uses code insufficient_user_quota. Add prepaid credit on Billing, then retry.

{
  "error": {
    "message": "Insufficient credit. Current balance: $0.000000. Please top up and try again (request id: ...)",
    "type": "new_api_error",
    "code": "insufficient_user_quota"
  }
}

The HTTP status is 402 when the key itself has no credit left or the account balance is negative, and 403 when the account balance cannot cover the estimated cost of this request. Handle both statuses by checking error.code.

API keys spend account USD credit. Empty credit fails the request.

Timeouts and 5xx

A long or interrupted call can return 500, 502, 503, 504, or 524. The client did not receive a successful response; this does not prove that generation stopped or no usage was charged.

Retry only when sending the same request twice is acceptable. Wait longer between each retry. Do not retry 401, 403, or 404 this way. A completed request that you send again can be charged again.

If timeouts persist, shorten the prompt or switch to a lighter model from GET /v1/models. Current service status is on Status.

Where to look first

Open Usage. Each recorded request shows time, request ID, model, token count, and USD cost.

Compare that row with the request id in the error message. Public prices are on Pricing. Service status is on Status.

Get help

Email support@beefapi.com. Include:

  • The client or SDK you used
  • The model ID
  • The HTTP status
  • The full error JSON, including the request id
  • Whether you called /v1/chat/completions, /v1/responses, /v1/messages, or /api/user/self

Do not send API keys or system access tokens.

Image and video failures

Image calls return image JSON; optional image jobs return job_id. Videos return id. Save these identifiers before polling. A polling response can be HTTP 200 while the task's status is failed; inspect both status layers.

  • For queued or in_progress, wait and poll the same ID. Do not create another task to check progress.
  • For failed, stop polling, read the task's error, and check the credit adjustment in Usage.
  • A 409 when reading an image job result means it is not completed. Read the job status first.
  • A video /content call before completion cannot download the final MP4. Wait for completed.
  • If a signed result link expires, get a fresh video download link from /content; save image results promptly.
  • Unsupported image job routes require the synchronous Images API. Video reference requests above 10 seconds or 720p require different parameters, not retries.

See Images, Videos, and Billing. Include the endpoint and task/job ID when contacting support; never send credentials or signed URLs.

On this page