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 | $4.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 | $4.00 | 10 | none | ~700ms |
keenable/realtimeKeenable realtime index | $4.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 for the model that succeeds. Mux reserves the price of each attempt before calling the provider and refunds it if that call fails 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.
The one exception is a timeout. If a provider hasn't answered after 15 seconds, Mux gives up and moves on, but the provider has almost always finished the search by then and billed for it. That attempt therefore keeps the model's base price (the price for up to 10 results, never the extra-results portion), and the amount is shown as cost_usd on its entry in attempts. Timeouts are rare on every model except exa/deep under heavy load.
If every attempt fails, you get 502 all_providers_failed with the attempts array. Your balance is unchanged unless one of the attempts timed out. 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. Only the options below are accepted; each is added to the upstream request for its provider and ignored for any other provider in your models list. Anything that changes what you'd be billed for (the query, search tier, result count, content and crawl options) or that Mux uses for filtering (domains, dates) can't be set here, and a request that tries gets 400 invalid_request.
| Provider | Allowed options |
|---|---|
| Exa | category, userLocation, moderation, includeText, excludeText |
| Parallel | max_chars_total, client_model, advanced_settings.excerpt_settings, advanced_settings.location |
| Keenable | none yet |
Values are passed to the provider as given; see the Exa and Parallel references for what each accepts. The whole object must stay under 8 KB.
const res = await mux.search({
query: "transformer architecture survey",
model: "exa/auto",
providerOptions: { category: "research paper" },
});Note: option values are not validated by Mux. A value the provider rejects fails that attempt (and is refunded) like any other provider error, and the request moves on to the next model in your list, if any. If you need an option that isn't listed, email support@getmux.io.