The Browserbase Search API gives your agents fast, token-efficient web search results as a complement to browser sessions. Use it for recon, lead discovery, or RAG pipelines — then hand off to a browser session for interaction.
Send a POST request to /v1/search with your query. Authenticate with the same x-bb-api-key header used across the Browserbase API.
import { Browserbase } from "@browserbasehq/sdk";
const bb = new Browserbase({ apiKey: process.env.BROWSERBASE_API_KEY! });
const response = await bb.search.web({
query: "browserbase",
numResults: 10, // up to 25 results
});
console.log(`Request ID: ${response.requestId}`);
for (const result of response.results) {
console.log(`${result.title} - ${result.url}`);
}
from browserbase import Browserbase
import os
bb = Browserbase(api_key=os.environ["BROWSERBASE_API_KEY"])
response = bb.search.web(
query="browserbase",
num_results=5,
)
print(f"Request ID: {response.request_id}")
for result in response.results:
print(f"{result.title} - {result.url}")
curl -X POST https://api.browserbase.com/v1/search \
-H "Content-Type: application/json" \
-H "x-bb-api-key: $BROWSERBASE_API_KEY" \
-d '{
"query": "browserbase",
"numResults": 10
}'
Request parameters
| Parameter | Type | Required | Description |
|---|
query | string | Yes | The search query (1–200 characters) |
numResults | integer | No | Number of results to return (1–25, default: 10) |
Response
| Field | Type | Description |
|---|
requestId | string | Unique identifier for the request |
query | string | The search query that was executed |
results | array | List of search result objects |
Each result object contains:
| Field | Type | Always present | Description |
|---|
id | string | Yes | Unique identifier for the result |
url | string | Yes | URL of the search result |
title | string | Yes | Title of the search result |
author | string | No | Author of the content |
publishedDate | string | No | Publication date (ISO 8601) |
image | string | No | Image URL |
favicon | string | No | Favicon URL |
Combining search with browser sessions
A common pattern is using the Search API to find relevant URLs, then opening them in browser sessions for deeper interaction — extracting content, filling forms, or taking screenshots.
import { Browserbase } from "@browserbasehq/sdk";
import { chromium } from "playwright-core";
const bb = new Browserbase({ apiKey: process.env.BROWSERBASE_API_KEY! });
const searchResponse = await bb.search.web({
query: "browserbase documentation",
numResults: 10,
});
for (const result of searchResponse.results) {
const session = await bb.sessions.create();
const browser = await chromium.connectOverCDP(session.connectUrl);
const page = browser.contexts()[0].pages()[0];
await page.goto(result.url);
const content = await page.textContent("body");
console.log(`Content from ${result.title}:`, content?.slice(0, 200));
await page.close();
await browser.close();
}
from browserbase import Browserbase
from playwright.sync_api import sync_playwright
import os
bb = Browserbase(api_key=os.environ["BROWSERBASE_API_KEY"])
search_response = bb.search.web(
query="browserbase documentation",
num_results=3,
)
with sync_playwright() as playwright:
for result in search_response.results:
session = bb.sessions.create()
browser = playwright.chromium.connect_over_cdp(session.connect_url)
page = browser.contexts[0].pages[0]
page.goto(result.url)
content = page.text_content("body")
print(f"Content from {result.title}:", content[:200] if content else "")
page.close()
browser.close()
Rate limits
The Search API is rate limited to 120 requests per minute per project. Exceeding this returns a 429 status code.
For high-volume use cases, space out your requests or implement exponential
backoff in your retry logic.
Error handling
| Status Code | Meaning |
|---|
200 | Success |
400 | Invalid request (empty query, numResults out of range) |
403 | Search API not enabled for your project |
429 | Rate limit exceeded |
503 | Search service temporarily unavailable |
500 | Internal server error |
import { Browserbase } from "@browserbasehq/sdk";
const bb = new Browserbase({ apiKey: process.env.BROWSERBASE_API_KEY! });
try {
const response = await bb.search.web({ query: "browserbase" });
console.log(response.results);
} catch (error) {
if (error.status === 429) {
console.log("Rate limited — retrying after delay");
} else if (error.status === 503) {
console.log("Service temporarily unavailable — retrying");
} else {
console.error("Search failed:", error);
}
}
from browserbase import Browserbase
import os
bb = Browserbase(api_key=os.environ["BROWSERBASE_API_KEY"])
try:
response = bb.search.web(query="browserbase")
print(response.results)
except Exception as error:
print(f"Search failed: {error}")