stagehand 4.1.0


pip install stagehand

  Latest version

Released: Sep 09, 2026


Meta
Author: Browserbase
Requires Python: >=3.11

Classifiers

Stagehand is the SDK for browser agents.
Read the Docs

MIT License Discord Community

browserbase%2Fstagehand | Trendshift

Ask DeepWiki

Stagehand Python SDK

What is Stagehand?

Stagehand is the SDK for browser agents. Playwright was built for testing, Stagehand is built for agents. Use familiar APIs, self-healing actions, and network-level security across TypeScript, Python, and Go.

Why Stagehand?

Stagehand gives browser agents an interface built for how they actually work. It combines familiar Playwright-style APIs with self-healing actions, agent-optimized page context, and native support for complex DOM structures like out-of-process iframes and closed Shadow DOMs.

Agents use fewer tokens, recover when websites change, and complete tasks more reliably. With a complete browser driver across TypeScript, Python, and Go, Stagehand delivers the flexibility of AI without sacrificing the speed, control, determinism, reliability, and observability required in production.

For the full overview, examples, and contributing guide, see the main README.

Example

The async Python SDK for Stagehand browser automation:

import asyncio
import os

from pydantic import BaseModel

from stagehand import Stagehand, browserbase, local_browser


class PullRequest(BaseModel):
    author: str
    title: str


async def main() -> None:
    browser = await local_browser.launch(headless=True)
    try:
        stagehand = await Stagehand.create(
            browser=browser,
            model="openai/gpt-5.4-mini",
            model_api_key=os.environ["OPENAI_API_KEY"],
        )
        try:
            page = (await browser.context.pages())[0]
            await page.goto("https://github.com/browserbase")

            # act() executes individual actions
            await stagehand.act("click on the stagehand repo")

            # observe() reports what is actionable on the page
            observed = await stagehand.observe("find the latest PR")

            # Locators give deterministic, Playwright-style actions
            await page.locator(observed.data[0].selector).click()

            # extract() returns structured data validated by a pydantic model
            result = await stagehand.extract(
                "extract the author and title of the PR",
                PullRequest,
            )
            print(result.data.author, result.data.title)
        finally:
            await stagehand.close()
    finally:
        await browser.close()


asyncio.run(main())

See examples for action, extraction, observation, and custom LLM usage.

For hosted browsers, import browserbase from stagehand and use browserbase.launch(api_key=...) or browserbase.connect(api_key=..., session_id=...) instead of local_browser. A launched session is released when you close() the browser handle, except with keep_alive=True: that handle's close() only disconnects, and the session keeps running until it is released out of band (Browserbase dashboard or API) or reaches its configured timeout. The Stagehand extension that launch() uploaded for that session is retained on the account for the same reason, so a keep_alive=True workflow that launches repeatedly accumulates extensions until they are deleted out of band. Sessions reached through browserbase.connect() are never released by close() — whoever created the session owns it.

The same browserbase facade exposes Browserbase Search and Fetch without launching a browser:

import asyncio
import os

from stagehand import browserbase


async def search_and_fetch() -> None:
    results = await browserbase.search(
        api_key=os.environ["BROWSERBASE_API_KEY"],
        query="browser agent frameworks",
        num_results=5,
    )
    fetched = await browserbase.fetch(
        api_key=os.environ["BROWSERBASE_API_KEY"],
        url=results.results[0].url,
        format="markdown",
    )
    print(fetched.content)


asyncio.run(search_and_fetch())

Stagehand.act(), Stagehand.observe(), and Stagehand.extract() use the active page by default. Pass page=page to target a specific SDK Page.

Page.goto(), reload(), go_back(), and go_forward() return the main-document Response, or None when navigation does not produce one. Response bodies and complete headers are retrieved lazily while the Stagehand session remains open.

When contributing examples or tests, keep browser ownership explicit: launch or connect a browser handle, pass it to Stagehand.create(), close Stagehand first, and close the browser in the outermost finally block.

Contributing

# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh

# Install just
brew install just

