Skip to main content

View on GitHub

View on PyPI

Installation

Install the Hyperbrowser SDK:
pip install hyperbrowser python-dotenv

Quick Start

The Hyperbrowser Python SDK supports both synchronous and asynchronous clients.

Synchronous Client

from hyperbrowser import Hyperbrowser
from dotenv import load_dotenv
import os

load_dotenv()

client = Hyperbrowser(api_key=os.getenv("HYPERBROWSER_API_KEY"))

# Create a session
session = client.sessions.create()
print(session.ws_endpoint)

Asynchronous Client

import asyncio
from hyperbrowser import AsyncHyperbrowser
from dotenv import load_dotenv
import os

load_dotenv()

client = AsyncHyperbrowser(api_key=os.getenv("HYPERBROWSER_API_KEY"))

async def main():
    session = await client.sessions.create()
    print(session.ws_endpoint)

asyncio.run(main())

Configuration Options

Both clients accept the same configuration parameters:
from hyperbrowser import Hyperbrowser

client = Hyperbrowser(
    api_key="your-api-key",  # Can also use HYPERBROWSER_API_KEY env var
    base_url="https://api.hyperbrowser.ai",  # Optional, default shown
    timeout=30,  # Request timeout in seconds
    runtime_proxy_override="regional-proxy.internal"  # Optional sandbox runtime override
)

Typing Support

The SDK is fully typed end‑to‑end with Pydantic models. Import types from hyperbrowser.models and pass method parameters as model instances.
from hyperbrowser.models import CreateSessionParams
  • Parameter models: Most methods accept a single Pydantic “params” object (parameter object/DTO). Create an instance and pass only the fields you need — None/unset fields are omitted on the wire.
  • Field names and aliases: Use Pythonic field names in code; the SDK serializes to API field names automatically via serialization_alias (e.g., use_ultra_stealthuseUltraStealth).
  • Responses: Methods return typed Pydantic models.

Example: Create a session

from hyperbrowser.models import CreateSessionParams, ScreenConfig

session = client.sessions.create(
    CreateSessionParams(
        accept_cookies=True,
        screen=ScreenConfig(width=1920, height=1080)
    )
)
print("session created", session.id)

Sandboxes

Sandbox APIs work in two layers. Sandbox control methods use your API key to create, inspect, connect to, and stop sandboxes. When you create or connect to a sandbox, the SDK also retrieves a sandbox-scoped runtime token and returns an authenticated SandboxHandle. Sandbox VM operations run inside that started sandbox and use the runtime token on the handle automatically. The SDK handles runtime token refreshes for you, so once you have a running SandboxHandle, you can call files, processes, terminal, networking, and snapshot methods without managing runtime auth yourself.

Sandbox Control

Use these methods to inspect existing sandboxes and discover reusable sandbox resources.

Details

List Sandboxes

from hyperbrowser.models import SandboxListParams

response = client.sandboxes.list(
    SandboxListParams(
        status="active",  # optional: sandbox status filter
        search="sdk",  # optional: search term
        page=1,  # optional: page number
        limit=20,  # optional: results per page
    )
)

print(response.total_count)
print([entry.id for entry in response.sandboxes])

List Images

images = client.sandboxes.list_images()
print([image.image_name for image in images.images])

List Snapshots

from hyperbrowser.models import SandboxSnapshotListParams

snapshots = client.sandboxes.list_snapshots(
    SandboxSnapshotListParams(
        image_name="node",  # optional: only snapshots for this image
        status="created",  # optional: snapshot status filter
        limit=10,  # optional: max results
    )
)

print([snapshot.snapshot_name for snapshot in snapshots.snapshots])

Get Sandbox Info

detail = sandbox.info()
print(detail.runtime.base_url)

Lifecycle

Use these methods to create, connect to, and stop sandbox instances.

Create Sandbox

Use client.sandboxes.create(...) to start a sandbox from an image.
from hyperbrowser.models import CreateSandboxParams, SandboxExposeParams

sandbox = client.sandboxes.create(
    CreateSandboxParams(
        image_name="node",  # required unless restoring from a snapshot
        region="us-west",  # optional: sandbox region
        timeout_minutes=30,  # optional: max sandbox lifetime
        enable_recording=True,  # optional: record the sandbox
        exposed_ports=[SandboxExposeParams(port=3000, auth=True)],  # optional
    )
)

