Brave search
TL;DR
About
In March 2025 Anthropic listed Brave Search as a subprocessor, and Simon Willison found Claude's web search citations matching Brave's results page. Brave uses its own index (it dropped Bing in 2023), so a Google ranking tells you little here. Take a docs team that moved 300 guides to /docs last month. A week later someone runs a site: query per folder, /docs/api then /docs/sdk, with country "us", pages until hasMore goes false and checks the URLs against the sitemap. Folders matter because a domain-wide query runs dry after a handful of pages. An answer flagged operatorsApplied false counts as zero found. A guide still absent gets a search on its quoted title, then goes to the companion submit_url script, which requests a recrawl but cannot promise indexing. Guides Brave has never read carry the placeholder snippet 'We cannot provide a description for this page right now'. Brave's AI answer and forum cards stay out of the output.
Input
query requiredSearch query. The operators site:, quoted phrases and OR are honored. site:domain also covers its subdomains (site:example.com returns docs.example.com), and site:domain/path narrows to a path prefix, which is the cheapest way to slice a large site.
offset optional0-based page index (0 is the first page, about 20 results). The pool behind one query is limited and its depth varies by query; past its end Brave re-serves earlier pages. hasMore in the output says whether a next page exists: keep paging while it is true, and dedupe on url anyway. Default 0.
country optionalISO-3166 alpha-2 country whose Brave results to read, e.g. "us". When omitted, Brave answers for the country of the browser's own network location, so the same query read from two places gives two different result pages. Pass it whenever readings must be comparable across browsers, or must stand in for another reader's, such as an assistant's US-side web search.
exactMatch optionalDeprecated; has no reliable effect, because Brave may correct spellings without saying so. To search a literal string, put it in quotes in query. Default false.
Output
count requiredHow many result cards were extracted from THIS page — literally results.length. NOT a match count and NOT an estimate of what Brave holds for the query; there is no such number on the page. A full page reads ~16-20.
query requiredoffset requiredhasMore requiredWhether Brave offers a next page for this query — its pager's next-page control, enabled or disabled. false on a pool's last page and on an empty answer. This is the end-of-pool signal: page while true, dedupe on url regardless, because the last page can repeat an earlier one.
results requiredThe page's organic web results, in rank order. EMPTY ONLY WHEN BRAVE SAID SO — see `emptyBecause`. If this script reads zero rows off a page that Brave answered normally it THROWS instead of returning [], because a silent empty is indistinguishable from a real one to any schema and would be read as 'the domain has nothing on this topic'.
emptyBecause requiredWhy `results` is empty, in Brave's own terms — and null whenever `results` is non-empty. One of: the operators were relaxed (too few documents matched them), Brave's no-matches banner, or its no-results message. This is what makes an empty answer READABLE: an empty set is a fact about the query, never a scraper failure, because the failure case throws.
operatorsApplied requiredWhether Brave honored the operators in `query`. false = Brave found too few matching documents, dropped the operators and answered a RELAXED query instead (it shows a 'search operators were not applied — Too few matches were found' banner): `results` are then soft relevance over the whole web, NOT filtered, so treat them as empty for any hard-filter use such as a site: coverage check. ONLY MEANINGFUL WHEN `query` CONTAINS AN OPERATOR — for an operator-free query it is vacuously true. Detected language-independently via the banner's /help/operators link, with the English sentence as a fallback; either signal reports false, so it errs toward warning you.
country optionalThe country the results were read for, lowercased, as passed in; null when none was passed and the page is the egress's own locale.
rewrittenTo optionalWhat Brave actually searched if it ANNOUNCED an auto-rewrite, else null. Read off the English 'Showing results for' line, so it stays null on a localized SERP — and also, measured, when Brave silently corrects a typo and announces nothing. null therefore means 'no rewrite was announced', never 'the literal query was searched'.
Example output
Shape only: placeholder values generated from the output schema, not a real run.
{
"count": 3,
"query": "…",
"offset": 3,
"country": 3,
"hasMore": true,
"results": [
{
"age": "…",
"url": "https://example.com/item/123",
"title": "Example",
"snippet": "…"
}
],
"rewrittenTo": "…",
"emptyBecause": "…",
"operatorsApplied": true
}