Skip to main content

bro

🔮 We've abstracted away the chaos of the web so you can focus on building.

bro is a stealth agentic browser built to handle everything from everyday pages to the most complex and well-protected websites. It lets you and your agents reliably navigate the web and extract data at scale without getting blocked.

Instead of juggling low-level CDP commands, managing infrastructure and handling proxies, you control a fully headed, actual rendered Chrome browser through a simple, agents-friendly Python library. Every session runs on an isolated VM instance - you don't share compute resources or IPs.

Features

  • Zero-headache API: 🧘‍♂️ Whether you're navigating, extracting data or parsing DOM, every command has complex underlying logic built-in - it keeps the agent in a single tab, handles dynamic page loads, automatically retries failures, handles downloads, manages timeouts and CDP syncs.
  • Two powerful modes:
    • Autopilot: 🤖 Let bro autonomously navigate and extract structured data on the fly.
    • Manual: 🕹️ Get full, deterministic control of the browser via agent-friendly commands.
  • Stealth features: 🥷 Clean browser fingerprints, human-like interaction, customizable network routing, and proxy tracking.
  • Flexible & cost-effective: 📉 Cut costs by customizing proxy and AI configurations based on your specific task.

Installation

Install the package via pip (requires Python 3.8+):

pip install bro-api-sdk

Getting a Token (Sign Up)

To use the bro-api-sdk, you need an API key. You can get one by signing up:

Quick Start Examples

Below are a couple of examples showcasing how easy it is to use bro to handle the browser. Both use a straightforward session context manager that handles all lifecycle and cleanup automatically.

1. Parsing Text and URLs

Extracting clean text and URLs directly from the rendered page layout.

from bro import BroClient, commands

# Initialize the client
client = BroClient(api_key="your_api_key_here")

# Use a context manager to ensure the session is properly stopped
with client.create_session() as session:
    print(f"Session started: {session.session_id}")
    
    # Execute commands sequentially in a batch
    result = session.execute([
        commands.open_url(url="https://news.ycombinator.com/"),
        commands.parse_text(),
        commands.parse_urls()
    ])
    
    if result.get("status") == "done":
        # parse_text returns a raw string natively
        print("--- Text ---")
        print(result["response"]["commands"][1]["data"])
        
        # parse_urls returns a dictionary containing 'links' and 'images' arrays
        print("--- URLs ---")
        print(result["response"]["commands"][2]["data"])

print(f"\n--- Session Usage Stats ---")
if session.billing:
    print(f"Total billed: ${session.billing.get('total_billed', 0):.4f}")

2. Extracting data using Autopilot extract command

If you already have a target URL, you can extract structured data directly, including automatically clicking "Next" to traverse multiple pages. The AI will analyze the DOM and visual data on the page to extract JSON for you based on your schema.

import json
from bro import BroClient, commands

client = BroClient(api_key="your_api_key_here")

with client.create_session() as session:
    print(f"Session started: {session.session_id}")
    
    result = session.execute([
        commands.open_url(url="https://news.ycombinator.com/"),
        commands.extract(
            data_instruction="Extract a list of top publications on this page",
            json_schema=[{
                "title": "<post title>",
                "link": "<post URL>",
                "points": "<number of points>"
            }],
            model_size="medium",
            paginate=True,         # Let AI find the 'Next' button and merge data
            pages_to_paginate=2    # Max pages to navigate through
        )
    ])
    
    if result.get("status") == "done":
        for cmd in result.get("response", {}).get("commands", []):
            if cmd.get("command") == "extract":
                print(f"\nExtracted Data:\n{json.dumps(cmd.get('data'), indent=2)}")

print(f"\n--- Session Usage Stats ---")
if session.billing:
    print(f"Total billed: ${session.billing.get('total_billed', 0):.4f}")
if session.tokens:
    print(f"LLM Tokens: {session.tokens.get('total', 0)}")

3. AI Actions & Data Extraction

You can combine commands to navigate complex flows before extracting data. This example uses Autopilot to type into a search box, press enter, and extract the top results.

import json
from bro import BroClient, commands

client = BroClient(api_key="your_api_key_here")

with client.create_session(
    enable_proxy=True,
    proxy_tier="basic",
    proxy_policy="extended",
    country="US"
) as session:
    session_id = session.session_id
    print(f"Session started: {session.session_id}, stream: {session.stream_url}")
    
    print("\nExecuting commands")
    batch_result = session.execute([
        commands.open_url(url="https://news.ycombinator.com"),
        commands.act(
            instruction="type 'llm' in the search box",
            max_steps=2,
            model_size='medium'
        ),
        commands.press(keys='enter'),
        commands.extract(
            data_instruction="Extract the top 5 news titles and their links.",
            json_schema=[{
                "title": "<title of the publication>",
                "url": "<direct URL to the publication>",
                "summary": "<summary of the publication, less than 10 words>",
                "company_mentioned": "<company name mentioned in the publication, set a primary company if multiple have been mentioned>",
            }],
            model_size="small"
        )
    ])
    
    if batch_result["status"] == "done":
        commands_executed = batch_result.get("response", {}).get("commands", [])
        for i, cmd in enumerate(commands_executed):
            cmd_name = cmd.get("command", "unknown")
            data = cmd.get("data", {})
            
            if cmd_name == "extract":
                output = data.get("extracted_json")
            elif cmd_name == "act":
                output = data.get("action_steps")
            else:
                output = data
                
            print(f"\n--- [{i}] {cmd_name.upper()} ---")
            print(json.dumps(output, indent=2))

if session_id:
    print("\n--- Final Session Stats ---")
    final_stats = client.get_session(session_id).metadata
    print(json.dumps(final_stats, indent=2))

Full Documentation

For the comprehensive SDK documentation, including all available commands, API references, advanced configurations, and integrations, please visit:

👉 Full SDK Docs

Release files for bro-api-sdk 0.1.7

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bro-api-sdk 0.1.7
File Size Uploaded
bro_api_sdk-0.1.7.tar.gz 24.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for bro-api-sdk 0.1.7
File Interpreter ABI Platform
bro_api_sdk-0.1.7-py3-none-any.whl Python 3 none any Details

Total release size: 48.1 kB

Release files / bro_api_sdk-0.1.7.tar.gz

Download URL bro_api_sdk-0.1.7.tar.gz
Size 24.7 kB
Tags Source
SHA-256 checksum
How to use checksums
4dc020627ef4a3a374bad47c6a21609112d38f01fb9223026326d0393fe0df60
BLAKE2b-256 checksum
How to use checksums
4498766fbbcf284a96184525cd60f29a4200581279596d5107d3235d3cbe47c9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / bro_api_sdk-0.1.7-py3-none-any.whl

Download URL bro_api_sdk-0.1.7-py3-none-any.whl
Size 23.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4c4c60b7b815bec9c73dfd73530cc4aa486409236185823f24471a75bd579585
BLAKE2b-256 checksum
How to use checksums
37e64b963fc480820d54e7db646fc53889bdf8be39f4211c516adb9f5422698a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

0.1.8

2 release files

This release

0.1.7 This release

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page