Errors

An error response has a JSON body. Match on error.code, not on the message. The status tells you what kind of fix to make.

What to do

Status What to do
400 Change the request. No offer can serve it as it is.
401 Send a valid key. See API keys.
402 Add funds, raise the limit, or lower the token limit.
403 Use a key with the right scope, or change the request.
404 Check the name. GET /v1/models lists your models.
409 Use a new idempotency-key for a new body.
413 Send less data. See Modalities.
429 Wait for Retry-After, then send the request again.
503 Send it again later. Some codes need a change; the tables say which.
500 Send it again. If it repeats, give the job id in the message to support.

When the auction refuses a request, eligibility.excluded lists each offer that it left out and why. See Exclusion reasons.

Error format

{
  "error": {
    "message": "`reasoning.effort` is not supported by any offer for kimi-k3",
    "type": "liquid_error",
    "code": "unsupported_parameter",
    "param": "reasoning.effort",
    "eligibility": { "excluded": [ … ] }
  }
}
Field Description
code Machine-readable error code. Match on this.
message Human-readable description.
param The request field that the error names, if any.
eligibility Present when the auction refused the request. Lists each excluded offer and the reason.
auto On no_eligible_offer for an Auto request: what Auto ranked by. See Auto Router.
binding_rule On no_eligible_offer when a provider allowlist left no offer.
fixes On no_eligible_offer: what to change. See Fixes.
provider On provider_failed, request_rejected and tools_unsupported: the awarded provider.

A 502 or 504 with an HTML body comes from the network in front of the exchange, not from the exchange.

POST /v1/messages returns the Anthropic format, {"type": "error", "error": {"type": ..., "message": ...}}. An auction error keeps the code, param, eligibility, auto, binding_rule and provider fields next to type and message.

HTTP status Anthropic error.type
400 invalid_request_error
401 authentication_error
403, 451 permission_error
404 not_found_error
413 request_too_large
429 rate_limit_error
502, 503 overloaded_error
other api_error

Error codes

Authentication

Status Code Description
401 invalid_api_key Missing, unknown, revoked or expired API key.
403 insufficient_permission The key's scope does not cover the endpoint.
403 address_not_allowed The key is restricted to other source addresses.
403 impersonated_session An operator views the account, and the request would change it.
451 jurisdiction_restricted The request came from an unavailable location, or through Tor. See Regional availability.
503 identity_provider_unavailable The exchange could not verify a browser session.
401 unauthenticated Provider endpoints: missing or invalid provider key.

Request

Status Code Description
400 invalid_request The body cannot be parsed, or a field is not valid. param names the field. A removed exchange field gets this code. See Purchasing rules.
400 conflicting_parameters An exchange rule is set in the flat form and in a group with different values. The message names both fields. See Purchasing rules.
400 tools_unsupported The awarded provider cannot run the request with tools. Remove tools.
400 request_rejected The awarded provider refused the request. The message is its reason.
400 invalid_header A purchasing header cannot be parsed.
400 unsupported_parameter No offer for the model supports a parameter. param names it. See below.
400 unsupported_content No offer can serve a content part, or /v1/responses does not read an input item. The message gives its path, such as messages[0].content[1].
400 unsupported_model An image or speech request named a router model that ranks by price. Name the model, or use a router model that ranks by Auto.
400 unsupported_rule An image or speech request had a rule that limits a price or a speed in tokens, such as exchange.rank.cost_tier. param names it.
413 request_too_large The body is over 20 MB (the default limit). See Modalities.
404 model_not_found The model is not a router model, and no offer quotes it.
409 idempotency_conflict The idempotency-key was reused with a different body.
409 idempotency_no_result The exchange saw the idempotency-key before, but the first request produced no receipt.
429 rate_limited Too many requests from the address, key or workspace, or a guardrail rate limit refused the call. Retry-After gives the seconds to wait.
503 overloaded The exchange is at its limit of work, or its database is too busy. It charged nothing. Retry-After gives 1 to 5 seconds.
400 invalid_end_user The end-user id is empty, over 512 characters or not printable ASCII.

unsupported_parameter also applies to these cases:

Models and strategy

These codes come before the auction.

Status Code Description
400 basket_requires_models architect.basket needs exchange.candidates.models.allow. Send the models, or [] for every listed model.
400 address_takes_no_basket The model is one model, and the request also sent exchange.candidates.models.allow. Remove one.
400 basket_names_router An entry in exchange.candidates.models.allow is a router model or architect.basket. Use exchange.rank.strategy to rank.
400 invalid_basket An entry in exchange.candidates.models.allow is blank.
400 strategy_conflicts_with_address The strategy kind does not match the model, such as auto with a model. Send architect.basket.
400 invalid_price_band exchange.rank.strategy.price_band_bps is above 10000.
403 key_policy_violation The request is outside the preset of the API key: no model matches, or the exchange.rank.workload_profile differs.

