> ## Documentation Index
> Fetch the complete documentation index at: https://docs.browserbase.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Search

> Fast, token-efficient web search results as a complement to browser sessions.

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](/platform/browser/getting-started/create-browser-session) for interaction.

## Perform a search

Send a `POST` request to `/v1/search` with your query. Authenticate with the same `x-bb-api-key` header used across the Browserbase API.

<Tabs>
  <Tab title="Node.js">
    <CodeGroup>
      ```typescript SDK theme={null}
      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}`);
      }
      ```

      ```typescript REST theme={null}
      const response = await fetch("https://api.browserbase.com/v1/search", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-bb-api-key": process.env.BROWSERBASE_API_KEY!,
        },
        body: JSON.stringify({
          query: "browserbase",
          numResults: 10,
        }),
      });

      const data = await response.json();

      console.log(`Request ID: ${data.requestId}`);
      for (const result of data.results) {
        console.log(`${result.title} - ${result.url}`);
      }
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Python">
    <CodeGroup>
      ```python SDK theme={null}
      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}")
      ```

      ```python REST theme={null}
      import requests
      import os

      response = requests.post(
          "https://api.browserbase.com/v1/search",
          headers={
              "Content-Type": "application/json",
              "x-bb-api-key": os.environ["BROWSERBASE_API_KEY"],
          },
          json={
              "query": "browserbase",
              "numResults": 10,
          },
      )

      data = response.json()

      print(f"Request ID: {data['requestId']}")
      for result in data["results"]:
          print(f"{result['title']} - {result['url']}")
      ```
    </CodeGroup>
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    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
      }'
    ```
  </Tab>
</Tabs>

### 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, such as extracting content, filling forms, or taking screenshots.

<Tabs>
  <Tab title="Node.js">
    <CodeGroup>
      ```typescript Playwright theme={null}
      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();
      }
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Python">
    <CodeGroup>
      ```python Playwright theme={null}
      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()
      ```
    </CodeGroup>
  </Tab>
</Tabs>

## Rate limits

The Search API is rate limited to **120 requests per minute** per project. Exceeding this returns a `429` status code.

<Tip>
  For high-volume use cases, space out your requests or implement exponential
  backoff in your retry logic.
</Tip>

## 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                                    |

<Tabs>
  <Tab title="Node.js">
    ```typescript SDK theme={null}
    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);
      }
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python SDK theme={null}
    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}")
    ```
  </Tab>
</Tabs>

## When to use Search

Use Search when your browser agent doesn’t yet know where the information lives. In other words, it will give you the best starting points on the web for some task.

Think about [Search](/platform/search/overview) -> [Fetch](/platform/fetch/overview) -> [Browsers](/platform/browser/getting-started/create-browser-session)

* **[Search:](/platform/search/overview)** Find relevant sources (website, news, docs).
* **[Fetch:](/platform/fetch/overview)** Quickly extract content from most pages, and filter out low-value results.
* **[Browsers:](/platform/browser/getting-started/create-browser-session)** Log in to portals with [agent identity](/platform/identity/overview), navigate complex pages, and extract the hard-to-reach data.

<CardGroup cols={1}>
  <Card title="Need more help deciding which API?" icon="book-open" iconType="sharp-solid" href="https://www.browserbase.com/blog/search-vs-fetch-vs-browsers">
    Read our [full guide](https://www.browserbase.com/blog/search-vs-fetch-vs-browsers) breaking down which API to use with examples.
  </Card>
</CardGroup>
