Skip to main content

Browser

A cloud browser you connect to over WebSocket. Each session runs its own isolated browser instance with stealth, fingerprint rotation, and CAPTCHA solving built in. You write navigation and extraction logic. Spider handles the anti-bot work. 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();
Tip
Sessions connect to pre-warmed browser instances. Session creation averages 705ms. Your first navigation is as fast as your hundredth.

Installation

All three SDKs talk to the same endpoint, wss://browser.spider.cloud.

Install the SDK

npm install spider-browser

Call goto() with a URL. Spider detects anti-bot challenges, rotates fingerprints, and solves CAPTCHAs automatically. 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);

Stealth and anti-bot

Set stealth on the connection to pick the proxy quality tier, 1 to 3. Leave it at 0 and Spider starts cheap and escalates automatically when a site blocks it, up to maxStealthLevels.

Stealth 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",     // Automatically solve CAPTCHAs
  smartRetry: true,     // Retry with browser switching on failure
  hedge: true,          // Mark as a parallel hedge attempt
});
Tip
Leaving stealth at 0 starts on the cheapest tier and escalates only when a site blocks the session. A site that never blocks you 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 fingerprint, 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";  // CAPTCHA handling (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.