Documentation

Everything you need to automate browsers in the cloud. Get from zero to running in under a minute.

Quickstart

1. Install the Python SDK:

pip install browserfabric

2. Set your API key:

export BROWSERFABRIC_API_KEY=bf_your_key_here

3. Run your first automation:

import browserfabric
import asyncio

async def main():
    async with browserfabric.browser() as session:
        await session.navigate("https://example.com")
        page = await session.snapshot()
        print(page)

asyncio.run(main())

Or use the REST API directly with curl:

# Create a session
curl -X POST https://api.browserfabric.com/api/v1/services/browseruse/call \
  -H "Authorization: Bearer bf_your_key" \
  -H "Content-Type: application/json" \
  -d '{"tool_name": "create_session", "arguments": {"headless": true}}'

Authentication

All API requests require an API key passed as a Bearer token in the Authorization header. Create keys from your dashboard.

Authorization: Bearer bf_your_api_key_here
POST/api/v1/auth/keysAuth required

Create a new API key. The raw key is only shown once.

Request Body

{
  "name": "My Production Key",
  "permissions": {
    "browseruse": true,
    "web_search": true,
    "web_crawler": true
  }
}

Response

{
  "api_key": "bf_abc123...",
  "key_prefix": "bf_abc123x",
  "name": "My Production Key",
  "permissions": {...}
}
GET/api/v1/auth/keysAuth required

List all API keys for your account. Keys are shown by prefix only.

DELETE/api/v1/auth/keys/{key_id}Auth required

Revoke an API key. This action is immediate and irreversible.

Sessions

A session is a cloud browser instance. Each session runs a full Chromium browser and exposes a CDP WebSocket for direct connection.

POST/api/v1/services/browseruse/callAuth required

Create a new browser session. Returns session_id and ws_url for CDP connections.

Request Body

{
  "tool_name": "create_session",
  "arguments": {
    "headless": true,
    "timeout": 30,
    "context_id": "optional-context-uuid",
    "persist": true
  }
}

Response

{
  "success": true,
  "result": {
    "session_id": "uuid",
    "ws_url": "ws://host:port",
    "cdp_port": 12345,
    "context_restored": false
  }
}
POST/api/v1/services/browseruse/callAuth required

Close a session. If persist=true was set, cookies and localStorage are saved automatically.

Request Body

{
  "tool_name": "close_session",
  "arguments": {},
  "session_id": "your-session-id"
}
POST/api/v1/services/browseruse/callAuth required

Get session metadata including CDP WebSocket URL and current page info.

Request Body

{
  "tool_name": "get_session_info",
  "arguments": {},
  "session_id": "your-session-id"
}

Persistent Contexts

Contexts save cookies and localStorage so you can resume sessions later without re-authenticating. There are two ways to persist:

Auto-persist on close

Set persist: true when creating a session. State is saved automatically when the session closes.

Manual save

Call save_context at any time during a session to snapshot the current browser state.

GET/api/v1/contextsAuth required

List all saved persistent contexts for your account.

Response

{
  "contexts": [
    {
      "id": "uuid",
      "name": "twitter-login",
      "domain": "https://twitter.com/",
      "cookies_count": 12,
      "created_at": "2026-03-16T..."
    }
  ],
  "total": 1
}
DELETE/api/v1/contexts/{context_id}Auth required

Delete a saved context.

CDP WebSocket

Every session exposes a Chrome DevTools Protocol WebSocket URL. Connect to it with Playwright, Puppeteer, or any CDP client for full browser control.

from playwright.async_api import async_playwright

# 1. Create session via BrowserFabric API
# response.result.ws_url = "ws://api.browserfabric.com:PORT"

# 2. Connect with Playwright
pw = await async_playwright().start()
browser = await pw.chromium.connect_over_cdp(ws_url)
page = browser.contexts[0].pages[0]

# 3. Full Playwright API available
await page.goto("https://example.com")
await page.screenshot(path="screenshot.png")
await page.fill("#email", "user@example.com")
await page.click("button[type=submit]")

MCP Integration

