A Brave API key gives you programmatic access to Brave’s independent web index: the same results Brave Search serves in the browser, returned as JSON you can feed into scripts, dashboards, or AI agents. The Brave Search API has become a common pick for giving agents live web access; if that’s your end goal, the Brave Search MCP server guide shows how the key plugs into Claude and other MCP clients. This post covers the part before that: creating the account, choosing a plan, generating the key, and sending a real query with curl, Python, and Apidog.
Everything below comes from Brave’s own dashboard documentation as of September 2026. Pricing and limits change, so treat the numbers as a snapshot and check the linked pages before you budget.
What you need before you start
- An email address for the dashboard account.
- A credit card. Brave requires one on every plan, including the free-credit tier, as an anti-fraud check. The FAQ on the plans page states that for free plans the card is only used to confirm your identity.
- curl, or Python 3 with the
requestspackage, for the command-line examples. - Apidog, if you want to store the key safely and turn the request into a repeatable test. It’s optional for the first call.
Step 1: Create a Brave Search API account
Go to the Brave Search API dashboard and register with an email address and password. Brave sends a confirmation link; click it to verify the address. Until you do, you can’t activate a plan.
The dashboard is separate from any Brave browser or Brave Rewards login, so an existing browser account won’t carry over. Register fresh.
Step 2: Choose a plan (the free tier has one catch)
Open the Plans page in the dashboard. As of September 2026, Brave’s pricing page lists these options:
| Plan | Price | Free credit | Rate limit |
|---|---|---|---|
| Search | $5.00 per 1,000 requests | $5 in credits every month | 50 requests per second |
| Answers | $4.00 per 1,000 queries, plus $5.00 per 1,000,000 input tokens and $5.00 per 1,000,000 output tokens | $5 in credits every month | 2 requests per second |
| Spellcheck | $5.00 per 10,000 requests | $5 in credits every month | 100 requests per second |
| Autosuggest | $5.00 per 10,000 requests | $5 in credits every month | 100 requests per second |
| Enterprise | Custom | Contact sales | Custom |
For web search, pick Search. The $5 monthly credit covers roughly 1,000 web-search requests before you pay anything, which is enough for development and small agent workloads. Billing is prepaid: you buy credits up front, and the monthly free credit is applied automatically.
The catch is the card. You can’t activate any plan, free credit included, without entering one. If you’ve seen older guides describing a no-card free plan with a fixed monthly query quota, they describe a previous generation of Brave’s pricing. New accounts get the credit model above.
Select the plan and enter your card details. The plan shows as active in the dashboard right away.
Step 3: Create the API key
With a plan active, open the API Keys section, click “Add API Key”, and give the key a descriptive name. Brave’s quickstart suggests names like “Production App” or “Development”. One key per environment pays off later, when you need to revoke a single key without touching the others.
Copy the key and store it somewhere safe immediately. Brave’s authentication guide is blunt about where it must not go: client-side code, public repositories, or any public location. If you’re new to how these credentials work, the primer on what an API key is covers the model in a few minutes.
Step 4: Send your first search request
The web search endpoint is https://api.search.brave.com/res/v1/web/search. Every request needs the key in an X-Subscription-Token header. Note the header name: it isn’t Authorization: Bearer, and sending the key that way fails.
curl
curl "https://api.search.brave.com/res/v1/web/search?q=openapi+3.1+breaking+changes&count=5&freshness=py" \
-H "Accept: application/json" \
-H "Accept-Encoding: gzip" \
-H "X-Subscription-Token: $BRAVE_API_KEY"
count caps results per page (max 20, default 20), offset pages through them (0-based, max 9), and freshness filters by age: pd, pw, pm, or py for the past day, week, month, or year. Other useful parameters are country (two-letter code), search_lang, and safesearch (off, moderate, or strict; moderate is the default).
Python
import os
import requests
url = "https://api.search.brave.com/res/v1/web/search"
headers = {
"Accept": "application/json",
"Accept-Encoding": "gzip",
"X-Subscription-Token": os.environ["BRAVE_API_KEY"],
}
params = {"q": "openapi 3.1 breaking changes", "count": 5, "freshness": "py"}
resp = requests.get(url, headers=headers, params=params, timeout=10)
resp.raise_for_status()
data = resp.json()
for hit in data["web"]["results"]:
print(hit["title"])
print(hit["url"])
print(hit["description"][:120], "\n")
The response carries a query object (with original and a more_results_available boolean for pagination) and a web.results array. Each result has title, url, and description; set extra_snippets=true and you get up to five extra excerpts per result, which helps when you’re building context for a model.
Brave versions the API with an optional Api-Version header in YYYY-MM-DD form. Leave it out and you get the latest version; pin it once your integration is in production so a future breaking change doesn’t land uninvited.
Step 5: Test the key in Apidog
Pasting a key into a curl one-liner is fine for a first hit. It’s a bad place to leave it. In Apidog you store the key once as a variable, reference it everywhere, and keep the secret itself off the shared project.
- Open environment management in the top-right of your Apidog project and add an environment called
Brave. Create a variable namedbrave_api_keyand put the real key in the local value field, not the shared value. Local values stay on your machine and never sync to teammates; the variables reference explains the two-value model, and the full workflow for environments and secret variables in Apidog covers dev, staging, and prod layouts if you need more than one. - Create a new GET request to
https://api.search.brave.com/res/v1/web/search. In the Headers tab addX-Subscription-Tokenwith the value{{brave_api_key}}. In Params addq,count, andfreshness. - Click Send. The response pane shows the JSON body, and the headers pane shows
X-RateLimit-RemainingandX-RateLimit-Reset, so you can watch your quota without printing anything. - Add assertions: status code equals 200,
$.web.resultsexists and has at least one element, and$.query.originalmatches the query you sent. Save the request into a test scenario. Now a key rotation or a Brave-side change shows up as a red run instead of a broken agent at 2 a.m.
Download Apidog to follow along; the free plan covers four users and includes environments and test scenarios.
Rate limits and how Brave reports them
Every response carries four headers, documented in Brave’s rate limiting guide:
X-RateLimit-Limit: the limits attached to your plan, for example1, 15000.X-RateLimit-Policy: the same limits with window sizes in seconds, for example1;w=1, 15000;w=2592000(a one-second window and a 30-day window).X-RateLimit-Remaining: what’s left in each window.X-RateLimit-Reset: seconds until each window resets.
Two details matter for budgeting. First, the guide states that only successful, non-error responses count against quota, so a burst of 422s from a typo doesn’t eat credits. Second, the per-second figure in those example headers (1 request per second) is the doc’s illustration, not the Search plan’s advertised 50 requests per second. Read your own headers instead of assuming.
Common errors and what to do
Authentication failure on a fresh key. Brave’s authentication guide says every request must carry X-Subscription-Token, and a missing or invalid value is rejected. This usually surfaces as HTTP 401 with a token-invalid error code, although Brave’s API reference doesn’t spell the status out. Check three things: the header name is exact (not Authorization), the key was copied without trailing whitespace, and a plan is active on the account. If you’re unsure why this scheme differs from bearer auth, see API key vs bearer token.
422 Unprocessable Entity. A parameter is out of range or malformed: count above 20, offset above 9, an unrecognized freshness value, or an empty q. The body follows Brave’s error schema:
{
"type": "ErrorResponse",
"error": {
"id": "<unique occurrence id>",
"status": 422,
"code": "<application error code>",
"detail": "<what went wrong>",
"meta": {}
},
"time": 0
}
Read error.detail; it names the field.
429 Too Many Requests. You hit the per-second window or ran out of credits. Brave documents both RATE_LIMITED and QUOTA_LIMITED as error codes, so check which one you got: waiting the number of seconds in X-RateLimit-Reset and retrying with backoff (Brave suggests 1s, 2s, 4s) fixes the first, and only topping up credits or waiting for the monthly reset fixes the second.
FAQ
Is the Brave Search API free?
Partly. Every plan gets $5 in credits each month, which is about 1,000 Search requests. Beyond that you pay $5.00 per 1,000 requests. There’s no way to activate a plan without a credit card, even if you never exceed the credit.
Do I need separate keys for web search and the LLM Context endpoint?
Brave’s API reference describes the token as generated “for the product”, which suggests a key is tied to the subscription it was created under. If a key that works on /web/search fails on /llm/context or the Answers endpoint, check which plan the key belongs to in the dashboard before assuming the key is broken.
What if my Brave API key leaks?
Revoke it in the API Keys section, generate a replacement, and update the variable in Apidog so every saved request picks up the new value at once. Then find out how it leaked: running a secret scanner for leaked API keys across your repos and CI logs is the fastest way to confirm nothing else is exposed.
Can I try queries without writing code?
Yes. The dashboard includes a Playground page for ad-hoc queries, and Apidog’s request builder does the same with the added benefit that the request is saved and testable afterward.
Next step
You have an account, an active plan, a named key, and a request that returns real results from three clients. From here, either wire the key into an agent through the MCP server, or build out the Apidog test scenario so key rotation and quota exhaustion get caught before your users notice. Both start with the same X-Subscription-Token header you set up today.