Start From A Snapshot

Start a new sandbox from a memory checkpoint.
from hyperbrowser.models import CreateSandboxParams

sandbox = client.sandboxes.create(
    CreateSandboxParams(
        snapshot_name="node-after-setup",  # required: snapshot name
        snapshot_id="snapshot-id",  # optional: pin a specific snapshot version
    )
)

Connect To A Running Sandbox

Use connect(...) to re-authenticate a running sandbox, refresh its runtime token, and return a SandboxHandle for runtime operations. If you already have a handle, call sandbox.connect() to re-authenticate it in place.
sandbox = client.sandboxes.connect(
    "sandbox-id",  # running sandbox ID
)
sandbox.connect()  # re-authenticate an existing handle in place

Stop Sandbox

sandbox.stop()  # stop the sandbox when finished

Sandbox VM Operations

These methods operate on the sandbox VM itself when the sandbox is running.

Networking

Expose Port

from hyperbrowser.models import SandboxExposeParams

exposure = sandbox.expose(
    SandboxExposeParams(
        port=3000,  # required: port inside the sandbox
        auth=True,  # optional: require the sandbox bearer token
    )
)

print(exposure.url)

Unexpose Port

sandbox.unexpose(
    3000,  # exposed port to remove
)

Get Exposed URL

url = sandbox.get_exposed_url(
    3000,  # exposed port
)

print(url)

Processes

Run A Command

Use sandbox.exec(...) for one-shot commands. You can also pass a plain string like sandbox.exec("node -v").
from hyperbrowser.models import SandboxExecParams

result = sandbox.exec(
    SandboxExecParams(
        command="bash",  # required: command to run
        args=["-lc", "pwd && echo $FOO"],  # optional: command arguments
        cwd="/tmp",  # optional: working directory
        env={"FOO": "bar"},  # optional: environment variables
        timeout_ms=5000,  # optional: runtime limit in milliseconds
        use_shell=False,  # optional: run through a shell
    )
)

print(result.stdout.strip())

Start A Process

Use sandbox.processes.start(...) for long-running processes.
from hyperbrowser.models import SandboxExecParams

process = sandbox.processes.start(
    SandboxExecParams(
        command="bash",  # required: command to run
        args=["-lc", "sleep 30"],  # optional: command arguments
        cwd="/tmp",  # optional: working directory
        env={"FOO": "bar"},  # optional: environment variables
    )
)

print(process.id)

Get A Process

process = sandbox.get_process(
    "process-id",  # process ID
)

List Processes

response = sandbox.processes.list(
    status=["queued", "running"],  # optional: one status or multiple statuses
    limit=20,  # optional: max results
    cursor="next-cursor",  # optional: pagination cursor
    created_after=1711929600000,  # optional: lower timestamp bound
    created_before=1712016000000,  # optional: upper timestamp bound
)

print([entry.id for entry in response.data])

Write Process Stdin

process.write_stdin(
    data="hello\n",  # optional: stdin payload
    encoding="utf8",  # optional: "utf8" or "base64"
    eof=True,  # optional: close stdin after this write
)

Files

Read Text File

text = sandbox.files.read_text(
    "/tmp/hello.txt",  # path inside the sandbox
    offset=0,  # optional: byte offset
    length=128,  # optional: max bytes to read
)

print(text)

Write Text File

sandbox.files.write_text(
    "/tmp/hello.txt",  # path inside the sandbox
    "hello from sandbox",  # file contents
    append=True,  # optional: append instead of overwrite
    mode="0640",  # optional: chmod-style mode string
)

List Files

entries = sandbox.files.list(
    "/tmp",  # directory path
    depth=2,  # optional: traversal depth, minimum 1
)

print([entry.path for entry in entries])

Watch A Directory

def on_event(event):
    print(event.type, event.name)


watch = sandbox.files.watch_dir(
    "/tmp/watch",  # directory to watch
    on_event,  # callback for file events
    recursive=True,  # optional: watch nested directories
    timeout_ms=30000,  # optional: auto-stop after this many ms
)

watch.stop()

Create Upload URL

