Search
Search the web, news or images and get ranked results. Optionally read the top results and get the passages that answer your query, scrape them in any format, or have a short cited answer written from them. Use Search when you want results to choose from; use Research when you want a finished answer with verified citations.
Requires an API key with the search scope. New keys get crawl and scrape by default, so add search when you create the key. Search is synchronous: the search and any page reads share a 25-second budget, and include_answer gets 30 more seconds to write.
curl -X POST "https://xdive.dev/api/orgs/$ORG_ID/search" \
-H "X-API-Key: $XDIVE_API_KEY" -H "Content-Type: application/json" \
-d '{
"query": "rotate API keys without downtime",
"limit": 5,
"freshness": "py",
"search_depth": "advanced"
}'from xdive import XDive
xdive = XDive() # reads XDIVE_API_KEY
response = xdive.search(
"rotate API keys without downtime",
limit=5,
freshness="py",
search_depth="advanced",
)
for result in response["results"]:
best = result.get("passages", [{}])[0].get("text", "")
print(result["rank"], result["url"], best[:120])import { XDive } from "xdive";
const xdive = new XDive(); // reads XDIVE_API_KEY
const response = await xdive.search("rotate API keys without downtime", {
limit: 5,
freshness: "py",
search_depth: "advanced",
});
for (const result of response.results) {
console.log(result.rank, result.url, result.passages?.[0]?.text.slice(0, 120));
}Parameters
| Field | Type | Default | Description |
|---|---|---|---|
query | string | required | The search query. At most 400 characters and 50 words. |
sources | array of strings | ["web"] | Any of web, news, images. Results from several sources are interleaved. |
limit | integer | 10 | Results to return, 1 to 50. |
country | string | none | Two-letter country code to localize results, such as US or DE. |
search_language | string | none | Language code such as en or en-us. |
freshness | string | none | Limit results by publication date. See Freshness. |
safe_search | string | moderate | off, moderate or strict. |
include_domains | array of strings | none | Only return results from these hosts. At most 20. See Domain filters. |
exclude_domains | array of strings | none | Never return results from these hosts. At most 20. |
search_depth | string | basic | basic returns the engine's results. advanced also reads the top results and attaches query-relevant passages and a relevance_score. See Search depth. |
auto_parameters | boolean | false | Infer sources and freshness from the wording of the query when you did not set them. |
scrape | object | none | Scrape the top results. See Scraping results. |
include_answer | boolean | false | Also write a short answer with citations from the top results. Needs an LLM. See Answer. |
Freshness
| Value | Results published |
|---|---|
pd | In the past day. |
pw | In the past week. |
pm | In the past month. |
py | In the past year. |
2026-01-01to2026-06-30 | Between two dates, inclusive, written YYYY-MM-DDtoYYYY-MM-DD. |
Domain filters
Entries are host names such as example.com, without a scheme, path or port. A filter matches the host and its subdomains: example.com matches docs.example.com but not notexample.com. Filters are applied after the engine ranks results, so a narrow include_domains can return fewer than limit results.
Search depth
With search_depth: "advanced", the top 8 web and news results are read in parallel, through the page cache, within 6 seconds. Each result that could be read gains:
page: the page'surl,titleand main-contentmarkdown, so you need no second fetch;passages: up to 3 excerpts most relevant to the query, best first;relevance_score: the score of the best passage.
Results keep the search engine's order. Advanced search does not re-rank them by relevance_score; sort by it yourself if that suits your use. Results that could not be read in time have no passages. Each page read counts as one page against your quota.
Passage scores are BM25 relevance scores of the passage against the query: higher is more relevant, and 0 means no query term in common, so such passages are left out.
Auto parameters
auto_parameters: true fills in parameters you left unset from the query's wording. Words such as "news", "latest", "breaking", "today" or "announced" add news to sources. "today", "yesterday", "breaking", "right now", "this week" or "latest" set freshness to pw; "this month", "recent" or "recently" set pm; the current year written in the query sets py. The parameters used are returned in parameters.
Scraping results
scrape fetches the top web and news results through the scrape pipeline and attaches each one as page, with passages and relevance_score computed from its content.
| Field | Type | Default | Description |
|---|---|---|---|
limit | integer | 3 | Results to scrape, 0 to 5. 0 means the default. |
formats | array of strings | ["markdown"] | Format names, as on Scrape. Format options are not accepted here. |
respect_robots | boolean | true | Skip pages that robots.txt disallows. |
main_content_only | boolean | true | Main-content extraction. |
A result that could not be scraped has scrape_error instead of page. With advanced and Markdown-only scraping, pages already read are reused; with other formats they are fetched again, but a page is never counted twice.
Answer
include_answer: true writes an answer of at most about 150 words from the top results, citing them as [1], [2]. Citation numbers are checked against the sources in code, so the answer cannot cite a page that was not read. If you do not pass scrape, the top 5 results are scraped for it.
The answer needs an LLM configured for your organization. Problems with the answer never fail the search: answer then holds an error instead.
Response
{
"query": "rotate API keys without downtime",
"provider": "brave",
"search_depth": "advanced",
"results": [
{
"id": "4f9c2a7e1b3d5f80",
"source": "web",
"rank": 1,
"title": "Rotating API keys safely",
"url": "https://docs.example.com/security/key-rotation",
"description": "Issue a second key, deploy it, then revoke the first.",
"published_at": "2026-03-02T00:00:00Z",
"page": {
"url": "https://docs.example.com/security/key-rotation",
"title": "Rotating API keys safely",
"depth": 0,
"markdown": "# Rotating API keys safely\n\nKeep two keys active during a rotation..."
},
"passages": [
{
"text": "Keep two keys active during a rotation. Issue the new key, roll it out to every client, confirm traffic has moved, then revoke the old key.",
"score": 6.218,
"start": 412
}
],
"relevance_score": 6.218
},
{
"id": "b07e19d2c4a6f835",
"source": "web",
"rank": 2,
"title": "Zero-downtime credential rotation",
"url": "https://blog.example.org/zero-downtime-rotation",
"description": "A checklist for rotating secrets in production."
}
]
}| Field | Type | Description |
|---|---|---|
query | string | The query as searched. |
provider | string | The search engine used, such as brave or serper; several engines are joined with + (brave+serper) when their results are fused. |
search_depth | string | The search_depth you sent, empty when omitted. |
parameters | object | With auto_parameters: the sources and freshness that were used. |
results | array | The results, best first. |
answer | object | With include_answer: text, citations and confidence, or error. |
Result fields
| Field | Type | Description |
|---|---|---|
id | string | Stable identifier of the result. |
source | string | web, news or images. |
rank | integer | Position in this response, from 1. |
title, url, description | string | As returned by the engine. |
published_at | string | Publication time, when the engine knows it. |
image | object | For image results: url, thumbnail, width, height. |
page | object | The page's content, from advanced or scrape. With scrape, a full scrape page object. |
passages | array | Up to 3 query-relevant excerpts, best first. Each has text, score and start, the byte offset of the excerpt in the page's text. |
relevance_score | number | The best passage's score. |
scrape_error | string | Why scrape could not fetch this result. |
Answer fields
| Field | Type | Description |
|---|---|---|
text | string | The answer, with citation markers such as [1]. |
citations | array | The sources the answer cites: number, url, title and a supporting quote. |
confidence | string | high, medium, low or none, from how many sources the answer cites. See Research. |
error | string | Present instead of the fields above when no answer could be written, for example when no LLM is configured. |
Usage
Each request counts as one search. Pages read by advanced and pages fetched by scrape count as pages. Identical engine queries are cached for an hour (10 minutes for news or freshness searches) and are answered faster, but still count as a search. A request is refused with 402 when your search quota, or for advanced and scrape your page quota, is used up.
Errors
| Status | Code | When |
|---|---|---|
400 | Missing or too long query, an unknown source, limit outside 1 to 50, an invalid country, search_language, freshness or safe_search, more than 20 domain filters or a filter that is not a host name, an invalid search_depth, scrape.limit outside 0 to 5, or an unknown format in scrape.formats. | |
402 | The monthly search quota, or the page quota for advanced and scrape, is used up. | |
403 | The key lacks the search scope. | |
429 | Your plan's request rate limit was exceeded. Retry after Retry-After. | |
429 | CONCURRENCY_LIMIT | Too many concurrent requests for your plan. Retry after Retry-After. |
502 | The search engine failed. | |
503 | No search engine is configured on the server. | |
503 | SERVER_BUSY | The server is at capacity. Retry after Retry-After. |
See Errors and limits for authentication errors and retries.
Related
- Research for an answer with verified citations from a full search-and-read run.
- Scrape for formats and their options.
- Usage and billing for what is metered.