Auction

The price cap is the most that a job can cost. The exchange sets it before the first token.

Status Code Description
400 no_eligible_offer The request, or the rules of the key or workspace, excluded every offer. Do not retry. Change the request.
503 no_eligible_offer No offer met the rules, and a wait can change that. For example, an offer failed a recent job. See eligibility.excluded.
403 no_eligible_offer A provider allowlist of the key or of a guardrail matches no provider that sells the model. binding_rule names it. Do not retry.
503 model_unavailable No seller can serve the named model now. param is model. Retry-After is 30. Retry later, or select another model from GET /v1/models.
402 insufficient_balance The cheapest eligible cap is more than the workspace balance. needed_usd and balance_usd give both amounts.
402 budget_exhausted The key reached its spending limit, or a guardrail budget is spent. Jobs in flight count at their price cap.
402 deposit_required The workspace holds only free credit, and keys of several such accounts send requests from this address. Add funds.
403 guardrail_violation The request is outside a workspace guardrail. See Guardrails.
403 content_blocked A guardrail blocks the request because its text matched a detector. See Guardrails.
503 guardrail_unavailable The router could not read the workspace guardrails, so it refused the call. Retry later.
403 pin_not_permitted A key that cannot pin offers sent x-liquid-pin-offer.
503 provider_failed The awarded provider failed, or the exchange could not reach it. If the provider refused the request, the code is tools_unsupported or request_rejected.
404 not_found The job does not exist or belongs to another workspace.

If an unserved parameter is the only reason for every exclusion, the error is 400 unsupported_parameter.

When a provider fails

If the awarded provider fails before any output, the exchange releases the hold and tries the next offer.

After any output, or if the provider may still run the job, the exchange tries no other offer. You get one cap and one charge.

When an allowlist leaves no offer

An offer can serve the model while a provider allowlist matches none of the providers. The no_eligible_offer error then has error.binding_rule.

binding_rule The allowlist
allowed_providers exchange.candidates.providers.allow in the request, or in the preset it names.
key_allowed_providers exchange.candidates.providers.allow in the preset of the API key. Use another key.
guardrail_allowed_providers exchange.candidates.providers.allow in a workspace guardrail. Change it in Guardrails.

Auto

These codes refuse a request that Auto ranks. See Auto Router.

Status Code Description
503 auto_unavailable Auto is off on this exchange, or it has no score snapshot yet.
400 auto_version_unknown The mode version is not defined. Send 1, 2, 3, 4 or 5.
400 auto_requires_price_bound No price bound. Send exchange.rank.cost_tier, exchange.limits.price.output_usd_per_mtok, exchange.cap_usd or x-liquid-cap-usd.
400 auto_preference_unsupported The mode version does not accept the preference. Version 1 accepts only premium; version 2 accepts all three.
400 auto_policy_unsupported The same, for a preference sent as exchange.policy or x-liquid-policy.
400 auto_pin_unsupported The request sent x-liquid-pin-offer.
400 preferred_providers_with_auto The request sent exchange.candidates.providers.prefer or provider.order. Auto ranks by score.
400 auto_reasoning_unsupported Auto has no scores for the requested reasoning effort.
503 auto_scores_stale The exchange's copy of the scores is older than its limit.

A no_eligible_offer error for an Auto request also has error.auto: the decision that Auto made before the rules left no offer.

Ranking axis

A model-name suffix (smartest, fastest or cheapest) or a smartest strategy can return these codes. See Axis routing. smartest is Auto mode version 4, so it can also return the Auto codes.

Status Code Description
400 smartest_needs_several_models smartest needs more than one model. Name a creator, a router model, a basket or a preset, or use fastest.
400 axis_conflict The model name and exchange.rank.strategy, x-liquid-policy or exchange.candidates.creators.allow ask for different rankings.
400 ambiguous_scope The name before the axis is both a served model and a creator. Send architect.basket with a pattern, such as deepseek-*.

Provider endpoints

A buyer key does not reach these seller endpoints.

Status Code Description
400 invalid_registration deployment_name, precision and region are required.
400 invalid_bands max_input_tokens and, if stated, max_output_tokens must be positive.
404 no_model The registration does not exist or belongs to another provider.
409 not_listed The exchange has not listed the registration.

Reservations

You get these codes when a preset names a reservation. See Reservations.

