Search
Unifies web, neural/semantic, and keyword search behind one schema: a query in, a ranked list of results out.
POST/api/v1/search
The contract is identical across providers, so you switch engines (Exa, Tavily, Serper, Brave, Linkup, …) by changing only the model string. No standard exists for search yet - this is SearchRouter's canonical shape.
Request
| Parameter | Type | Required | Description |
|---|---|---|---|
| model | string | required | Model slug, e.g. exa/neural. Or use models for cross-model fallback. |
| query | string | required | The search query. |
| search_type | "web" | "neural" | "keyword" | "auto" | optional | Search mode. Defaults to auto. |
| num_results | integer | optional | Number of results to return. Default 10. |
| include_content | boolean | optional | Fetch full page text where the provider supports it. Default false. |
| include_domains | string[] | optional | Restrict results to these domains. |
| exclude_domains | string[] | optional | Exclude these domains from results. |
| start_published_date | string | null | optional | ISO 8601 lower bound on publish date. |
| end_published_date | string | null | optional | ISO 8601 upper bound on publish date. |
| provider | object | optional | Routing preferences. See Routing. |
json
{
"model": "exa/neural",
"query": "best vector databases for RAG 2026",
"search_type": "auto",
"num_results": 10,
"include_content": false,
"include_domains": ["arxiv.org"],
"exclude_domains": [],
"start_published_date": null,
"end_published_date": null,
"provider": {
"order": ["exa", "tavily"],
"allow_fallbacks": true,
"sort": "price"
}
}Response
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | optional | Unique request id. |
| model | string | optional | The resolved model slug. |
| provider | string | optional | The provider that actually served the request. |
| search_type | string | optional | The search mode used. |
| results | object[] | optional | Ranked result objects (see below). |
| usage | object | optional | { requests, results, cost } - cost in USD. |
Result object
| Field | Type | Required | Description |
|---|---|---|---|
| title | string | optional | Result title. |
| url | string | optional | Canonical URL. |
| snippet | string | optional | Short extract. |
| content | string | null | optional | Full page text when include_content is set and supported. |
| score | number | null | optional | Relevance score, or null for providers that don't return one. |
| published_date | string | null | optional | ISO 8601 publish date or null. |
| author | string | null | optional | Author, when available. |
| raw | object | optional | Original provider payload, for debugging. |
json
{
"id": "sr-gen-abc123",
"model": "exa/neural",
"provider": "exa",
"search_type": "neural",
"results": [
{
"title": "Comparing Vector Databases",
"url": "https://example.com/vdb",
"snippet": "A short extract...",
"content": null,
"score": 0.87,
"published_date": "2025-11-02",
"author": null,
"raw": { }
}
],
"usage": { "requests": 1, "results": 10, "cost": 0.005 }
}ⓘNormalization. Adapters map provider fields into this shape - Exa's
text → content, dates normalized to ISO 8601, and a null score for engines (Brave/Google/Linkup) that don't rank. The untouched provider payload is kept under result.raw.Examples
cURL
bash
curl https://searchrouter.ai/api/v1/search \
-H "Authorization: Bearer $SR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "exa/neural",
"query": "best vector databases for RAG 2026",
"num_results": 10
}'Python
python
import os, requests
resp = requests.post(
"https://searchrouter.ai/api/v1/search",
headers={"Authorization": f"Bearer {os.environ['SR_API_KEY']}"},
json={
"model": "exa/neural",
"query": "best vector databases for RAG 2026",
"num_results": 10,
},
)
resp.raise_for_status()
for r in resp.json()["results"]:
print(r["score"], r["title"], r["url"])JavaScript
javascript
const resp = await fetch("https://searchrouter.ai/api/v1/search", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SR_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "exa/neural",
query: "best vector databases for RAG 2026",
num_results: 10,
}),
});
const { results } = await resp.json();
results.forEach((r) => console.log(r.score, r.title, r.url));