Search
Reference for POST /v1/search, the unified search endpoint.
POST https://api.getmux.io/v1/search
Runs a search through one or more providers and returns normalized results. Requires an API key (mux-...). Management keys get 403 wrong_key_type.
Request body
| Field | Type | Default | Description |
|---|---|---|---|
query |
string | required | The search query, 1 to 2,000 characters. |
model |
string | "auto" |
A model id such as exa/auto, or "auto". See Models. |
models |
string[] | none | Fallback order, at most 5 model ids. Takes precedence over model. |
max_results |
integer | 10 |
Number of results, 1 to 100. Capped to the model's own maximum (100 for Exa, 50 for Parallel and Keenable). |
include_domains |
string[] | none | Only return results from these domains (subdomains included). |
exclude_domains |
string[] | none | Drop results from these domains. |
published_after |
string | none | Only results published on or after this date, YYYY-MM-DD. |
published_before |
string | none | Only results published on or before this date, YYYY-MM-DD. Not applied by Parallel models. |
content |
string | "snippet" |
"snippet" or "full". |
provider_options |
object | none | Raw provider fields merged into the upstream request. See Models. |
Unknown fields are rejected with 400 invalid_request, and so are values outside the ranges above. The TypeScript SDK uses camelCase for these (maxResults, includeDomains, excludeDomains, publishedAfter, publishedBefore, providerOptions); the Python SDK uses the snake_case names shown here.
Response
{
"id": "req_9fVx2kQ0b1c3dEfG",
"model": "exa/auto",
"provider": "exa",
"query": "open source vector databases",
"results": [
{
"title": "A guide to open source vector databases",
"url": "https://example.com/vector-dbs",
"snippet": "Milvus, Qdrant and Weaviate … compared on recall and cost",
"content": null,
"published_date": "2026-05-02"
}
],
"usage": { "cost_usd": 0.007, "results": 1, "latency_ms": 1180, "byok": false },
"attempts": [{ "model": "exa/auto", "source": "platform", "status": "ok" }]
}| Field | Description |
|---|---|
id |
Request id (req_...). Also returned in the x-mux-request-id header. |
model |
The model that served the request. Also in the x-mux-model header. |
provider |
exa, parallel or keenable. |
query |
Your query, echoed back. |
results[].title |
Page title, or null. |
results[].url |
Result URL. |
results[].snippet |
Relevant excerpt(s), or null. |
results[].content |
Longer text when content: "full" and supported, otherwise null. |
results[].published_date |
YYYY-MM-DD, or null if unknown. |
usage.cost_usd |
What this request cost. 0 for a free BYOK request. |
usage.results |
Number of results returned (after domain filtering). |
usage.latency_ms |
Time spent in the provider call that succeeded. |
usage.byok |
true if your own provider key served the request. |
attempts |
Every model tried, in order. See below. |
attempts
Each entry has:
model: the model id.source:"platform"(Mux's provider account) or"byok"(your own key). May be absent when a model was skipped because its provider is not available.status:"ok","error"(the provider call failed and was refunded) or"skipped"(not called, for example because of insufficient credits or a key limit).error: present forerrorandskipped, with the reason.
The last entry is the one that succeeded. Upstream calls time out after 15 seconds, and a timeout counts as a failed attempt.
Response headers
| Header | Value |
|---|---|
x-mux-request-id |
Same as id. Include it when contacting support. |
x-mux-model |
Same as model. |
Examples
Filter by domain and date
curl https://api.getmux.io/v1/search \
-H "Authorization: Bearer $MUX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "gpu supply chain constraints",
"model": "exa/auto",
"max_results": 10,
"include_domains": ["reuters.com", "ft.com"],
"published_after": "2026-01-01"
}'Exclude noisy sources
curl https://api.getmux.io/v1/search \
-H "Authorization: Bearer $MUX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "best static site generators", "exclude_domains": ["pinterest.com", "quora.com"]}'Fallbacks across providers
curl https://api.getmux.io/v1/search \
-H "Authorization: Bearer $MUX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "postgres connection pooling", "models": ["exa/fast", "parallel/fast", "keenable/pro"]}'Billing for a request
The price is the model's list price for the number of results requested (after capping to the model's maximum). Extra results beyond the first 10 cost extra on Exa and Parallel. The amount is reserved before the provider is called and refunded if the call fails. A request that is rejected, skipped or refunded costs nothing. See Pricing.
Errors
| Status | Code | When |
|---|---|---|
| 400 | invalid_request |
Bad JSON, unknown field, or a value out of range. |
| 400 | unknown_model |
A model id isn't recognized. |
| 401 | invalid_api_key, key_disabled, key_expired |
Authentication failed. |
| 402 | insufficient_credits |
Not enough credits for any attempted model. |
| 402 | key_limit_exceeded |
The API key's credit limit would be exceeded. |
| 403 | wrong_key_type |
You used a management key. |
| 502 | all_providers_failed |
Every attempt failed. Includes attempts. |
The full list is on the Errors page.