Brave Search Scraper - Brave Search API & SERP Results
Pricing
from $2.00 / 1,000 search results
Brave Search Scraper - Brave Search API & SERP Results
Scrape organic Brave Search results into clean JSON: rank, title, real URL, host, site name and snippet for any query and market, with multi-page walks and per-keyword rank. A Brave Search API on your Apify account, billed per result.
Pricing
from $2.00 / 1,000 search results
Rating
0.0
(0)
Developer
SR
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
17 days ago
Last modified
Categories
Share
Brave Search Scraper: Brave Search API for Organic SERP Results
The Brave Search API in this Actor turns a query into ranked organic rows from Brave's own index: title, URL, host, site name and snippet, one row per result, ready to download as JSON, CSV or Excel or to stream into your own service. Use it to follow where a page ranks on Brave, to check whether Brave's index agrees with Google's and Bing's, or to hand an LLM fresh web context without running a browser. No Brave account, no Brave API key, no rate-limit contract: start it from the Apify Store or the Apify API and pay per result.
What you get
- Organic results from an independent index. Brave crawls and ranks its own web index instead of reselling Google's or Bing's, so the same query often returns a genuinely different set of pages. A domain that is invisible on Google can still be sitting in Brave's top 10.
- One row per result, with the position attached.
rankcounts within the keyword,positioncounts across the whole run, so a multi-keyword run stays sortable without extra work. - Real destination URLs. Each row carries the URL Brave printed, its host and the site name Brave shows above the title.
- Multi-keyword, multi-page runs. Give it a list of queries and a page depth; the Actor walks them in one run and de-duplicates across page boundaries before it numbers the ranks.
- Honest empty runs. If Brave shows nothing, or refuses every attempt, the run finishes successfully with an empty dataset and a coded error telling you which of the two it was.
- Pay only for rows. Billing follows the results you receive, not the compute behind them.
Input
| Field | Type | Default | Description |
|---|---|---|---|
keywords | array of strings | required | One search query per entry. A comma- or newline-separated string works too. |
country | string | us | Two-letter market code. Brave localises results, so this changes what comes back. |
pages | integer 1–10 | 1 | How deep to walk each keyword. Each page is one more request. |
safesearch | off | moderate | strict | moderate | Brave's own filter level. |
maxResults | integer 1–5000 | 200 | Stop after this many rows. Also the cost ceiling for the run. |
attempts | integer 1–10 | 3 | How many times to continue when Brave refuses the current connection. |
Example input:
{"keywords": ["lego 10313 wildflower"],"country": "nl","pages": 1,"safesearch": "moderate","maxResults": 200,"attempts": 3}
Leave country out and you get the US market; leave everything but keywords out and the
defaults above apply, which is what an API run without an input body does.
Output
Every row lands in the default dataset as a JSON record. These are the first two rows of a real
run of the input above (20 rows returned, country: nl):
[{"keyword": "lego 10313 wildflower","country": "nl","rank": 1,"title": "Boeket met wilde bloemen 10313 | Botanicals | Officiële LEGO® winkel NL","url": "https://www.lego.com/nl-nl/product/wildflower-bouquet-10313","display_host": "lego.com","description": "Kweek creativiteit – bouw en geniet van een levensecht LEGO® Botanicals Boeket met wilde bloemen (10313) met dit indrukwekkende bouwproject voor volwassenen.","site": "LEGO","page": 1,"position": 1,"fetched_at": "2026-09-27T17:32:53.196Z"},{"keyword": "lego 10313 wildflower","country": "nl","rank": 2,"title": "Wildflower Bouquet 10313 | Botanicals | Buy online at the Official LEGO® Shop US","url": "https://www.lego.com/en-us/product/wildflower-bouquet-10313","display_host": "lego.com","description": null,"site": "LEGO","page": 1,"position": 2,"fetched_at": "2026-09-27T17:32:53.196Z"}]
| Field | Description |
|---|---|
keyword | The query that produced this row. |
country | The market the search was made for. |
rank | 1-based position for that keyword, counted after duplicates are removed. |
title | Result title, or null if Brave printed none. |
url | Destination URL. |
display_host | Host of the destination, without www.. |
description | Result snippet; null when Brave returned the result without one. |
site | The site name Brave prints above the title. |
page | Which page of that keyword the row came from. |
position | 1-based position in the run as a whole, so rows merge across runs cleanly. |
fetched_at | When the row was fetched, ISO 8601 UTC. |
Alongside the rows, the run writes a summary record with the counts: keywords asked for, pages
asked and fetched, results, distinct hosts, rows with a snippet, attempts used, and how long the
fetch took. A two-keyword, four-page run over the Dutch market returned 79 rows from 61 distinct
hosts in 8.52 seconds. Failures land in an errors record:
| Code | Meaning |
|---|---|
blocked | Brave refused every attempt; some pages were not fetched |
no_results | A page loaded and had no results on it |
http_error | Brave answered with a status other than 200, or the request timed out |
bad_input | No keyword was given |
A refused run reads, for example:
{"code": "blocked", "message": "brave refused every exit tried (3 of 3 attempts); 1 of 1 pages not fetched"}
Results collected before the refusal are kept, nothing is fetched twice, and a run that ends up empty still exits successfully — you are never charged for results you did not receive.
Paging and refusals
Pages per keyword walks deeper. Brave counts its offset in pages from zero, which this Actor
handles for you: page 1 carries no offset, page 2 carries offset 1. rank is assigned after
duplicates are removed, so the numbering has no gaps even when Brave repeats a URL across a page
boundary.
Brave refuses anyone who asks too quickly. When that happens the Actor continues from the same
page on a fresh connection, up to Attempts per run. When every attempt
is refused you get the blocked error above plus captchaAttempts in the summary, so an empty
run is never ambiguous about why. A hundred pages finish in a few minutes; no browser is
involved, because Brave puts the results in the page itself.
Use cases
Brave rank tracking
Schedule a daily run per keyword set and store the rows in your warehouse. Because each row
carries rank, url, keyword and country, a join on date gives you a Brave rank tracker:
positions gained, lost and new entrants per market, billed per result instead of a monthly SEO
seat.
Index-gap analysis
Run the same queries against this Actor and against a Google or Bing scraper, then diff the
domains. Brave's index is built independently, so disagreements are the finding: pages that rank
on Brave but are missing from Google, and pages ranking on Google that Brave has not picked up.
brave search vs google is a search people actually make, and this is the data behind the
answer.
AI grounding and agent search
Feed the top organic rows for a question into your prompt as fresh web context. The rows are
small and clean, so they fit a context window without HTML noise, and rank tells you which
excerpt to trust first.
Market and competitor monitoring
The same query returns different results per market. Running it for us, nl, de and fr
shows which competitors invest in each country and where your own pages are missing, with
country on every row so the four runs merge into one table.
Why run a Brave Search API on Apify
- No separate signup. Brave's official API wants its own account, its own key and, per Brave's own FAQ, a credit card even for its free plan. This Actor runs from the Apify account you already have, with your Apify API token and nothing else.
- Billing per row, not per request. You pay for results you can use, and an empty run costs only the run fee.
- No capacity negotiation. Brave's official Search API publishes a query-per-second capacity per plan; here the ceiling is the run length and the number of rows you asked for.
- Runs, not calls. A list of 50 keywords across 3 pages is one run with one summary, one error record and one bill, instead of 150 calls you have to orchestrate yourself.
How it compares
Brave's official Search API was listed at $5 per 1,000 requests with a capacity of 50 queries per second and $5 in free monthly credits (brave.com/search/api, checked 7 October 2026) — a strong choice if you want the raw API and will manage your own quota. This Actor is the scraper shape of the same data: no key, no quota to watch, per-result billing and the position fields already attached.
The Apify Store carries more than a dozen other Brave scrapers, with per-result prices currently
ranging from about $0.0005 to $0.005 (Store, 7 October 2026). Differences worth checking before
you pick one: which result types are included (organic only here — no ads, no images, no
videos), whether rank survives de-duplication across pages, whether an empty or refused run is
billed as an error or as results, and whether the row keeps the destination URL Brave actually
printed.
For a Google-shaped SERP, use a Google SERP Actor instead: different index, different coverage, different price. Running two engines over the same keyword list and diffing the domains is cheaper than arguing about which index is "the" web.
FAQ
Do I need a Brave search API key?
No. This Actor reads Brave's public search results, so no Brave account, key or subscription is involved. An Apify account and its API token are enough.
Can I use this as a Brave rank tracker?
Yes. Each row carries rank for your keyword and country. Run it daily per keyword set and
compare runs to follow positions over time.
How many results do I get per query?
Up to maxResults rows in total for the run (default 200, maximum 5000), spread over the pages
you asked for. Brave sometimes returns fewer results than you asked for; you pay for the rows you
receive.
What happens if Brave blocks or refuses a request?
The Actor retries on a fresh connection up to Attempts per run. If it still cannot fetch a
page it writes a blocked error, keeps the rows it already collected and finishes successfully.
You are not charged for results you did not get.
Which markets are supported?
Any two-letter country code Brave accepts, such as us, nl, de, fr, gb or jp. Brave
localises results per market, and the market you asked for is echoed on every row.
Is this the same as Brave's official search API?
No. That is a hosted API with its own key, pricing and capacity; this is a scraper Actor that reads Brave's public result pages. Same index, different contract: no key, no quota, pay per result.
Can I run it on a schedule?
Yes. Use Apify Schedules to run it hourly, daily or weekly per keyword set, and an Apify integration or webhook to push the rows to your warehouse, sheets or storage.
Pricing
This Brave Search API uses Apify's pay-per-event pricing:
- $0.003 per result row returned ($3 per 1,000 results), tiered down to $0.002 on Apify's higher plans
- $0.001 per run start fee, charged once per run
A default run returning 10 rows costs about $0.031. Empty results are free: you pay the run fee and nothing else. There is no subscription and no per-compute-unit charge. On the free Apify plan each run returns at most 10 results; upgrade your Apify plan to remove that cap.