Use this file to discover all available pages before exploring further.
This guide helps you migrate from the legacy Stagehand Python SDK to the new Stainless-based SDK with a Bring Your Own Browser (BYOB) architecture.
The new Python SDK is a pure API client. You manage the browser yourself using Playwright, Selenium, Puppeteer, or any other browser automation tool. The SDK handles only the AI-powered operations.
import osfrom playwright.sync_api import sync_playwrightfrom stagehand import Stagehand# Note: Custom logging configuration is not yet supported.# Use standard Python logging if needed:import logginglogging.basicConfig(level=logging.INFO)
# Recommended for simple navigationpage.goto("https://google.com/")
# Use this if you need Stagehand to track navigation stateclient.sessions.navigate( id=session_id, url="https://google.com/", frame_id="", # Empty string for main frame x_language="python", x_sdk_version=SDK_VERSION,)
Any direct page manipulation should use Playwright’s native API.
Old SDK (v2)
New SDK (v3)
# Click using Playwright locator (this was already Playwright)await page.get_by_role("link", name="About", exact=True).click()# Keyboard inputawait page.keyboard.press("Enter")
# Same Playwright API, but synchronous (or use async Playwright if preferred)page.get_by_role("link", name="About", exact=True).click()# Keyboard inputpage.keyboard.press("Enter")
In the old SDK, page was a Stagehand-enhanced Playwright page. In the new SDK, page is a standard Playwright page. Direct Playwright methods work the same way.
data = await page.extract("extract the first result from the search")print(data.model_dump_json())
extract_response = client.sessions.extract( id=session_id, instruction="extract the first result from the search", schema={ "type": "object", "properties": { "title": { "type": "string", "description": "The title of the first search result" }, "url": { "type": "string", "description": "The URL of the first search result" } }, "required": ["title"] }, x_language="python", x_sdk_version=SDK_VERSION,)extracted_data = extract_response.data.resultprint(f"Extracted: {extracted_data}")
Key difference: The new SDK requires an explicit JSON schema for extraction. This provides better type safety and clearer expectations for the AI model.
# Clean up Playwright resourcesbrowser.close()playwright.stop()# End the Stagehand sessionclient.sessions.end( id=session_id, x_language="python", x_sdk_version=SDK_VERSION,)
Important: Always clean up both Playwright and the Stagehand session. Use a try/finally block to ensure cleanup happens even on errors.
Metrics are now returned per-operation via response.data.result.usage instead of a cumulative stagehand.metrics object. New fields include cached_input_tokens and reasoning_tokens.
Ensure you’re using the correct session_id returned from client.sessions.start().
Playwright connection issues
Make sure your Browserbase API key has the correct permissions and the session is still active.
Missing x_language and x_sdk_version parameters
These are required for all session operations. Use x_language="python" and x_sdk_version="3.0.6" (or the latest version).
Extraction returns unexpected format
The new SDK requires an explicit JSON schema. Make sure your schema matches the expected output structure.
LLM metrics endpoint returns 404
In v3, LLM metrics are no longer available via a separate replay endpoint. Instead, access metrics directly from the usage field on operation responses (e.g., response.data.result.usage).