Browsers
Some pages are built by JavaScript after they load: the HTML the server sends doesn't contain the data. To get it, load the page in a real browser with options.browser:
"options": { "browser": true }See it work
This page writes a paragraph with JavaScript. Without a browser, the API reads the HTML as sent, before any script runs:
Actions
Data
With a browser, the script runs first:
Actions
Data
{
"browser": { "engine": "chromium", "driver": "playwright", "stealth": "plugin" },
"data": ["Served by the server", "Rendered by JavaScript"]
}A browser is slower than a plain request (about a second, more for stealth engines) and uses more resources. Use it when the data needs JavaScript, or when a site only lets real browsers in.
Engines
| Engine | Based on | Stealth | Speed | When to use it |
|---|---|---|---|---|
chromium (default) | Chromium | stealth plugin | fast | Most JavaScript sites |
firefox | Firefox | none | fast | Sites that behave differently in Firefox |
camoufox | Firefox, Camoufox | built in: fingerprint spoofing at the C++ level | slower | Sites with serious bot protection |
cloakbrowser | Chromium, CloakBrowser | built in: patched in the browser source | fast | Sites with serious bot protection, Chromium flavour |
lightpanda | Lightpanda, a browser written for automation | none | fastest, lightest | Simple JavaScript pages at volume |
Pick one by name:
"options": { "browser": "camoufox" }GET /browsers lists the engines installed on this server.
Drivers
A driver is the library that controls the browser. Each engine has a default; choose another with driver:
| Driver | Engines |
|---|---|
playwright | chromium (default), firefox (default), camoufox (default), cloakbrowser (default), lightpanda |
puppeteer | chromium, cloakbrowser, lightpanda (default) |
patchright | chromium: a Playwright build patched to leave no automation traces |
"options": { "browser": { "engine": "chromium", "driver": "puppeteer" } }Stealth
stealth is on by default. What it does depends on the engine:
| Engine and driver | Stealth |
|---|---|
chromium with Playwright or Puppeteer | the puppeteer-extra stealth plugin hides automation traces (navigator.webdriver, plugins, WebGL vendor…) |
chromium with patchright | built into the driver |
camoufox, cloakbrowser | built into the browser, can't be turned off |
firefox, lightpanda | none exists: use camoufox or cloakbrowser when it matters |
"stealth" in the response tells you what applied: "plugin", "builtin" or "off".
Options
browser accepts true, an engine name, or an object:
| Property | Type | Default | Description |
|---|---|---|---|
engine | string | "chromium" | chromium, firefox, camoufox, cloakbrowser or lightpanda (chrome is accepted for chromium) |
driver | string | per engine | playwright, puppeteer or patchright |
stealth | boolean | true | See Stealth |
wait_until | string | "load" | When the page counts as loaded: domcontentloaded, load, networkidle (no network activity for 500 ms) or commit |
wait_for | string | — | A CSS selector to wait for before extracting |
block | string[] or false | ["media", "font", "ads", "trackers"] | What the browser doesn't download, see Block resources. false loads everything |
viewport | object | { "width": 1920, "height": 1080 } | Window size |
capture | object | — | Capture the page's own JSON requests, see below |
headless | boolean | true | false needs a display on the server |
strict | boolean | false | Fail instead of substituting, see below |
"options": {
"browser": {
"engine": "cloakbrowser",
"wait_until": "networkidle",
"wait_for": ".product",
"block": ["image", "font"]
}
}Block resources
Pages load faster and use less proxy bandwidth when the browser skips what scraping doesn't need. block lists what to skip:
| Value | Skips |
|---|---|
image | Images. Off by default: screenshots and lazy-loaded content need them |
media | Audio and video |
font | Web fonts |
stylesheet | CSS. Pages may lay out or behave differently without it |
ads | Requests to the main ad networks (Google Ads, Amazon, Criteo, Taboola, Outbrain…) |
trackers | Requests to analytics and tracking services (Google Analytics and Tag Manager, Hotjar, Segment, Clarity…) |
The default is ["media", "font", "ads", "trackers"]. Your list replaces it, it doesn't add to it, and false loads everything:
"browser": { "block": ["image", "media", "font", "stylesheet", "ads", "trackers"] }Ads and trackers are refused by host name, whatever the engine and driver. If the page you scrape is itself on one of those hosts, it still loads. Without a browser, block has nothing to do: only the HTML is downloaded.
Capture the page's API calls
Many sites load their data from their own JSON API after the page loads. Instead of scraping the rendered HTML, capture those responses as they are:
Actions
Data
"captured": [
{ "url": "…/demo/shop/api", "status": 200, "json": { "page": 1, "stock": [ … ] } }
]| Property | Description |
|---|---|
url_contains | Keep responses whose URL contains this text |
post_data_contains | Keep only requests whose body contains all of these texts |
timeout | How long to wait for a first match after the page loads, in ms. Default 5000 |
Only JSON responses are kept, 20 at most.
Everything else still applies
Browsers work with the other options:
- Actions click, type and scroll in the page.
- Proxies, of any type, carry the browser's traffic.
- Custom requests:
method,body,headersandcookiesapply to the first request, the one that loads the page. - Retries, fallbacks, timeouts and the cache work the same.
- Cookies set by the site are kept for the rest of the request: actions, retries and fallbacks, browser or not.
When something can't be done
Rather than failing, the API adapts the request and says so in warnings:
| You asked for | The API does |
|---|---|
| An engine that isn't installed | Uses the closest installed one: cloakbrowser → chromium, camoufox → firefox… |
A driver the engine doesn't support (camoufox with puppeteer) | Uses the engine's default driver |
stealth on firefox or lightpanda | Runs without |
| A fingerprint on a stealth browser | Keeps the browser's own fingerprint |
follow_redirects: false or max_redirects | Browsers follow redirects themselves: ignored |
"warnings": ["camoufox can't be driven by puppeteer: used playwright instead"]Set "strict": true to get 503 BROWSER_UNAVAILABLE instead of a substitution.