Brave Search Scraper - Brave Search API & SERP Results avatar

Brave Search Scraper - Brave Search API & SERP Results

Pricing

from $2.00 / 1,000 search results

Go to Apify Store
Brave Search Scraper - Brave Search API & SERP 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

SR

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

17 days ago

Last modified

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. rank counts within the keyword, position counts 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

FieldTypeDefaultDescription
keywordsarray of stringsrequiredOne search query per entry. A comma- or newline-separated string works too.
countrystringusTwo-letter market code. Brave localises results, so this changes what comes back.
pagesinteger 1–101How deep to walk each keyword. Each page is one more request.
safesearchoff | moderate | strictmoderateBrave's own filter level.
maxResultsinteger 1–5000200Stop after this many rows. Also the cost ceiling for the run.
attemptsinteger 1–103How 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"
}
]
FieldDescription
keywordThe query that produced this row.
countryThe market the search was made for.
rank1-based position for that keyword, counted after duplicates are removed.
titleResult title, or null if Brave printed none.
urlDestination URL.
display_hostHost of the destination, without www..
descriptionResult snippet; null when Brave returned the result without one.
siteThe site name Brave prints above the title.
pageWhich page of that keyword the row came from.
position1-based position in the run as a whole, so rows merge across runs cleanly.
fetched_atWhen 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:

CodeMeaning
blockedBrave refused every attempt; some pages were not fetched
no_resultsA page loaded and had no results on it
http_errorBrave answered with a status other than 200, or the request timed out
bad_inputNo 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.

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.