cdpfleet Docs GitHub Dashboard

CDP & Puppeteer

Add "cdp": true to a launch and the response carries a cdpUrl next to wsUrl: a browser-level Chrome DevTools Protocol WebSocket. Drive it with Puppeteer, Playwright's connectOverCDP() in any language and any recent version, or a raw CDP client — Stagehand, browser-use, chromedp, Rod and most agent frameworks connect this way.

Launch

POST https://starter.cdpfleet.com/chrome/session
x-api-key: <your key>
{ "proxy": "http://user:[email protected]:8080", "headless": "new", "cdp": true }

→ { "sessionId": "…",
    "wsUrl":  "wss://router01.cdpfleet.com/session/…",
    "cdpUrl": "wss://router01.cdpfleet.com/session/…/cdp", … }

Available on Google Chrome, Microsoft Edge, Brave, Opera, Yandex Browser, Chromium. Everything else about the session is unchanged: the same proxy, proxy_rules and live proxy swap, the same timeouts, threads and billing.

Puppeteer

// npm install puppeteer-core
import puppeteer from 'puppeteer-core';

const KEY = process.env.CDPFLEET_API_KEY;
const res = await fetch('https://starter.cdpfleet.com/chrome/session', {
  method: 'POST',
  headers: { 'x-api-key': KEY, 'content-type': 'application/json' },
  body: JSON.stringify({ proxy: 'http://user:[email protected]:8080', headless: 'new', cdp: true }),
});
const { cdpUrl } = await res.json();

const browser = await puppeteer.connect({ browserWSEndpoint: cdpUrl, headers: { 'x-api-key': KEY } });
const page = await browser.newPage();
await page.goto('https://example.com');
console.log(await page.title());
await browser.close(); // ends the session and stops billing

Use puppeteer-core: the browser runs on cdpfleet, nothing to download.

Playwright connectOverCDP

Unlike connect(), connectOverCDP() doesn't need a client of the server's exact version. You get the Chromium-level API; Playwright features that need its own server protocol (for example tracing to a file on the browser side) behave as with any CDP browser.

// npm install [email protected]
// cdp: true — Playwright's connectOverCDP (any recent version), or Puppeteer:
//   puppeteer.connect({ browserWSEndpoint: cdpUrl, headers: { 'x-api-key': KEY } })
// Browsers run on cdpfleet, so no `npx playwright install` is needed.
import { chromium } from 'playwright';

const KEY = process.env.CDPFLEET_API_KEY;

// 1. Launch the browser
const res = await fetch('https://starter.cdpfleet.com/chrome/session', {
  method: 'POST',
  headers: { 'x-api-key': KEY, 'content-type': 'application/json' },
  body: JSON.stringify({
    proxy: 'http://user:[email protected]:8080',
    headless: 'new',
    cdp: true,
  }),
});
if (!res.ok) throw new Error(`launch failed: ${res.status} ${await res.text()}`);
const { cdpUrl } = await res.json();

// 2. Connect and drive it
const browser = await chromium.connectOverCDP(cdpUrl, { headers: { 'x-api-key': KEY } });
const page = await browser.newPage();
await page.goto('https://example.com');
console.log(await page.title());
await browser.close(); // ends the session and stops billing

Raw CDP

Any WebSocket client works. Put the key in the x-api-key header, or in the URL when the client can't set headers:

wss://router01.cdpfleet.com/session/…/cdp?api_key=cdpf_…

→ {"id":1,"method":"Browser.getVersion"}
← {"id":1,"result":{"product":"Chrome/154.0.8037.97", …}}

Rules