API reference

Errors

The error format, every error code Mux returns, and which errors to retry.

Errors are JSON with a single error object. code is a stable, machine-readable string; message is for humans and may change. Some errors carry extra fields.

{
  "error": {
    "code": "insufficient_credits",
    "message": "Insufficient credits. Add credits at /v1/credits/checkout.",
    "needed_usd": 0.007
  }
}

Branch on the HTTP status and code, not on message. In the SDKs every non-2xx response throws a MuxError with status, code and message (and the parsed body). See SDKs.

Error codes

Status Code Meaning What to do
400 invalid_request The body isn't valid JSON, has an unknown field, or a value is missing or out of range (for example max_results over 100, a bad date, or an amount outside 5 to 10,000). The message says which. Fix the request. Don't retry unchanged.
400 unknown_model A model id in model or models doesn't exist. Use an id from GET /v1/models.
400 unknown_provider The provider in a provider-keys path isn't exa, parallel or keenable. Fix the provider name.
401 invalid_api_key The Authorization header is missing, isn't Bearer mux-..., or the key doesn't exist or was deleted. Check the key.
401 key_disabled The key has been switched off. Re-enable it or use another key.
401 key_expired The key is past its expires_at. Create a new key.
402 insufficient_credits Your balance can't cover any model that was attempted. Includes needed_usd, the price of the cheapest blocked attempt. Add credits.
402 key_limit_exceeded The request would take this API key past its credit limit. Includes needed_usd. Nothing was charged. Raise or reset the limit, or use another key.
403 wrong_key_type A management key was used to search, or an API key was used on a management endpoint. Use the right kind of key.
404 not_found The key id or provider key doesn't exist in your account. Check the id.
429 rate_limited This API key is sending requests faster than its rate limit. Nothing was charged. The Retry-After header says how many seconds to wait. Slow down, or retry after the delay. The SDKs do this for you.
429 too_many_concurrent_requests The account already has too many searches in flight. Nothing was charged. Wait for some requests to finish, or lower your concurrency.
502 all_providers_failed Every attempted model failed or was unavailable. Includes attempts. You weren't charged. Retry, or add more models to models.
502 stripe_error Creating the Stripe Checkout session failed. Retry shortly.
503 overloaded Every model you allowed is at capacity right now. Nothing was charged. Includes a Retry-After header. Retry shortly, or add more models to models so Mux has somewhere to fall back to.
503 byok_disabled Provider keys can't be stored on this deployment. Contact support.
503 stripe_disabled Credit purchases aren't available. Contact support.
500 internal Something went wrong on our side. Retry with backoff.

insufficient_credits and key_limit_exceeded

Both return 402. When you use models fallbacks, Mux skips any model it can't afford and tries the next one, so you only see a 402 when every model was blocked. If both kinds of block happened, you get key_limit_exceeded.

all_providers_failed

The attempts array shows what happened to each model, which makes this easy to debug:

{
  "error": {
    "code": "all_providers_failed",
    "message": "All providers failed.",
    "attempts": [
      { "model": "exa/auto", "source": "platform", "status": "error", "error": "exa timeout" },
      { "model": "keenable/pro", "status": "skipped", "error": "provider not configured" }
    ]
  }
}

Each failed attempt was refunded, so your balance and the key's limit are unchanged, with one exception: an attempt whose error is a provider timeout (no answer after 15 seconds) keeps the model's base price, because the provider has normally completed the search by then. Such an attempt carries a cost_usd field. See Pricing.

Rate limits

Mux limits how fast one key can search and how many searches one account can run at once, so a runaway loop can't use up shared capacity.

Limit Default Error
Requests per second per API key 20 sustained, bursts up to 40 429 rate_limited
Searches in flight per account 50 429 too_many_concurrent_requests
Calls to one provider at a time Shared across all customers falls back to the next model, then 503 overloaded

Successful search responses include x-ratelimit-limit (requests per second allowed) and x-ratelimit-remaining (requests left in the current burst). Rejected requests include Retry-After. Limited requests are never charged. If you need higher limits, contact us.

Responses without the error format

Requests that never reach the API handlers can get a plain response instead of the JSON error object: an unknown path returns 404, a wrong HTTP method returns 405, and a malformed query string (for example ?limit=abc) returns 400. Check the status first and parse the body only if it is JSON.

Retrying

  • Don't retry 4xx errors (including 402). They won't succeed until you change the request, the key or your balance.
  • 502 all_providers_failed is safe to retry yourself: you weren't charged. The SDKs don't retry it automatically because the gateway has already tried every model you allowed.
  • 500 and other 5xx (except 502) and 429 are retried automatically by the SDKs, up to 2 retries (3 attempts in total) with exponential backoff starting at 300 ms. If the response has a Retry-After header, the SDKs wait at least that long (up to 10 seconds). You can change this with maxRetries (TypeScript) or max_retries (Python).
  • Retrying a search is safe: failed attempts are refunded, and a request that errors before succeeding isn't charged.

Include the x-mux-request-id response header (or the id in the body) when contacting support about a specific request.