The cloud browser API for AI agents.
Open a session from the Spider SDK, or point Playwright at it over CDP. It holds the top Stealth Bench score, 99%, and connects in under a second.
Sign up, then open a live session in the playground. Pay per use, no monthly minimum.
Browser automation for AI agents, in four calls.
The setup at the top of the panel never changes. Pick a call to see what it is for, what you write, and what comes back. Copy takes the setup, the call and the close together, so it runs as pasted.
import { SpiderBrowser } from "spider-browser"
const browser = new SpiderBrowser({
apiKey: process.env.SPIDER_API_KEY,
// act, extract and agent run on a model key you supply
llm: { provider: "openai", model: "gpt-4o", apiKey: process.env.OPENAI_API_KEY },
})
await browser.init()
await browser.goto("https://shop.example/headphones")await browser.act("Sort the results by price, low to high")
await browser.act("Open the first product")await browser.close()
page changes · example
act "Sort the results by price, low to high"
matched select[name="sort"] chose "price-asc"
page 36 results, cheapest first
act "Open the first product"
matched a.product-card:first-child click
page /headphones/studio-wiredconst actions = await browser.observe("Ways to narrow these results")
// no instruction: every interactive element, no model call
const all = await browser.observe()await browser.close()
ObserveResult[] · example
[
{ selector: "select[name=\"sort\"]", tag: "select", type: "select-one",
text: "Featured", rect: { x: 812, y: 164, width: 180, height: 36 }, score: 0.94 },
{ selector: "input#in-stock", tag: "input", type: "checkbox",
text: "In stock only", rect: { x: 32, y: 228, width: 18, height: 18 }, score: 0.88 },
{ selector: "button[data-filter=\"wired\"]", tag: "button", type: "button",
text: "Wired", rect: { x: 32, y: 276, width: 96, height: 32 }, score: 0.71 }
]import { z } from "zod"
const Products = z.array(z.object({
name: z.string(),
price: z.number(),
inStock: z.boolean(),
}))
const products = await browser.extract(
"Every product on the page with its price and stock status",
{ schema: Products },
)await browser.close()
products · example
[
{ name: "Studio Wired", price: 24, inStock: true },
{ name: "Commute ANC", price: 89, inStock: true },
{ name: "Reference Open", price: 349, inStock: false }
]const result = await browser.agent({ maxRounds: 12 }).execute(
"Find the cheapest in-stock headphones and return the name, price and URL"
)await browser.close()
AgentResult · example
round 1 observe 36 products, sort control found
round 2 act sort by price, low to high
round 3 act open "Studio Wired"
round 4 extract name, price, url
{
done: true,
rounds: 4,
label: "Cheapest in-stock headphones",
extracted: { name: "Studio Wired", price: 24,
url: "https://shop.example/headphones/studio-wired" }
}What the session handles for you.
Ready before you ask.
init() attaches to a browser process that is already running, so your first command goes out without waiting for a launch. close() drops the connection; the server disposes that session's contexts and targets and keeps the process warm for the next caller.
- init()
- attach to a warm process
- close()
- dispose contexts, keep the process
- record: true
- session video, +15% compute
Act on the page, then bring data back.
Four natural-language calls sit on top of a full page API. observe() needs no model. act(), extract() and agent() run on the model key you configure, and extract() returns JSON in the zod schema you pass.
- page
- click, fill, type, press, hover, scroll
- wait
- selector, navigation, network idle
- read
- content, screenshot, extractFields
The session handles blocked pages.
CAPTCHA solving is on unless you turn it off, and country picks the exit address. The 999-URL run below is the published record: every URL, its domain and its outcome.
- 999 urls
- 999 passed, 254 domains
- run
- 2026-02-14, published set
Anti-bot pass rate and latency, measured.
Spider passed 79 of 80 anti-bot tasks on Stealth Bench V1 on Sep 18, 2026, the top score of the 8 cloud browsers on the board. A session connects in under a second, and a plain page loads a quarter second after that. Every figure here names its run.
- 99%
- Stealth Bench V1 79 of 80 anti-bot tasks · Sep 18, 2026
- 0.9s
- to connect socket open, key accepted, protocol answering · median · Sep 14, 2026
- 238ms
- page load, once attached example.com to domcontentloaded · median · Sep 14, 2026
Spider passed 79/80 anti-bot tasks on Sep 18, 2026, over loopback through the session proxy that production requests use. Spider's figure is the CDP harness run. Other providers retain the March 22, 2026 readings described in the blog as LLM-judged; they were not re-measured. Production requests use the session proxy.
Scale is more sessions, not a bigger one. An account holds up to 1,000 open sessions and opens up to 100 new ones a minute. Each session takes 500 commands a second sustained with bursts to 1,000, and the 999-URL run held 25 sessions open for 19 minutes with no failures.
Spider passed 79/80 anti-bot tasks on Sep 18, 2026, over loopback through the session proxy that production requests use.
Spider's figure is the CDP harness run. Other providers retain the March 22, 2026 readings described in the blog as LLM-judged; they were not re-measured. Production requests use the session proxy.
Latency is a raw CDP client on a laptop over the public internet, ten warmup rounds and then the measured rounds, the same method as the February speed run. Fifty rounds against google.com gave the connect figure; twenty against example.com gave the page load.
Pick a way in.
The SDK is the whole product: the page API and the four calls. A Playwright or Puppeteer script connects to the same session over CDP and keeps its own API.
- TypeScript
npm install spider-browser
npm ↗ - Python
pip install spider-browser
PyPI ↗ - Rust
cargo add spider-browser
crates.io ↗
A first session
Open, extract one thing with a schema, print it, and close in a finally block so the session closes on an error too.
import { SpiderBrowser } from "spider-browser"
import { z } from "zod"
const browser = new SpiderBrowser({
apiKey: process.env.SPIDER_API_KEY,
country: "DE", // exit from a German address
llm: { provider: "openai", model: "gpt-4o", apiKey: process.env.OPENAI_API_KEY },
})
try {
await browser.init()
await browser.goto("https://shop.example/headphones")
const products = await browser.extract("Every product name and price", {
schema: z.array(z.object({ name: z.string(), price: z.number() })),
})
console.log(products.length, "products, first:", products[0])
} finally {
await browser.close()
}An existing Playwright script
Connect over CDP with your key as the token. The session's proxy and CAPTCHA handling apply to whatever the script does next.
import { chromium } from "playwright"
const browser = await chromium.connectOverCDP(
`wss://browser.spider.cloud/v1/browser?token=${process.env.SPIDER_API_KEY}`
)
const page = await browser.newPage()
await page.goto("https://shop.example/headphones")
console.log(await page.title())
await browser.close()- MCP
Browser tools for Claude, Cursor or any MCP client: open, navigate, click, fill, screenshot, content, and one natural-language step. The four SDK calls are not in the MCP tool set.
MCP server - Desktop
The same browser as an app for macOS on Apple silicon, Windows and Linux.
macOS Windows Linux
Pay for what a session uses.
example inputs: a 5 minute session, 12 MB transferred
- compute 5 min × $0.0001 $0.0005
- bandwidth 0.012 GB × $1 $0.012
- session compute + bandwidth $0.0125
Minutes count from init() to close() and are pro-rated to the millisecond, elapsed time over 60,000 as credits, billed every 3 seconds while the session is open. One credit is $0.0001. Recording multiplies the compute term by 1.15 and leaves bandwidth alone. Your model provider bills the model calls that act(), extract() and agent() make; Spider does not. No monthly minimum. The whole meter, constants included, is in the pricing guide .
Questions.
How do I connect?
Install the SDK (npm, pip or cargo, package name spider-browser), pass your Spider API key to the constructor and call init(). That attaches you to a browser that is already running. If you have a Playwright or Puppeteer script, connect it to wss://browser.spider.cloud/v1/browser with your key as the token and keep the script.
Can I keep my Playwright or Puppeteer code?
Yes. The session speaks CDP over a WebSocket, so connectOverCDP() and puppeteer.connect() attach to it, and the same proxy handling and CAPTCHA solving apply. act(), observe(), extract() and agent() are SDK calls, so a script that wants them uses the SDK.
What do act, extract and agent need from me?
A model key. Pass an llm option with a provider (OpenAI, Anthropic or OpenRouter), a model name and your key, and those three calls use it. Spider does not bill for model calls; your provider does. observe() runs without a model when you call it with no instruction.
What happens to a session when I am done?
Call close(). It drops the WebSocket, and the server disposes the contexts, targets and backend session that belonged to it. The browser process itself stays warm for the next caller, which is why init() does not wait for a launch.
What happens when a page blocks the browser?
The session handles it. CAPTCHA solving is on unless you set captcha to off, and country picks the exit address. Some pages still fail; the dataset run linked above lists every URL and its outcome.
How fast is a session?
Under a second to connect. On Sep 14, 2026, a raw CDP client on a laptop opened the socket, had its key accepted and got a protocol answer in a median 0.9s, then loaded example.com to domcontentloaded in a median 238ms. The browser process is already running, so init() never waits for a launch.
How reliable is it on protected sites?
Spider passed 79 of 80 anti-bot tasks on Stealth Bench V1 on Sep 18, 2026, a 99% score, on pages behind Cloudflare, Akamai, PerimeterX and DataDome. That is the top score on the board of 8 cloud browsers. The tasks and the harness are public at github.com/spider-rs/benchmark.
How many sessions can I run at once?
Up to 1,000 open sessions per account by default, opened at up to 100 a minute. Each session takes 500 commands a second sustained, with bursts to 1,000, and a session can stay open for 30 minutes before the server ends it. The 999-URL run held 25 sessions open for 19 minutes with no failures.
How does it compare with Browserbase, Kernel or Browser Use?
On the same Stealth Bench tasks the March 22, 2026 readings were Browser Use Cloud 81%, Onkernel 68%, Browserbase 41%, against Spider's 99% on Sep 18, 2026. Kernel publishes a faster session start. Spider publishes the whole pipeline, connect through page load, and the pass rate on the hard pages, because that is where an agent spends its time.
Which languages are supported?
TypeScript, Python and Rust, with the same calls in each: init, goto, act, observe, extract, agent. The page API underneath (click, fill, type, press, scroll, waits, screenshot, content) is there in all three too.
What does it cost?
$1 per GB transferred and $0.0001 per minute while a session is open (one credit a minute), with no monthly minimum. Recording a session adds 15% to its compute. Your model provider bills the model calls that act, extract and agent make; Spider does not.
Open a session and see what comes back.
An account, a key, and init(). One session or a hundred a minute, pay per use, no monthly minimum.