Skip to main content
Stagehand is an open source AI browser automation framework that lets you choose what to write in code vs. natural language. By integrating with Notte, you can run Stagehand automations on cloud-hosted browsers with built-in anti-detection, captcha solving, and residential proxies.
This guide is compatible with Stagehand v3. If you’re using an earlier version, refer to the Stagehand migration guide.

Prerequisites

  • A Notte API key (get one here)
  • An LLM API key (e.g., OpenAI)
  • Stagehand v3

Adding Notte to existing Stagehand implementations

If you already have a Stagehand v3 implementation, you can switch to using Notte’s cloud browsers by updating your browser configuration.

1. Install the SDKs

pip install notte-sdk stagehand

2. Connect Stagehand to a Notte browser

Create a Notte cloud browser session and pass its CDP URL to Stagehand:
stagehand_basic.py
import asyncio
import os

from notte_sdk import NotteClient
from stagehand import Stagehand


async def main():
    client = NotteClient()

    with client.Session() as session:
        # Connect Stagehand to Notte's cloud browser via CDP
        stagehand = Stagehand(
            env="LOCAL",
            local_browser_launch_options={
                "cdp_url": session.cdp_url(),
            },
            model_name="openai/gpt-4.1",
            model_api_key=os.environ.get("MODEL_API_KEY"),
        )
        await stagehand.init()

        page = stagehand.page
        await page.goto("https://example.com")
        await stagehand.act("Click on the 'More information...' link")

        await stagehand.close()


asyncio.run(main())
That’s it — Stagehand is now running on a Notte cloud browser with built-in stealth and anti-detection.

Complete example

A production-ready script using Stagehand’s observe, act, and extract on a Notte browser:
stagehand_complete.py
import asyncio
import os

from dotenv import load_dotenv
from notte_sdk import NotteClient
from stagehand import Stagehand

load_dotenv()


async def main():
    client = NotteClient()

    with client.Session() as session:
        stagehand = Stagehand(
            env="LOCAL",
            local_browser_launch_options={
                "cdp_url": session.cdp_url(),
            },
            model_name="openai/gpt-4.1",
            model_api_key=os.environ.get("MODEL_API_KEY"),
            verbose=1,
        )
        await stagehand.init()

        try:
            # Navigate to a webpage
            page = stagehand.page
            await page.goto("https://news.ycombinator.com")

            # Observe: find possible actions on the page
            observations = await stagehand.observe("find the top story link")
            print(f"Found {len(observations)} possible actions")

            # Act: click on the first result
            if observations:
                await stagehand.act(observations[0])

            # Extract: get structured data from the page
            result = await stagehand.extract(
                "extract the title and URL of this story",
                {
                    "type": "object",
                    "properties": {
                        "title": {"type": "string"},
                        "url": {"type": "string"},
                    },
                },
            )
            print(f"Extracted: {result}")

        finally:
            await stagehand.close()

    print("Done")


if __name__ == "__main__":
    asyncio.run(main())
Set the following environment variables in your .env file:
NOTTE_API_KEY=your-notte-api-key
MODEL_API_KEY=your-openai-api-key

Benefits of using Notte with Stagehand

  • Anti-detection: Notte’s stealth mode keeps your automations undetected
  • Captcha solving: Built-in captcha solving handles CAPTCHAs automatically
  • Residential proxies: Route traffic through residential proxies in 195+ countries
  • Live view: Debug automations in real-time with live view
  • Session replay: Record and review runs with session recordings
  • No local browser: Run automations without installing or maintaining browsers locally

Next steps