upload = sandbox.files.upload_url(
    "/tmp/upload.txt",  # target path inside the sandbox
    one_time=True,  # optional: invalidate the URL after one use
    expires_in_seconds=60,  # optional: URL lifetime
)

print(upload.method, upload.url)

Create Download URL

download = sandbox.files.download_url(
    "/tmp/hello.txt",  # source path inside the sandbox
    one_time=True,  # optional: invalidate the URL after one use
    expires_in_seconds=60,  # optional: URL lifetime
)

print(download.method, download.url)

Terminal

Create A Terminal

Use sandbox.terminal.create(...) or the alias sandbox.pty.create(...).
from hyperbrowser.models import SandboxTerminalCreateParams

terminal = sandbox.terminal.create(
    SandboxTerminalCreateParams(
        command="bash",  # required: command to launch
        args=["-l"],  # optional: command arguments
        cwd="/tmp",  # optional: working directory
        env={"FOO": "bar"},  # optional: environment variables
        rows=24,  # optional: terminal rows
        cols=80,  # optional: terminal columns
        timeout_ms=60000,  # optional: PTY timeout in milliseconds
    )
)

print(terminal.id)

Get A Terminal

terminal = sandbox.terminal.get(
    "terminal-id",  # terminal ID
    include_output=True,  # optional: include buffered output
)

print(len(terminal.current.output or []))

Snapshots

Create A Memory Snapshot

from hyperbrowser.models import SandboxMemorySnapshotParams

snapshot = sandbox.create_memory_snapshot(
    SandboxMemorySnapshotParams(
        snapshot_name="node-after-setup",  # optional: custom snapshot name
    )
)

print(snapshot.snapshot_id)
Sandbox guides:

Integration Examples

from playwright.sync_api import sync_playwright
from hyperbrowser import Hyperbrowser
from hyperbrowser.models import CreateSessionParams
from dotenv import load_dotenv
import os

load_dotenv()

client = Hyperbrowser(api_key=os.getenv("HYPERBROWSER_API_KEY"))


def main():
    # Create session
    session = client.sessions.create(params=CreateSessionParams(accept_cookies=True))

    try:
        # Connect with Playwright
        with sync_playwright() as p:
            browser = p.chromium.connect_over_cdp(session.ws_endpoint)
            default_context = browser.contexts[0]
            page = default_context.pages[0]

            page.goto("https://example.com")
            print(f"Page title: {page.title()}")

    except Exception as e:
        print(f"Error: {e}")
    finally:
        # Stop session
        client.sessions.stop(session.id)


if __name__ == "__main__":
    main()

Computer Actions

Programmatically control the browser with low-level actions. For the session-id parameter, you can also just pass in the detailed session object itself, and it is actually recommended to do so.

Click

response = client.computer_action.click(
    "session-id",  # or session object
    x=500,
    y=300,
    button="left",  # "left" | "right" | "middle" | "back" | "forward" | "wheel"
    click_count=1,
    return_screenshot=False  # do not return screenshot (default: False)
)

print(response.success)
print(response.screenshot) # base64 if requested

Type Text

response = client.computer_action.type_text(
    "session-id",
    text="Hello, World!",
    return_screenshot=False  # do not return screenshot (default: False)
)

Press Keys

Uses the xdotool format for keys: https://github.com/sickcodes/xdotool-gui/blob/master/key_list.csv
response = client.computer_action.press_keys(
    "session-id",
    keys=["Control_L", "a"],  # Key combination
    return_screenshot=False  # do not return screenshot (default: False)
)

Move Mouse

response = client.computer_action.move_mouse(
    "session-id",
    x=500,
    y=300,
    return_screenshot=False  # do not return screenshot (default: False)
)

Drag

response = client.computer_action.drag(
    "session-id",
    coordinates=[
        {"x": 100, "y": 100},
        {"x": 200, "y": 200},
        {"x": 300, "y": 300}
    ],
    return_screenshot=False  # do not return screenshot (default: False)
)

Scroll

response = client.computer_action.scroll(
    "session-id",
    x=500,
    y=300,
    scroll_x=0,
    scroll_y=100,
    return_screenshot=False  # do not return screenshot (default: False)
)

Screenshot

response = client.computer_action.screenshot("session-id")
print(response.screenshot)  # base64

Support