> ## Documentation Index
> Fetch the complete documentation index at: https://perplexity-cf-proxied-beta.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Browser

> Remote browser automation via Chrome DevTools Protocol (CDP) with Playwright or any CDP client.

## Overview

The Browser API provides remote browser automation via Chrome DevTools Protocol (CDP). Connect using Playwright, Puppeteer, or any CDP-compatible client to automate web interactions in isolated browser environments.

<Info>
  Browsers auto-terminate after 5 minutes of inactivity.
</Info>

## Authentication

Set your API key as an environment variable:

<Tabs>
  <Tab title="macOS/Linux">
    ```bash theme={null}
    export PERPLEXITY_API_KEY="your_api_key_here"
    ```
  </Tab>

  <Tab title="Windows">
    ```powershell theme={null}
    setx PERPLEXITY_API_KEY "your_api_key_here"
    ```
  </Tab>
</Tabs>

## Quick Start

Create a browser session, connect via CDP, and clean up:

<CodeGroup>
  ```python Python SDK theme={null}
  import asyncio
  import os
  from perplexity import Perplexity
  from playwright.async_api import async_playwright

  client = Perplexity()

  # Create browser session
  # Note: Use extra_body={} to ensure empty JSON body is sent
  session = client.browser.sessions.create(extra_body={})
  print(f"Session ID: {session.session_id}")

  # Connect via CDP
  async def browse():
      ws_url = f"wss://api.perplexity.ai/v1/browser/proxy/sessions/{session.session_id}/websocket?token={client.api_key}"

      async with async_playwright() as p:
          browser = await p.chromium.connect_over_cdp(ws_url)
          page = await browser.new_page()
          await page.goto("https://example.com")
          print(await page.title())
          await browser.close()

  asyncio.run(browse())

  # Cleanup
  client.browser.sessions.delete(session_id=session.session_id)
  ```

  ```python Python (HTTP) theme={null}
  import asyncio
  import requests
  import os
  from playwright.async_api import async_playwright

  API_KEY = os.getenv("PERPLEXITY_API_KEY")

  headers = {
      "Content-Type": "application/json",
      "Authorization": f"Bearer {API_KEY}"
  }

  # Create browser session
  session = requests.post(
      "https://api.perplexity.ai/v1/browser/sessions",
      json={},
      headers=headers
  ).json()
  session_id = session["session_id"]
  print(f"Session ID: {session_id}")

  # Connect via CDP
  async def browse():
      ws_url = f"wss://api.perplexity.ai/v1/browser/proxy/sessions/{session_id}/websocket?token={API_KEY}"

      async with async_playwright() as p:
          browser = await p.chromium.connect_over_cdp(ws_url)
          page = await browser.new_page()
          await page.goto("https://example.com")
          print(await page.title())
          await browser.close()

  asyncio.run(browse())

  # Cleanup
  requests.delete(
      f"https://api.perplexity.ai/v1/browser/sessions/{session_id}",
      headers=headers
  )
  ```

  ```bash cURL theme={null}
  # Create browser session
  SESSION=$(curl -s -X POST \
    "https://api.perplexity.ai/v1/browser/sessions" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $PERPLEXITY_API_KEY" \
    -d '{}')
  SID=$(echo $SESSION | jq -r '.session_id')
  echo "Session ID: $SID"

  # WebSocket URL for CDP connection:
  # wss://api.perplexity.ai/v1/browser/proxy/sessions/$SID/websocket?token=$PERPLEXITY_API_KEY

  # Cleanup
  curl -s -X DELETE \
    "https://api.perplexity.ai/v1/browser/sessions/$SID" \
    -H "Authorization: Bearer $PERPLEXITY_API_KEY"
  ```
</CodeGroup>

<Accordion title="Response">
  ```json theme={null}
  {
    "session_id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "running"
  }
  ```
</Accordion>

## Endpoints

| Method | Endpoint                    | Description            |
| ------ | --------------------------- | ---------------------- |
| POST   | `/v1/browser/sessions`      | Create browser session |
| DELETE | `/v1/browser/sessions/{id}` | Stop browser session   |

