# Brave Search Scraper – Organic SERP Results (`datascraperes/brave-search-scraper`) Actor

Collect Brave Search organic SERP results for 1–10,000 keywords: positions, titles, URLs, domains, snippets and localization. Pay per delivered result.

- **URL**: https://apify.com/datascraperes/brave-search-scraper.md
- **Developed by:** [DataScraperES](https://apify.com/datascraperes) (community)
- **Categories:** SEO tools, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.45 / 1,000 organic brave search results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

**Collect Brave Search organic SERP results at scale** for one to 10,000 keywords and receive ranked positions, titles, URLs, domains, snippets, localization settings, and pagination metadata in an export-ready Apify Dataset. Pay only for organic results delivered.

### What this Actor does

This Actor requests Brave Search web result pages and extracts the organic results visible in the returned HTML. It is focused on clean, one-row-per-result SERP data rather than mixing organic links with images, news, video, or AI modules. It normalizes and deduplicates the input queries, follows the requested page range, removes duplicate destination URLs within each query, and stores one Dataset item per delivered organic result.

Each result includes the original query, stable query and result identifiers, page and organic position, title, destination URL, hostname, displayed URL, snippet, localization settings, pagination outcome, and collection timestamp. Query-level outcomes such as empty results, temporary failures, rate limits, challenge pages, retries, and budget skips are kept in the default Key-Value Store so they can be inspected without being mixed into billable result rows.

### Use cases

- Monitor organic search visibility for selected keywords and markets.
- Compare titles, snippets, domains, and rankings across search engines.
- Build keyword research, content planning, and competitor datasets.
- Feed ranked URLs into downstream SEO, reporting, or enrichment workflows.

### How to use

1. Open the Actor in Apify Console.
2. Enter one or more search queries and choose the result, page, country, language, and Safe Search limits.
3. Click **Start** and open the Dataset when the run finishes.

### Input

`queries` is required and accepts up to 10,000 entries. Blank values are rejected; surrounding whitespace and repeated internal whitespace are normalized, and duplicate queries are removed case-insensitively while preserving the first occurrence. Runs of 1,000–2,000 queries are easier to monitor; larger runs remain sequential and can take substantially longer.

`maxResultsPerQuery` accepts 1–100 results and defaults to 20. `maxPagesPerQuery` accepts 1–10 pages and defaults to 1. `countryCode` and `searchLanguage` are two-letter localization codes and default to `es`. `safeSearch` accepts `off`, `moderate`, or `strict` and defaults to `moderate`.

Request pacing and retry handling are managed automatically for stable runs. The Actor applies a 1,000 ms delay between sequential Brave Search requests and up to 3 bounded retries for transient network, rate-limit, and server failures. Challenge pages are reported rather than repeatedly retried.

```json
{
  "queries": ["brave search scraper"],
  "maxResultsPerQuery": 3,
  "maxPagesPerQuery": 1,
  "countryCode": "es",
  "searchLanguage": "es",
  "safeSearch": "moderate"
}
```

### Output

Every delivered organic result is stored as one item in the default Dataset. `position` is the query-wide organic position across the fetched pages, while `pagePosition` is the position within its source page. `paginationStoppedReason` explains why the Actor stopped requesting pages.

The default Key-Value Store also contains `SUMMARY` with aggregate counters and `QUERY_STATUSES` with one non-billable status record per processed query. Dataset items can be downloaded or consumed through the Apify API in JSON, JSONL, CSV, Excel, and other supported export formats.

This is the complete Dataset item from a real successful run:

```json
{
  "type": "organicResult",
  "query": "brave search scraper",
  "queryId": "b6b0e1d1a57fb23021a34e4c",
  "countryCode": "es",
  "searchLanguage": "es",
  "safeSearch": "moderate",
  "pagesFetched": 1,
  "organicResultsFound": 3,
  "paginationStoppedReason": "max_results",
  "fetchedAt": "2026-08-27T19:01:53.275924+02:00",
  "resultId": "dca5f24d4b0d3d376f3649bae1652e85",
  "page": 1,
  "pagePosition": 2,
  "position": 2,
  "title": "Brave Search API",
  "url": "https://brave.com/es/search/api/",
  "domain": "brave.com",
  "displayUrl": "brave.com › es › search › api",
  "description": "July 1, 2026 - Es importante destacar que la API del Buscador de Brave no es un scraper que se limite a utilizar bots para consultar a Google o Bing y reempaquetar sus resultados ."
}
```

### Pricing

This Actor uses Apify pay-per-event pricing. One `organic-result` event represents one organic result successfully delivered to the default Dataset. The configured price per 1,000 delivered results is:

| Apify plan tier | Price per 1,000 results | Price per result |
|---|---:|---:|
| FREE | $0.60 | $0.00060 |
| BRONZE | $0.55 | $0.00055 |
| SILVER | $0.50 | $0.00050 |
| GOLD | $0.45 | $0.00045 |
| PLATINUM | $0.45 | $0.00045 |
| DIAMOND | $0.45 | $0.00045 |

Apify selects the applicable tier for the customer account at run time. The **Pricing** tab is the source of truth for the active configuration.

Empty queries, failed requests, challenge pages, status records, run summaries, duplicate queries removed during input normalization, and results that are not delivered do not trigger an `organic-result` charge. Apify platform usage can still apply according to your plan.

### API and integrations

Run the Actor through Apify Console, API, CLI, schedules, tasks, or webhooks. Consume the default Dataset and Key-Value Store through their Apify API links, connect them to automation tools or databases, or export the results for SEO reporting and analysis.

### Related Actors

| Actor | Best for |
|---|---|
| [Google SERP Scraper API – Search Results Scraper](https://apify.com/datascraperes/google-serp-scraper) | Comparing the same keyword set with Google organic rankings. |
| [Bing Search Scraper – SERP Results](https://apify.com/datascraperes/bing-search-scraper) | Comparing results with Bing markets, SafeSearch, and SERP controls. |
| [DuckDuckGo Search Scraper — Organic SERP API](https://apify.com/datascraperes/duckduckgo-search-results-scraper) | Adding privacy-focused DuckDuckGo results to a cross-engine study. |
| [Yahoo Search Results Scraper](https://apify.com/datascraperes/yahoo-search-scraper) | Checking localized Yahoo rankings and snippets for the same queries. |

### Limits and data quality

- A run accepts up to 10,000 normalized queries. The Actor processes them sequentially to keep request rate, proxy rotation, memory use, and billing predictable.
- Progress and aggregate counters are checkpointed during long runs, so an Apify migration can restart from the last checkpoint without requiring concurrent workers.
- For 10,000 queries, total runtime is dominated by the managed request pacing and Brave response time. Use 1,000–2,000 query batches when you need shorter operational windows or easier retries.
- Each query can request up to 100 organic results across at most 10 pages.
- These are maxima, not guaranteed counts; Brave Search may expose fewer results, repeat or omit destinations, or change rankings and snippets between runs.
- Country and language settings influence localization but do not guarantee that every result originates in that country.
- The Dataset covers organic web results only. Ads, image results, news results, video results, Ask/LLM responses, and other specialized modules are not included.
- Temporary HTTP errors, rate limits, or challenge pages can stop a query. Review `QUERY_STATUSES` and `paginationStoppedReason` when fewer results are returned.
- A result page can change after collection; keep `fetchedAt`, query settings, and page metadata when comparing runs.

### Frequently asked questions

#### Does the Actor return paid advertisements?

No. Dataset items represent organic Brave Search web results only.

#### Why did I receive fewer results than requested?

The source may expose fewer unique results, pagination may end, duplicate URLs may be removed, the run spending limit may be reached, or Brave may return a temporary restriction or challenge. Check `QUERY_STATUSES` and the result metadata.

#### Can I search several countries in one run?

One country and one search language are applied to all queries in a run. Start separate runs when you need to compare different localizations.

#### How can I control the maximum cost?

Set a maximum total charge for the run in Apify. The Actor checks available result capacity before paid delivery and stops when the configured limit cannot accommodate another result.

### Responsible use

Use search-result data only for lawful purposes. You are responsible for complying with applicable laws, regulations, privacy requirements, copyright obligations, and the source's terms. Do not use the Actor to bypass access controls, CAPTCHA, Proof of Work, rate limits, or other anti-automation measures.

### Support

If a run produces unexpected results, open an issue in the Actor's **Issues** tab with the run ID, affected query, localization settings, and a reproducible input. Never include passwords, API tokens, proxy credentials, or other sensitive information.

# Actor input Schema

## `queries` (type: `array`):

Queries are trimmed, internal whitespace is normalized, and duplicates are removed preserving first occurrence. For large jobs, 1,000–2,000 queries per run are easier to monitor; up to 10,000 are accepted.

## `maxResultsPerQuery` (type: `integer`):

Maximum unique organic results delivered for each query.

## `maxPagesPerQuery` (type: `integer`):

Maximum Brave Search HTML pages requested for each query. Pages use Brave's offset parameter.

## `countryCode` (type: `string`):

Two-letter country code used to localize Brave Search results.

## `searchLanguage` (type: `string`):

Two-letter language code used to localize Brave Search results.

## `safeSearch` (type: `string`):

Brave Search safe-search mode.

## Actor input object example

```json
{
  "queries": [
    "Apify",
    "Brave Search",
    "Python"
  ],
  "maxResultsPerQuery": 1,
  "maxPagesPerQuery": 1,
  "countryCode": "es",
  "searchLanguage": "es",
  "safeSearch": "moderate"
}
```

# Actor output Schema

## `results` (type: `string`):

Default Dataset. Each item is one delivered organic result and one billable event when pay-per-event pricing is active.

## `summary` (type: `string`):

Aggregate query, page, retry, challenge, delivery, and billing counters.

## `queryStatuses` (type: `string`):

Non-billable status records for empty, failed, partial, challenged, and budget-skipped queries.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "queries": [
        "Apify",
        "Brave Search",
        "Python"
    ],
    "maxResultsPerQuery": 1,
    "maxPagesPerQuery": 1,
    "countryCode": "es",
    "searchLanguage": "es",
    "safeSearch": "moderate"
};

// Run the Actor and wait for it to finish
const run = await client.actor("datascraperes/brave-search-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "queries": [
        "Apify",
        "Brave Search",
        "Python",
    ],
    "maxResultsPerQuery": 1,
    "maxPagesPerQuery": 1,
    "countryCode": "es",
    "searchLanguage": "es",
    "safeSearch": "moderate",
}

# Run the Actor and wait for it to finish
run = client.actor("datascraperes/brave-search-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "queries": [
    "Apify",
    "Brave Search",
    "Python"
  ],
  "maxResultsPerQuery": 1,
  "maxPagesPerQuery": 1,
  "countryCode": "es",
  "searchLanguage": "es",
  "safeSearch": "moderate"
}' |
apify call datascraperes/brave-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datascraperes/brave-search-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/ZPkgJwNZNPXWhEI6c/builds/24zu0uDglx3Pn3w79/openapi.json
