Guides

Models and routing

Choose a provider, set fallbacks, and understand how Mux normalizes Exa, Parallel and Keenable.

A Mux model is a provider and one of its search modes, written provider/variant: for example exa/auto, parallel/fast or keenable/pro. The same request body works with every model.

ModelPer 1,000 requestsIncluded resultsExtra resultLatency
exa/instant
Exa instant, lowest-latency neural search
$7.0010+$1.00 / 1k~300ms
exa/fast
Exa fast
$7.0010+$1.00 / 1k~500ms
exa/auto
Exa auto (default, best general quality)
$7.0010+$1.00 / 1k~1s
exa/deep
Exa deep multi-query search
$12.0010+$1.00 / 1k~5s
parallel/turbo
Parallel turbo, ~200ms
$1.0010+$1.00 / 1k~200ms
parallel/fast
Parallel fast, <1s
$1.0010+$1.00 / 1k~800ms
parallel/basic
Parallel basic
$5.0010+$1.00 / 1k~1s
parallel/advanced
Parallel advanced, highest quality excerpts
$5.0010+$1.00 / 1k~3s
keenable/pro
Keenable pro index
$10.0010none~700ms
keenable/realtime
Keenable realtime index
$10.0010none~700ms

The table above is loaded live from GET /v1/models. Prices are per 1,000 requests and include 10 results. Prices are current list prices and can change. You can fetch the same data yourself:

curl https://api.getmux.io/v1/models

Each entry has id, provider, description, pricing (per_1k_requests_usd, included_results, per_1k_extra_result_usd), max_results and typical_latency_ms.

Picking a model

Pass model to use one specific model:

curl https://api.getmux.io/v1/search \
  -H "Authorization: Bearer $MUX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "rust async runtimes compared", "model": "exa/deep"}'

An unknown model id returns 400 unknown_model. If you pin one model and it fails, the request fails (after refunding you); there is no silent substitution.

auto

If you omit model, or pass "auto", Mux tries these in order and returns the first success:

  1. parallel/fast
  2. exa/auto
  3. keenable/pro

auto is a good default when you care about getting an answer more than about which provider gives it.

Fallback lists

Pass models (up to 5) to set your own order. Mux tries each in turn until one succeeds:

curl https://api.getmux.io/v1/search \
  -H "Authorization: Bearer $MUX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "sec filings for acme corp", "models": ["exa/auto", "parallel/basic", "keenable/pro"]}'

When models is set it takes precedence over model. The attempts array in the response shows what was tried:

"attempts": [
  { "model": "exa/auto", "source": "platform", "status": "error", "error": "exa 503: ..." },
  { "model": "parallel/basic", "source": "platform", "status": "ok" }
]

What fallbacks cost

You pay only for the model that succeeds. Mux reserves the price of each attempt before calling the provider and refunds it if that call fails, times out, or is skipped. A model is skipped (not called, not charged) when its price would exceed your balance or the API key's credit limit, so a cheaper model later in the list can still serve the request.

If every attempt fails, you get 502 all_providers_failed with the attempts array, and your balance is unchanged. See Errors.

How providers are normalized

Mux translates your request into each provider's native format and translates the answer back into one shape. Differences you should know about:

Feature Exa Parallel Keenable
Max max_results 100 50 50
include_domains / exclude_domains Native Native One domain native (as site); more handled by Mux
published_after Native Native Native
published_before Native Not applied upstream Native
content: "full" Full page text Excerpts joined together Not available (content is null)

Further details:

  • Domain filters are always enforced. In addition to passing them upstream where supported, Mux filters the returned results by include_domains and exclude_domains (matching the domain and its subdomains, ignoring a leading www.). Because filtering happens after the provider answers, you may get fewer results than max_results.
  • Keenable accepts a single site. If you pass exactly one include domain it is sent natively; with several, Mux filters the results itself.
  • published_before and Parallel. Parallel's search has no upper date bound, so published_before is not applied when a Parallel model serves the request. Use an Exa or Keenable model if you need it.
  • max_results is capped to the model's maximum. Asking for 80 results from a Parallel model returns at most 50, and you are billed for the 50.
  • Dates in results are normalized to YYYY-MM-DD; published_date is null when the provider doesn't report one.

Snippets and full content

content controls how much text comes back:

  • "snippet" (default): short, relevant excerpts in snippet.
  • "full": also fills content with longer text where the provider supports it. See the table above for what each provider returns.

provider_options

provider_options is an escape hatch for provider-specific features Mux doesn't model. Its keys are merged into the top level of the upstream request body, overriding any field Mux set with the same name.

const res = await mux.search({
  query: "transformer architecture survey",
  model: "exa/auto",
  providerOptions: { category: "research paper" },
});

Warning: provider_options is passed through unvalidated and you are billed at the Mux model's price regardless of what it changes. Overriding a field Mux relies on (such as numResults for Exa) can produce unexpected results, and options written for one provider will be ignored or rejected by another, which matters if you also use models fallbacks. Merging is shallow: for nested objects, your value replaces Mux's value entirely.