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.
| Model | Per 1,000 requests | Included results | Extra result | Latency |
|---|---|---|---|---|
exa/instantExa instant, lowest-latency neural search | $7.00 | 10 | +$1.00 / 1k | ~300ms |
exa/fastExa fast | $7.00 | 10 | +$1.00 / 1k | ~500ms |
exa/autoExa auto (default, best general quality) | $7.00 | 10 | +$1.00 / 1k | ~1s |
exa/deepExa deep multi-query search | $12.00 | 10 | +$1.00 / 1k | ~5s |
parallel/turboParallel turbo, ~200ms | $1.00 | 10 | +$1.00 / 1k | ~200ms |
parallel/fastParallel fast, <1s | $1.00 | 10 | +$1.00 / 1k | ~800ms |
parallel/basicParallel basic | $5.00 | 10 | +$1.00 / 1k | ~1s |
parallel/advancedParallel advanced, highest quality excerpts | $5.00 | 10 | +$1.00 / 1k | ~3s |
keenable/proKeenable pro index | $10.00 | 10 | none | ~700ms |
keenable/realtimeKeenable realtime index | $10.00 | 10 | none | ~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/modelsEach 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:
parallel/fastexa/autokeenable/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_domainsandexclude_domains(matching the domain and its subdomains, ignoring a leadingwww.). Because filtering happens after the provider answers, you may get fewer results thanmax_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_beforeand Parallel. Parallel's search has no upper date bound, sopublished_beforeis not applied when a Parallel model serves the request. Use an Exa or Keenable model if you need it.max_resultsis 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_dateisnullwhen the provider doesn't report one.
Snippets and full content
content controls how much text comes back:
"snippet"(default): short, relevant excerpts insnippet."full": also fillscontentwith 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_optionsis 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 asnumResultsfor Exa) can produce unexpected results, and options written for one provider will be ignored or rejected by another, which matters if you also usemodelsfallbacks. Merging is shallow: for nested objects, your value replaces Mux's value entirely.