Which Brave Search Domains Are Actually Worth Reviewing?
Brave results can surface many hosts, but a host is not automatically a company or a useful lead. Search for your actual market, keep the URL and query behind each candidate, then let a reviewer classify businesses, sources, forums and hosted pages.
I founded Serpent API, whose Brave result contract supplies the example fields. This is an affiliated, contract-based workflow; these exact queries have no authenticated parsed production result for this article. Brave’s official Search API is another direct option with its own response contract.
Write a query set for the domains you need
Start with task-specific phrases rather than one broad keyword. A research project might use product category, comparison, forum and region variants. Predefine a small query set and a maximum requested result count. Save the exact query beside each domain so a reviewer can understand why it appeared.
Normalize www and host case, but do not automatically collapse subdomains: a marketplace, documentation site and user forum can have different roles. Keep representative URLs and titles for each host. Review the landing pages and classify the domain manually. A domain that appears in many sampled queries is a stronger review candidate, not automatically more authoritative.
Keep host, URL and query together
Brave offers its own official Search API for direct indexed search access. Serpent exposes Brave as an engine on shared Quick and Deep web endpoints. These are different contracts with different result fields and billing units; compare them on your needed query set rather than assuming identical output.
| Field or control | Use in this workflow | Check before trusting it |
|---|---|---|
q, engine, country | Preserve the exact request identity. | Compare only samples with intended matching settings. |
results.organic[] | Read url, title and position from each usable row. | Validate array and row types; a position is an observed list location. |
num and returned count | Keep requested depth separate from usable rows. | Requested results are best-effort; never fill missing rows with invented values. |
delivery, meta.partialResults | Mark short or incomplete observations for review. | Inspect these before interpreting a missing URL as a change. |
Build a candidate-domain queue
Install requests and set SERPENT_API_KEY in your local environment. This complete Python example shows the request and parsed-field handling for the workflow. It has been syntax-checked locally, but the sample query output has not been validated against an authenticated production response. Run it against your account before adopting it.
import os
from datetime import datetime, timezone
from urllib.parse import urlsplit, urlunsplit, parse_qsl, urlencode
import requests
BASE = "https://apiserpent.com"
KEY = os.environ["SERPENT_API_KEY"]
def snapshot(engine, query, country="us", num=10, deep=False):
endpoint = "/api/search" if deep else "/api/search/quick"
response = requests.get(
BASE + endpoint,
params={"engine": engine, "q": query, "country": country,
"num": num, "format": "full"},
headers={"X-API-Key": KEY}, timeout=55 if deep else 30)
response.raise_for_status()
data = response.json()
if data.get("success") is not True or not isinstance(data.get("results"), dict):
raise ValueError("No usable results object")
rows = data["results"].get("organic")
if not isinstance(rows, list):
raise ValueError("Organic rows are missing")
return {"observed_at": datetime.now(timezone.utc).isoformat(),
"query": query, "country": country, "engine": engine,
"requested": num, "organic": rows,
"delivery": data.get("delivery"),
"partial": (data.get("meta") or {}).get("partialResults")}
def normalized_url(raw):
if not isinstance(raw, str) or not raw.startswith(("https://", "http://")):
return None
parts = urlsplit(raw)
host = (parts.hostname or "").lower().removeprefix("www.")
path = parts.path.rstrip("/") or "/"
query = urlencode(sorted((k, v) for k, v in parse_qsl(parts.query)
if not k.lower().startswith("utm_")))
return urlunsplit((parts.scheme.lower(), host, path, query, ""))
QUERIES = ["independent running shoe reviews",
"running shoe comparison sites", "running shoe discussion forums"]
domains = {}
for query in QUERIES:
sample = snapshot("brave", query, country="us", num=20)
for row in sample["organic"]:
if not isinstance(row, dict):
continue
url = normalized_url(row.get("url"))
if not url:
continue
host = urlsplit(url).hostname
if not host:
continue
entry = domains.setdefault(host, {"queries": set(), "examples": []})
entry["queries"].add(query)
entry["examples"].append({"url": url, "title": row.get("title"),
"position": row.get("position")})
print({"query": query, "returned": len(sample["organic"]),
"delivery": sample["delivery"]})
for host, info in sorted(domains.items(), key=lambda pair: -len(pair[1]["queries"])):
print({"host": host, "query_count": len(info["queries"]),
"example": info["examples"][0]})
How to read the output: The output is a candidate list with evidence, not a complete list of Brave-indexed domains. Keep the raw query and delivery record for each pull. Decide explicitly whether to roll a subdomain up to a parent organization after a human reviews it; public-suffix rules and hosted platforms make a simple last-two-label split unreliable.
Budget the discovery schedule
Three Quick queries once per day for 30 days mean 90 Serpent Web calls. At the documented Default rate of $0.60/1,000 calls, the metered planning figure is $0.054. Brave’s official Search plan listed $5 per 1,000 requests and $5 monthly credits on October 5, 2026; check the official dashboard before purchase. A Brave request and a Serpent Quick call are unlike output contracts, so the price lines do not prove equal value.
Serpent’s published pricing gives Web-category rates by account tier. The figures above use the documented Default rate as a dated planning example, not a measured invoice. Confirm your tier, optional features and actual charges in your account before scaling. A response with fewer rows does not by itself change the requested-page unit for Deep.
Compare Brave API routes fairly
| Option | Useful for | Published access or billing unit | Decision |
|---|---|---|---|
| Brave Search API | Direct official Brave index API with its own response contract. | $5 per 1,000 Search requests and $5 monthly credits listed October 5, 2026. | Choose for direct official integration; map its response fields and plan terms. |
| Serpent Brave Quick | Shared web shape with organic URL and position rows. | One Web unit per Quick call; Default $0.60/1,000 units. | Choose if you already normalize multiple engines in one client; validate your sample. |
| Manual Brave Search | Inspect current result context and candidate pages. | Human effort. | Use as the review layer for role and relevance. |
Why a host is not always a company
Brave results are ordered for a query, not an exhaustive topic directory. A short response, query phrasing, country or timing can exclude relevant domains. Do not report coverage percentages without a known ground-truth set and dated method. Respect site terms when opening discovered pages; this guide only builds the discovery queue.
Review relevance before counting domains
The code groups exact hosts; that is a safe first pass, but a host is not always a business. A community on a hosted platform may be its own candidate, while two subdomains may belong to one publisher. Preserve the original host and URL, then let a reviewer assign an entity ID. Avoid automatically collapsing everything to the last two hostname labels, which can merge unrelated hosted pages.
| Candidate field | Reviewer question | Decision it supports |
|---|---|---|
| Queries that surfaced the host | Did it appear for product, comparison or community intent? | Prioritize candidates related to the actual research task. |
| Example page and title | Is this a real source, marketplace, forum, aggregator or irrelevant result? | Classify the entity without treating a rank as endorsement. |
| First and last observed dates | Is it repeatedly seen or was this a single sample? | Separate steady candidates from new leads. |
For an illustrative lead list, a host seen on two distinct query intents can be reviewed first, but “query_count=2” means two of your chosen searches, not twice the market reach. After reviewing 20 candidates, record how many are useful and why the rest were excluded. That relevance yield, plus the number of useful new entities on a later run, tells you whether to refine the queries or buy more depth.
Check the candidate list before using it
- Choose a narrow topic and several queries that represent the prospects or sources you want to discover.
- Collect usable Brave organic URLs with their query and country, then normalize hosts without merging distinct subdomains blindly.
- Review a sample of the distinct domains for relevance and false positives; keep excluded domains and reasons in the ledger.
- Repeat the same query set later and judge useful new domains, not the raw count of result cards.
Build a small domain candidate list
Start with the few queries that drive a real decision. Save the returned rows and their limits before increasing the schedule.
Get an API keyFAQ
Does one Brave query find every competing domain?
No. Use a small set of distinct task phrases and treat returned hosts as candidates, not a census.
Can I deduplicate to the top-level domain automatically?
Do so only if that matches your use case. Subdomains and hosted sites can represent different entities; retain the full host first.
Is Brave’s official API the same as a Serpent Brave result?
No. They have different contracts and billing units. Compare parsed fields on your own queries.
What does query_count mean?
It is the number of your sampled phrases that returned a host. It is a review-priority signal, not a measure of popularity or authority.





