Skip to main content
cdpUrl is a WebSocket endpoint to the session’s Chrome. Any CDP client can attach. You never launch a browser.
Use Patchright, not stock Playwright or Puppeteer. It’s Playwright’s API minus the CDP calls anti-bot systems fingerprint; Playwright code moves over by changing one import, Puppeteer code needs porting. Stock frameworks get blocked on sites that look for automation.

Other clients

Playwright

Works, with the caveats above.

Puppeteer

puppeteer-core with browserWSEndpoint.

Browser Use

Agents on a Driver browser.

Stagehand

Natural-language actions over CDP.

Reuse the context and tab

The browser opens with one context and one tab. Reuse them; fresh incognito contexts and blank pages don’t look like a person’s Chrome.
Need more tabs? context.newPage() on the existing context.

Disconnecting versus stopping

browser.close() (Patchright, Playwright) and browser.disconnect() (Puppeteer) end your connection only. The session runs, and bills, until DELETE /v1/browser/session or its duration. Reconnect to the same cdpUrl as often as you like while it’s active.

Reconnecting

If your process crashes, GET /v1/browser/session: while status is active the cdpUrl still works. If the session ended, a profile with persist: true carries the state into a new one. Several clients can attach at once (your script and the live view, say), but two scripts driving one tab fight each other: one automation client per session. cdpUrl is a credential. Its hostname is a relay near the machine, not the session’s network; egress is from the country you asked for whatever host you connect to.

Timeouts and waits

Real machines on real networks: page loads take real time. Use the framework’s auto-waiting (page.click, locator.waitFor), not fixed sleeps, and raise the navigation timeout for slow sites instead of retrying in a loop.