Browser-as-a-Service
Browser-as-a-Service (BaaS) gives you a real remote Chromium browser you control with Playwright or Puppeteer over a WebSocket. Use it when you need to click, type, log in, or run any multi-step interactive flow — not just fetch a page.
Endpoint: wss://browser.omniscrape.io?apikey=YOUR_API_KEY
Billed: by connection time — $0.02/min standard, $0.10/min with media loaded.
Connect with: Playwright (Node.js or Python) or Puppeteer.
When to use BaaS vs Web Unlocker
| Need | Use |
|---|---|
| Fetch a page's content (HTML, Markdown, JSON) | Web Unlocker |
| Render a SPA and read its content | Web Unlocker (mode: js_rendering) |
| Click buttons, fill forms, basic interactions | Web Unlocker (js_actions) |
| Full login flow (email + password + 2FA) | BaaS |
| Drive many pages in one browser session | BaaS |
| Keep a live browser open across many steps | BaaS |
If you're just reading page content, Web Unlocker is simpler and cheaper. BaaS is for automation flows where you need the full power of Playwright/Puppeteer.
Connect
Playwright — Node.js
import { chromium } from "playwright";
const browser = await chromium.connectOverCDP(
`wss://browser.omniscrape.io?apikey=${process.env.OMNISCRAPE_KEY}`
);
const page = await browser.newPage();
await page.goto("https://example.com/login");
await page.fill("#email", "user@example.com");
await page.fill("#password", "mypassword");
await page.click("button[type=submit]");
await page.waitForSelector(".dashboard");
console.log(await page.title());
await browser.close(); // ends the session — billing stops here
Playwright — Python
import os
from playwright.sync_api import sync_playwright
ws = f"wss://browser.omniscrape.io?apikey={os.environ['OMNISCRAPE_KEY']}"
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp(ws)
page = browser.new_page()
page.goto("https://example.com")
print(page.title())
browser.close() # ends the session — billing stops here
Puppeteer — Node.js
import puppeteer from "puppeteer-core";
const browser = await puppeteer.connect({
browserWSEndpoint: `wss://browser.omniscrape.io?apikey=${process.env.OMNISCRAPE_KEY}`,
});
const page = await browser.newPage();
await page.goto("https://example.com");
console.log(await page.title());
await browser.close();
Connection options
Pass options as query parameters on the WebSocket URL:
| Parameter | Default | Description |
|---|---|---|
apikey | — | Required. Your API key. |
proxy_country | auto | Route through a specific country — ISO code, e.g. us, de, jp. |
render_media | false | Load images, fonts, and video. Billed at the higher rate ($0.10/min) when true. |
session_id | — | Pin the same residential IP across reconnects for sticky flows. |
const url =
"wss://browser.omniscrape.io" +
`?apikey=${process.env.OMNISCRAPE_KEY}` +
"&proxy_country=de" +
"&render_media=false";
const browser = await chromium.connectOverCDP(url);
Billing
The meter starts the moment you connect and stops when the WebSocket closes (either you call browser.close() or the connection drops).
| Mode | Rate |
|---|---|
Standard (render_media=false) | $0.02 / minute |
Full media (render_media=true) | $0.10 / minute |
Always call browser.close() in a finally block — an uncaught error that leaves the socket open keeps billing:
const browser = await chromium.connectOverCDP(wsUrl);
try {
const page = await browser.newPage();
await page.goto("https://example.com");
// ... your automation
} finally {
await browser.close(); // always runs, even on error
}
Tips to keep costs low:
- Keep
render_media=falseunless you explicitly need images loaded. - For pages you only need to read (not interact with), Web Unlocker at $0.0035/request is much cheaper than a browser-minute.
Errors
The WebSocket connection is rejected before it upgrades when:
| HTTP code | Cause |
|---|---|
401 | Missing or invalid apikey. |
402 | Balance too low, trial expired (TRIAL_EXPIRED), or plan concurrent browser limit reached. |
429 | Concurrent browser limit for your plan. Back off and retry. |
Your Playwright/Puppeteer client surfaces these as a failed connection — check the error message for the status code, verify your apikey, and check your account balance in the dashboard.
Alternative WebSocket endpoint
If browser.omniscrape.io is blocked in your network, use the API host instead:
wss://api.omniscrape.io/v1/browser?apikey=YOUR_API_KEY
Both endpoints are equivalent.