## WebSocket Connection (CDP)

Connect to the browser via Chrome DevTools Protocol:

```
wss://api.perplexity.ai/v1/browser/proxy/sessions/{session_id}/websocket?token=<YOUR_TOKEN>
```

<Note>
  The WebSocket URL uses `token` as a query parameter for authentication, not the `Authorization` header.
</Note>

## Examples

Once connected via CDP, you have full browser automation capabilities. Here are common operations:

### Take a Screenshot

```python theme={null}
# Save screenshot to file
await page.screenshot(path="screenshot.png")

# Get screenshot as bytes
screenshot_bytes = await page.screenshot()

# Full page screenshot (scrolls entire page)
await page.screenshot(path="fullpage.png", full_page=True)
```

### Navigate and Get Page Info

```python theme={null}
# Navigate to URL
await page.goto("https://example.com")

# Get current page info
title = await page.title()
url = page.url
content = await page.content()

print(f"Title: {title}")
print(f"URL: {url}")
print(f"Content length: {len(content)} characters")
```

### Execute JavaScript

```python theme={null}
# Run JavaScript and get result
result = await page.evaluate("document.title")

# Evaluate expressions
count = await page.evaluate("document.querySelectorAll('a').length")
print(f"Found {count} links on page")

# Modify the page
await page.evaluate("document.body.style.backgroundColor = 'lightblue'")
```

### Navigation Controls

```python theme={null}
# Go back to previous page
await page.go_back()

# Go forward
await page.go_forward()

# Reload current page
await page.reload()

# Wait for navigation
await page.goto("https://example.com", wait_until="networkidle")
```

### Extract Page Content

```python theme={null}
# Get all visible text
text = await page.inner_text("body")

# Get specific element text
heading = await page.inner_text("h1")

# Get element attribute
href = await page.get_attribute("a.main-link", "href")

# Query multiple elements
links = await page.query_selector_all("a")
for link in links:
    print(await link.get_attribute("href"))
```

### Interact with Elements

```python theme={null}
# Click a button
await page.click("button#submit")

# Fill a form field
await page.fill("input[name='search']", "perplexity")

# Press keyboard keys
await page.press("input[name='search']", "Enter")

# Select dropdown option
await page.select_option("select#country", "US")
```

<Tip>
  For more Playwright operations, see the [Playwright documentation](https://playwright.dev/python/docs/api/class-page).
</Tip>

## Rate Limits

| Limit                            | Value     |
| -------------------------------- | --------- |
| Browsers created per minute      | 5         |
| Concurrent browsers              | 10        |
| Requests per second (other APIs) | 1         |
| Inactivity timeout               | 5 minutes |

<Warning>
  Always delete browser sessions when done. Sessions count toward your concurrent limit (10) and will block new session creation if the limit is reached. Sessions auto-terminate after 5 minutes of inactivity, but manual cleanup is recommended.
</Warning>

## Pricing

Browser sessions are billed based on compute time usage.

| Price per Hour | Minimum Billing              |
| :------------: | ---------------------------- |
|     \$0.25     | Rounded up to nearest minute |

<Note>
  **Usage Calculation:** Billing is calculated based on the total time your browser session is active, rounded up to the nearest minute. For example, a session running for 1 minute and 15 seconds will be billed for 2 minutes (\$0.0083).

  See detailed pricing information and cost examples for all Perplexity APIs on our [Pricing page](/docs/getting-started/pricing).
</Note>

<Card title="Contact Sales" icon="file-pencil" iconType="solid" href="https://perplexity.typeform.com/to/nXeehCGo">
  Get in touch with our team to discuss enterprise pricing and custom requirements.
</Card>

## Error Codes

| Code | Meaning             |
| :--: | ------------------- |
|  400 | Invalid request     |
|  404 | Session not found   |
|  429 | Rate limit exceeded |
|  500 | Internal error      |

## Next Steps

<CardGroup cols={2}>
  <Card title="Browser API Reference" icon="book" href="/api-reference/browser-sessions-post">
    Complete API documentation for browser endpoints.
  </Card>
</CardGroup>