Status Code Description
404 reservation_not_found This workspace does not have the reservation contract that the preset names.
409 reservation_not_serving The reservation does not serve this month, and the preset names no other model. The term has not started, no deployment is linked, or the month is suspended.
429 reservation_pool_used This month's pool is used, and the preset names no other model. Add overflow models, or wait for next month.
429 reservation_rate_limited You passed the contract's tokens or requests a minute, and the preset names no other model. Retry after Retry-After, or add overflow models. The x-ratelimit-* headers show the limit.
400 reservation_needs_price_ranking The preset ranks a reservation by Auto, which has no score for it. Rank by price or by speed.

Exchange

Status Code Description
503 storage_unavailable A required exchange service is unavailable. The exchange did not process the request. Send it again.
500 internal_error Unexpected failure. If the request has a job, the message includes the job id.

Fixes

Each entry in fixes is one change. reason is the exclusion reason, offers is the count of offers it left out, and message says what to change. The message of the error holds the same text, because many clients show only that field.

The exchange tests each change before it answers. It drops the one rule and ranks the request again. admits lists the providers that can then win. estimate_nanos is the lowest charge, in nano-USD (one USD is 1,000,000,000), that you can expect for this job at one of them. The charge at settlement follows the tokens that the job uses.

The message says What the test found
Any one of these works Each entry is enough alone, and has admits.
no single change The exchange tested each entry, and none is enough alone. Make more than one.
Change one of these The exchange did not test each entry. An entry may not be enough alone.

owner says who can make the change. A field of the request cannot widen a rule of a key preset or a guardrail.

owner.kind Who changes it param and header
request The sender of the request. Name the field to set, when one field fixes the reason.
key_preset An administrator of the workspace, in the preset that owner.name names. Absent.
guardrail An administrator of the workspace, in the guardrail that owner.name names. owner.on_key is true when the guardrail is linked to this key. Absent.

owner is absent when the state of the market caused the reason.

Exclusion reasons

Each entry in eligibility.excluded has provider, offer_id, reason and sometimes detail. The tables group the reasons by what you change.

Change the model or the provider

Change a price limit

Change a speed limit

Change the request itself

Change a data rule

Nothing to change

Auto has no score

Output limits

max_tokens is a maximum for the answer. If every offer is excluded, and output_bound_unsupported or context_too_large excluded at least one, the auction runs again. It tries a lower max_tokens for each of those offers, from the largest value to the smallest.

The exchange calculates the cap from the lower value. An answer that reaches it stops with finish_reason: "length" (stop_reason: "max_tokens" on the Anthropic endpoint).

A request with no limit (max_tokens, max_completion_tokens or max_output_tokens) starts at 32,768 tokens. If the cap or your balance excludes all offers, the exchange halves that limit until an offer fits, down to 1,024 tokens. It never changes a limit that you set.

Reasoning models

The thinking of a reasoning model counts toward max_tokens, and the exchange bills it as output.

Tool calls

If the request sends tools, the exchange checks each tool call in the answer. A call is bad when it has one of these faults:

Fault Meaning
invalid_json The arguments are not JSON.
unknown_name The name is not one of the tools in the request.
schema_mismatch The arguments break the schema of the tool.

The receipt has the counts in answer_checks.tool_calls, answer_checks.tool_call_errors and answer_checks.tool_call_faults.

Tool-call markup. Some providers do not turn the calls of a model into tool_calls, and your agent loop stops. The exchange sets answer_checks.tool_markup to 1 when the request sent tools, the answer has no tool call, and the text holds DeepSeek, Hermes, Qwen or Kimi markup. It keeps the answer and records the markup for the deployment.

Structured output

If you send response_format with json_object or json_schema, the exchange checks the answer when the job ends. json_object asks for one JSON value. json_schema also asks that the value matches your schema. On POST /v1/messages it checks output_config.format, and on POST /v1/responses it checks text.format.

The result is in exchange.answer_checks.structured_output, on the last chunk of a stream.

result Meaning
passed The answer is JSON, and for json_schema it matches the schema.
not_json The answer is not one JSON value. Text around the value, or a code fence, gives this result.
schema_mismatch The answer is JSON but breaks the schema. keyword names the JSON Schema keyword, such as required.
cut The answer stopped at max_tokens. Send the request again with a larger max_tokens.
refused The answer has no text, or the model refused.
unchecked The exchange did not check the answer: only tool calls, or the schema or answer is too large or invalid.

Only not_json and schema_mismatch count against the provider.

If the answer writes more than 1,024 whitespace characters in a row outside a JSON string, the exchange stops it and counts it against the provider. A request that is not streamed goes to the next offer. A stream fails with provider_failed, and you pay nothing.

The receipt keeps the result and the keyword, not the path of the failed field.