Browser
A cloud browser you connect to over WebSocket. Each session runs its own isolated browser instance on our native engine, a real browser built for automation that renders pages fully. You write navigation and extraction logic, and Spider runs the browser. There are SDKs for TypeScript, Python, and Rust.
Quick start
Install the SDK, export your API key, and open a session.
Connect and scrape
import { SpiderBrowser } from "spider-browser";
const browser = new SpiderBrowser({
apiKey: process.env.SPIDER_API_KEY,
});
await browser.init();
// Navigate to any page
await browser.page.goto("https://www.example.com");
// Get the rendered content as clean text
const content = await browser.page.content();
console.log(content);
await browser.close();Installation
All three SDKs talk to the same endpoint, wss://browser.spider.cloud.
Install the SDK
npm install spider-browser
Navigating pages
Call goto() with a URL. When a site answers with a challenge page, the browser completes it and returns the real page. Use gotoFast() (goto_fast() in Python and Rust) when you do not need to wait for full DOM readiness.
Navigation methods
// Standard navigation, waits for DOM content
await browser.page.goto("https://www.amazon.com/dp/B0DGJHM7QN");
// Fast navigation, returns as soon as possible
await browser.page.gotoFast("https://news.ycombinator.com");
// Wait up to 5s for at least 500 characters of content
const html = await browser.page.content(5000, 500);Zero-config extraction
Call scrape() with nothing at all. Spider reads the rendered page, works out what it is, and names the fields itself. No selectors, no schema, no prompt. Pass domain or slug to use a built-in pattern instead, or fields to pin exact selectors.
No selectors required
await browser.page.goto("https://www.rollingstone.com/music/music-news/");
const data = await browser.page.scrape();
console.log(data);
// {
// headline: "...",
// author: "...",
// published_at: "2026-08-01",
// summary: "...",
// image_url: "https://..."
// }Extracting structured data
Pass CSS selectors to extractFields() and get a JSON object back. Spider runs the selectors server-side, so you never parse HTML yourself. Use it when you know the page structure and want the same fields back every time, with no model involved.
Field extraction
const product = await browser.page.extractFields({
title: "#productTitle",
price: ".a-price .a-offscreen",
rating: "#acrPopover .a-icon-alt",
reviews: "#acrCustomerReviewText",
image: { selector: "#landingImage", attribute: "src" },
});
console.log(product);
// {
// title: "Apple AirPods Pro 2",
// price: "$189.99",
// rating: "4.7 out of 5 stars",
// reviews: "48,239 ratings",
// image: "https://m.media-amazon.com/images/..."
// }Natural language extraction
Use browser.extract() with a plain English prompt when you do not know the page structure ahead of time. It reads the rendered page and returns structured JSON. Pass a schema to get typed, validated output. The AI methods (act, extract, agent) call your own model, so set the llm option with a provider (openai, anthropic, or openrouter), a model, and that provider's API key. In Rust they need the ai cargo feature, which is on by default.
AI-powered extraction
import { z } from "zod";
const browser = new SpiderBrowser({
apiKey: process.env.SPIDER_API_KEY,
llm: { provider: "openai", model: "gpt-4o", apiKey: process.env.OPENAI_API_KEY },
});
await browser.init();
await browser.page.goto("https://www.amazon.com/dp/B0DGJHM7QN");
const Product = z.object({
name: z.string(),
price: z.string(),
return_policy: z.string(),
});
const product = await browser.extract(
"Get the product name, price, and return policy",
{ schema: Product }
);
console.log(product);
// {
// name: "Apple AirPods Pro 2",
// price: "$189.99",
// return_policy: "Returnable within 30 days of delivery"
// }Screenshots
Capture a full-page or viewport screenshot. Returns base64-encoded PNG.
Capture screenshots
import fs from "fs";
// Full page screenshot
const screenshot = await browser.page.screenshot();
// Save to disk
fs.writeFileSync("page.png", Buffer.from(screenshot, "base64"));Page interactions
Use browser.act() with a plain English instruction to click, type, or interact with any element. It needs the llm option. For precise control without a model, use the page's direct DOM methods: click() and fill() take CSS selectors, and type() sends keystrokes to whatever element has focus.
Interact with pages
// Natural language interactions (needs the llm option)
await browser.act("Click the 'Sign In' button");
await browser.act("Type 'hello world' into the search box and press Enter");
// Direct DOM methods, no model involved
await browser.page.fill("#email", "user@example.com");
await browser.page.click("#submit-btn");
// type() sends keystrokes to the focused element
await browser.page.focus("#search");
await browser.page.type("hello world");
await browser.page.press("Enter");Autonomous agent mode
Call page.agent() with a goal. The agent clicks, fills forms, and extracts data in the current tab until the task is complete, and returns { done, rounds, extracted, label }. Works for multi-step workflows where you cannot predict the exact page sequence ahead of time. browser.agent(options).execute(goal) runs the same loop without the single-tab restriction. Both need the llm option.
Autonomous agent
await browser.page.goto("https://news.ycombinator.com");
const result = await browser.page.agent(
"Find the top 3 posts from today and return their titles, " +
"URLs, and point counts as JSON.",
{ maxRounds: 20 }
);
console.log(result.done, result.rounds);
console.log(result.extracted);Fidelity tiers and challenge pages
Set stealth on the connection to pick the proxy quality tier, 1 to 3. Leave it at 0 and Spider starts cheap and moves up a tier when a site turns the session away, up to maxStealthLevels steps. captcha sets what happens on a challenge page: "off" leaves it alone, "detect" reports it, and "solve" has the browser complete it before returning the page.
Tier configuration
const browser = new SpiderBrowser({
apiKey: process.env.SPIDER_API_KEY,
stealth: 0, // Auto-escalate on failure (1-3 pins a tier)
maxStealthLevels: 3, // Allow up to 3 escalation steps
captcha: "solve", // Complete challenge pages before returning
smartRetry: true, // Retry with browser switching on failure
hedge: true, // Mark as a parallel hedge attempt
});stealth at 0 starts on the cheapest tier and moves up only when a site turns the session away. A site that never does stays on that tier for the whole session.Session recording
Set record: true to capture a full session replay. The recording includes every navigation, click, and form fill. The SDK emits recording.started when capture begins and recording.completed with the session id, frame count, and duration once the session closes. Watch the replay in the playground's Browser tab at /playground/?view=browser. There is no API call that returns a playback URL.
Record a session
const browser = new SpiderBrowser({
apiKey: process.env.SPIDER_API_KEY,
record: true,
});
// Fires once the session closes and the recording is saved
browser.on("recording.completed", ({ sessionId, frameCount, durationMs }) => {
console.log(`Recorded ${sessionId}: ${frameCount} frames, ${durationMs}ms`);
});
await browser.init();
await browser.page.goto("https://www.example.com");
await browser.page.click("a");
// Then watch it at /playground/?view=browser
await browser.close();Concurrent sessions
Open up to 100 browser sessions in parallel. Each session is fully isolated: separate browser profile, cookie jar, and proxy. All plans include 100 concurrent sessions.
Parallel sessions
const urls = [
"https://news.ycombinator.com",
"https://reddit.com/r/programming",
"https://lobste.rs",
];
// Open 3 sessions in parallel
const results = await Promise.all(
urls.map(async (url) => {
const browser = new SpiderBrowser({
apiKey: process.env.SPIDER_API_KEY,
});
await browser.init();
await browser.page.goto(url);
const content = await browser.page.content();
await browser.close();
return { url, content };
})
);
console.log(`Scraped ${results.length} sites`);Geo targeting
Set country to route the session through a residential proxy in that region. Supports 199+ country codes. The proxy applies to all navigations within the session.
Country-specific sessions
// Route through a UK proxy
const browser = new SpiderBrowser({
apiKey: process.env.SPIDER_API_KEY,
country: "GB",
});
await browser.init();
await browser.page.goto("https://www.amazon.co.uk/dp/B0DGJHM7QN");
const price = await browser.page.extractFields({
price: ".a-price .a-offscreen",
});
console.log(price); // { price: "£179.99" }Connection options
Full reference for SpiderBrowserOptions. Every field except apiKey is optional.
SpiderBrowserOptions
interface SpiderBrowserOptions {
apiKey: string; // Your Spider API key
serverUrl?: string; // WebSocket server (default: wss://browser.spider.cloud)
browser?: "auto" | "chrome" | "firefox"; // Browser to use (default: "auto")
url?: string; // Target URL hint for browser and proxy selection
stealth?: number; // 1-3 proxy quality tier, 0 = auto-escalate (default: 0)
maxStealthLevels?: number; // Max escalation steps (default: 3)
captcha?: "off" | "detect" | "solve"; // Challenge pages: off, detect, or solve (default: "solve")
smartRetry?: boolean; // Auto-retry with browser switching (default: true)
maxRetries?: number; // Maximum retry attempts (default: 12)
retryTimeoutMs?: number; // Timeout for retry attempts (default: 15000)
hedge?: boolean; // Mark as a parallel hedge attempt (default: false)
country?: string; // Proxy country code, e.g. "US" (default: none)
proxyUrl?: string; // Custom proxy URL, overrides country
mode?: "scraping" | "cua"; // "scraping" for fast text, "cua" for full rendering
record?: boolean; // Record session for playback (default: false)
llm?: LLMConfig; // { provider, model, apiKey } for act/extract/agent
logLevel?: LogLevel; // Log level (default: "info")
connectTimeoutMs?: number; // Connection timeout in ms (default: 30000)
commandTimeoutMs?: number; // Command timeout in ms (default: 30000)
}Raw WebSocket
Connect directly with any CDP-compatible client. Pass your API key and session options as query parameters to wss://browser.spider.cloud/v1/browser. Works with Playwright, Puppeteer, or any WebSocket library that speaks CDP.
Direct WebSocket connection
import { chromium } from "playwright";
const browser = await chromium.connectOverCDP(
"wss://browser.spider.cloud/v1/browser?" +
"token=YOUR_API_KEY&s=2"
);
const page = browser.contexts()[0].pages()[0];
await page.goto("https://www.example.com");
console.log(await page.content());
await browser.close();Create an API key and make your first request in under 3 minutes. SDK source and full examples are on GitHub. See the Browser API reference for endpoint details and pricing.