just install
just generate
just check
just test
just build
4.2.0a0.dev1545 Sep 28, 2026
4.2.0a0.dev1544 Sep 28, 2026
4.2.0a0.dev1543 Sep 27, 2026
4.2.0a0.dev1541 Sep 26, 2026
4.2.0a0.dev1540 Sep 26, 2026
4.2.0a0.dev1539 Sep 25, 2026
4.2.0a0.dev1538 Sep 25, 2026
4.2.0a0.dev1537 Sep 24, 2026
4.2.0a0.dev1536 Sep 23, 2026
4.2.0a0.dev1535 Sep 23, 2026
4.2.0a0.dev1534 Sep 23, 2026
4.2.0a0.dev1533 Sep 23, 2026
4.2.0a0.dev1532 Sep 22, 2026
4.2.0a0.dev1531 Sep 22, 2026
4.2.0a0.dev1530 Sep 22, 2026
4.2.0a0.dev1529 Sep 22, 2026
4.2.0a0.dev1528 Sep 22, 2026
4.2.0a0.dev1527 Sep 21, 2026
4.2.0a0.dev1526 Sep 19, 2026
4.2.0a0.dev1525 Sep 19, 2026
4.2.0a0.dev1524 Sep 18, 2026
4.1.0 Sep 09, 2026
4.1.0a0.dev1500 Sep 09, 2026
4.1.0a0.dev1499 Sep 09, 2026
4.1.0a0.dev1498 Sep 09, 2026
4.1.0a0.dev1497 Sep 09, 2026
4.1.0a0.dev1496 Sep 03, 2026
4.1.0a0.dev1495 Sep 03, 2026
4.1.0a0.dev1494 Sep 02, 2026
4.0.3 Sep 09, 2026
4.0.3a0.dev1493 Sep 02, 2026
4.0.3a0.dev1492 Sep 02, 2026
4.0.3a0.dev1491 Sep 02, 2026
4.0.3a0.dev1484 Sep 01, 2026
4.0.3a0.dev1483 Aug 30, 2026
4.0.3a0.dev1478 Aug 28, 2026
4.0.3a0.dev1477 Aug 27, 2026
4.0.3a0.dev1476 Aug 27, 2026
4.0.3a0.dev1475 Aug 26, 2026
4.0.3a0.dev1474 Aug 25, 2026
4.0.2 Aug 20, 2026
4.0.1 Aug 14, 2026
4.0.0 Aug 10, 2026
3.23.0 Aug 20, 2026
3.22.0 Jul 22, 2026
3.21.0 May 29, 2026
3.20.0 May 07, 2026
3.19.5 Apr 03, 2026
3.19.4 Apr 03, 2026
3.19.3 Apr 03, 2026
3.19.2 Apr 03, 2026
3.19.1 Mar 31, 2026
3.19.0 Mar 27, 2026
3.18.0 Mar 25, 2026
3.7.0 Mar 24, 2026
3.6.0 Feb 25, 2026
3.5.0 Jan 29, 2026
3.4.8 Jan 27, 2026
3.4.7 Jan 15, 2026
3.4.6 Jan 13, 2026
3.4.2 Jan 13, 2026
3.4.1 Jan 13, 2026
3.4.0 Jan 13, 2026
0.5.14 Mar 17, 2026
0.5.13 Feb 28, 2026
0.5.12 Feb 24, 2026
0.5.11 Feb 23, 2026
0.5.10 Feb 16, 2026
0.5.9 Dec 23, 2025
0.5.8 Dec 19, 2025
0.5.7 Dec 03, 2025
0.5.6 Nov 14, 2025
0.5.5 Oct 24, 2025
0.5.4 Oct 08, 2025
0.5.3 Sep 16, 2025
0.5.2 Aug 28, 2025
0.5.1 Aug 19, 2025
0.5.0 Jul 28, 2025
0.4.1 Jul 18, 2025
0.4.0 Jun 30, 2025
0.0.7 Jun 24, 2025
0.0.6 Jun 19, 2025
0.0.5 Jun 16, 2025
0.0.4 Jun 16, 2025
0.0.3 Jun 16, 2025
0.0.2 Jun 16, 2025

Wheel compatibility matrix

Platform Python 3
any

Files in release

Extras: None
Dependencies:
browserbase (<2,>=1.15)
opentelemetry-api (<2,>=1.35)
pydantic (<3,>=2.12)
websockets (>=16.1.1)