BrowserFabric is a hosted Model Context Protocol server. Point any MCP-speaking agent — Claude Desktop, Cursor, Cline, the Anthropic Agent SDK, your own app — at https://www.browserfabric.com/mcp with your API key and you get all 28 browser tools (create_session, navigate, click_element, type_text, take_screenshot, evaluate_js, save_context, list_contexts, and more).

Endpoint: https://www.browserfabric.com/mcp
Transport: streamable-http
Auth: Authorization: Bearer bf_your_api_key

Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "browserfabric": {
      "url": "https://www.browserfabric.com/mcp",
      "headers": {
        "Authorization": "Bearer bf_your_api_key_here"
      }
    }
  }
}

Quit and relaunch Claude Desktop. The tools appear under the 🔌 icon in the composer.

Cursor

Open Cursor Settings → Features → MCP Servers → Add, then paste:

{
  "name": "browserfabric",
  "type": "http",
  "url": "https://www.browserfabric.com/mcp",
  "headers": {
    "Authorization": "Bearer bf_your_api_key_here"
  }
}

Cline / Continue / any MCP-compatible client

Any client that speaks the MCP streamable-http transport can use the same URL. Most accept a headers map next to the URL — put your bearer token there.

Python (Claude Agent SDK, MCP library)

import asyncio
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async def main():
    async with streamablehttp_client(
        "https://www.browserfabric.com/mcp",
        headers={"Authorization": "Bearer bf_your_api_key_here"},
    ) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            tools = await session.list_tools()
            print([t.name for t in tools.tools])

            r = await session.call_tool("create_session", {"headless": True})
            session_data = r.content[0].text  # JSON string

asyncio.run(main())

TypeScript (Anthropic Agent SDK)

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

const stream = client.beta.messages.stream({
  model: "claude-opus-4-6",
  max_tokens: 4096,
  mcp_servers: [
    {
      type: "url",
      url: "https://www.browserfabric.com/mcp",
      name: "browserfabric",
      authorization_token: "bf_your_api_key_here",
    },
  ],
  messages: [
    { role: "user", content: "Open example.com and summarise the page." },
  ],
});

for await (const event of stream) {
  // MCP tool calls happen automatically via the SDK's MCP connector
}

A note on persistence

Sessions you create over MCP are the same sessions you see in your dashboard Sessions tab, and contexts saved with save_context are reusable across MCP, REST, and the SDKs — that's the whole point of a hosted cloud browser. An agent can hand a running tab off to a human (and vice versa) just by sharing the session_id.

Usage Tracking

Every API call is tracked with timing data. Query your usage from the API or view it on your dashboard.

GET/api/v1/usage?days=30Auth required

Get usage summary. Defaults to 30 days.

Response

{
  "total_calls": 142,
  "period_days": 30,
  "by_service": {
    "browseruse": 128,
    "web_search": 14
  }
}

Python SDK

pip install browserfabric

Full example with persistent context:

import browserfabric
import asyncio

async def main():
    client = browserfabric.Client(
        api_key="bf_your_key",
        base_url="https://api.browserfabric.com"
    )

    # Create session with persistence
    async with client.browser(persist=True) as session:
        await session.navigate("https://example.com")
        await session.click("#login-btn")
        await session.type_text("#email", "user@example.com")
        screenshot = await session.screenshot()

        # Save context manually
        ctx = await session.save_context("my-login")
        print(f"Saved context: {ctx['context_id']}")

    # Later: restore the context
    async with client.browser(context_id=ctx['context_id']) as session:
        # Cookies and localStorage are restored
        info = await session.session_info()
        print(f"Restored: {info}")

asyncio.run(main())

Error Handling

401

Unauthorized

Missing or invalid API key. Check your Authorization header.

403

Forbidden

Your API key doesn't have permission for this service.

404

Not Found

Service not running or resource doesn't exist.

429

Too Many Requests

Rate limit exceeded. Back off and retry.

All tool call responses follow this format:

{
  "success": true | false,
  "result": { ... },
  "session_id": "uuid or null",
  "error": "error message or null"
}

Base URL

All API endpoints are relative to:

https://api.browserfabric.com/api/v1