> For the complete documentation index, see [llms.txt](/llms.txt)

# BAP

# BAP

Browser Automation Protocol (BAP) is Browserless's automation layer on top of BrowserQL: managed stealth, residential proxies, CAPTCHA solving, and live debugging URLs, driven through a typed, Puppeteer- or Playwright-shaped API instead of hand-written GraphQL. Pick a language below, or send BQL documents directly if you don't want an SDK in the loop.

- A Browserless API token from your [account dashboard](https://browserless.io/account/)
- npm 11.10 or later for the TypeScript SDK, or Python 3.11 or later for the Python SDK

## How it works

BAP doesn't connect over Chrome DevTools Protocol. Each `Page` method builds a BrowserQL mutation, sends it as one JSON frame over a WebSocket, and awaits the response. Operations are queued and run serially, matching BrowserQL's server-side concurrency model.

That architecture is why BAP is fast over the wire: a CDP session sends thousands of small messages for a single interaction, while BAP sends one frame per method call. It's also why the method set is a subset of Puppeteer's and Playwright's. `Page` exposes what BQL can express, and nothing that needs a live CDP session.

Each new page opens its own WebSocket connection. Nothing connects when you call `Browserless.connect()`.

## Which one should I use?

Reach for the **TypeScript** or **Python SDK** first: you get autocomplete, typed options and responses, and method names that match Puppeteer and Playwright respectively, so a mismatched argument fails at the call site instead of silently sending the wrong GraphQL variable.

In **TypeScript**, every option and response is typed, so mistakes surface as compile-time errors rather than runtime GraphQL errors. The package is isomorphic and runs in Node.js or a browser bundle. In **Python**, options and response fields are generated straight from the schema, so a mismatched keyword argument fails at call time, and the package ships matching async (`bap`) and sync (`bap.sync_api`) surfaces. The [Quickstart's runtime notes](/bap/getting-started#runtime-notes) cover both.

Use **BrowserQL directly** when you're not writing TypeScript or Python, want to generate BQL documents from another tool, or are working in the hosted IDE. Every BAP method is a thin wrapper over a BQL mutation, so anything BAP can do, BQL can do too.

Already have Puppeteer or Playwright code you don't want to rewrite? None of these three wrap BQL: connect to [Browsers as a Service](/baas/start) over CDP instead, if you don't need BQL's managed stealth, proxying, or CAPTCHA solving.

## Guides

The guides apply to both SDKs, with TypeScript and Python examples side by side. Start with the [Quickstart](/bap/getting-started), then pick the task in front of you:

## FAQ & Troubleshooting

<details>
<summary>What's the difference between BAP and BrowserQL?</summary>

BrowserQL (BQL) is the GraphQL protocol. BAP is a typed SDK, in TypeScript or Python, built on top of it. Every BAP method sends a BQL mutation under the hood, so anything you can do with BAP, you can do with BQL directly, and vice versa.

</details>

<details>
<summary>Which language should I pick if I don't have a preference?</summary>

Either is fully supported and generated from the same BrowserQL schema, so pick whichever matches the rest of your stack. There's no feature gap between the two SDKs.

</details>