Skip to main content

Overview

Stagehand is an AI-powered browser automation framework with methods like observe(), extract(), and act(). This guide walks you through deploying and running a Stagehand project on Intuned. You’ll build a sample scraper that extracts book data—without writing Playwright selectors or custom parsing logic. The same patterns apply to any automation you build with the framework.
This guide assumes you have a basic understanding of Intuned projects. If you’re new to Intuned, start with the getting started guide.

When to use AI automation

Intuned supports AI-powered browser automation frameworks like Stagehand, Browser Use, and others. Use AI automation when:
  • Pages are dynamic — Elements change position, structure, or content unpredictably
  • You don’t know the exact page structure — Scraping sites you haven’t mapped in detail
  • You want natural language control — Describe what to do instead of writing precise selectors
  • Traditional Playwright code is too brittle for your case — AI agents adapt to minor UI changes automatically
Stagehand is one option for AI automation on Intuned. The setup patterns in this guide apply to other AI frameworks as well. For a deeper dive into choosing between deterministic, AI-driven, and hybrid approaches, check out Flexible Automations.

Guide

Let’s build a getBooks API with AI. The template handles all the Stagehand setup for you. You can develop with Stagehand in two ways:
  • Online IDE — Zero setup. Write, test, and deploy directly from your browser.
  • CLI — Use your favorite IDE with full version control.
1

Create a project

  1. Go to Intuned dashboard
  2. Select + New Project > Templates > Stagehand
  3. Select your language (Python or TypeScript)
  4. Name it and select Create Project
Create Stagehand project from template
2

Explore the project

The template includes a book scraper API that combines Playwright with AI agents.Project structure:
my-stagehand-project/
├── api/
│   └── get-books.ts             # Main automation API
├── hooks/
│   └── setupContext.ts          # CDP URL setup
├── package.json                 # Dependencies
└── intuned.json                 # Project configuration
The automation code:
Python
from typing import TypedDict
from playwright.async_api import Page
from stagehand import Stagehand
from intuned_runtime import attempt_store, get_ai_gateway_config
from pydantic import BaseModel


class Params(TypedDict):
    category: str | None


class BookDetails(BaseModel):
    title: str
    price: str
    rating: str | None = None
    availability: str | None = None


class BooksResponse(BaseModel):
    books: list[BookDetails]


MAX_PAGES = 10


async def automation(page: Page, params: Params, **_kwargs):
    base_url, api_key = get_ai_gateway_config()
    cdp_url = attempt_store.get("cdp_url")

    # Initialize Stagehand with observe/act/extract capabilities
    stagehand = Stagehand(
        env="LOCAL",
        local_browser_launch_options=dict(
            cdp_url=cdp_url, viewport=dict(width=1280, height=800)
        ),
        model_api_key=api_key,
        model_client_options={
            "baseURL": base_url,
        },
    )
    await stagehand.init()

    await page.set_viewport_size({"width": 1280, "height": 800})

    category = params.get("category")
    all_books: list[BookDetails] = []

    try:
        await stagehand.page.goto("https://books.toscrape.com")

        # Navigate to category if specified using observe and act
        if category:
            await stagehand.page.observe(f'the "{category}" category link in the sidebar')
            await stagehand.page.act(f'Click on the "{category}" category link in the sidebar')

        # Collect books from all pages
        for page_num in range(1, MAX_PAGES + 1):
            # Extract all book details from the current page
            result = await stagehand.page.extract(
                "Extract all books visible on the page with their complete details",
                schema=BooksResponse,
            )
            all_books.extend(result.books)

            # Check if there's a next page and navigate to it
            if page_num < MAX_PAGES:
                try:
                    next_button = await stagehand.page.observe(
                        'the "next" button or link to go to the next page'
                    )
                    if not next_button:
                        break
                    await stagehand.page.act('Click the "next" button to go to the next page')
                except Exception:
                    break

    finally:
        await stagehand.close()

    return BooksResponse(books=all_books)
What this does: Navigates to https://books.toscrape.com, uses Stagehand’s observe() and act() methods to navigate to a specific category, then uses extract() to collect book details across multiple pages with type-safe schemas (Pydantic for Python, Zod for TypeScript).
3

Run your automation

Run the book scraper to test your setup.
  1. In the Online IDE, select the API from the dropdown
  2. Select Select Parameter and enter {"category": "Travel"}
  3. Select Start Run
Running Stagehand automation in IDE
4

Deploy and test

Deploy your automation to Intuned’s infrastructure.
  1. In the Online IDE, select Deploy in the top-right corner
  2. After deployment completes, go to the project’s Runs page
  3. Select Start Run, then choose your API
  4. Enter parameters: {"category": "Travel"} and select Start Run
Running Stagehand automation in Dashboard
  1. After the run completes, view the extracted results
View Stagehand run results

How it works

  • The setupContext hook stores the CDP URL in attemptStore for your API to access
Check out our setup hook recipe.
  • Your API initializes Stagehand with the CDP URL and AI gateway credentials from getAiGatewayConfig()
  • Stagehand provides three core AI-powered methods:
    • observe() - Find elements on the page using natural language
    • act() - Perform actions like clicking using natural language
    • extract() - Extract structured data from the page with type-safe schemas
  • Uses the AI SDK pattern with AISdkClient and createOpenAI
  • Call methods directly on stagehand (e.g., stagehand.act(), stagehand.extract())
  • Use the Playwright page for navigation (e.g., page.goto())
  • Your API accepts parameters (like category) that can vary for each run
  • The automation handles pagination automatically and cleans up Stagehand when done