Skip to main content
When working with Notte sessions, you have two ways to interact with the browser: using Playwright directly via CDP, or using Notte’s AI-enabled SDK methods. Both approaches work with the same session, and you can even mix them in your automation.

Direct Playwright Control

When you access session.page, you get a Playwright-compatible page object that connects directly to the browser via Chrome DevTools Protocol:
page = session.page
page.goto("https://example.com")
page.fill("input[name='email']", "user@example.com")
page.click("button[type='submit']")
This gives you the full Playwright API - everything you can do with Playwright works here. You control the browser directly through WebSocket connections with low latency.

Notte SDK Methods

Notte provides high-level methods designed for AI agents and structured automation:
session.execute(type="goto", url="https://example.com")
obs = session.observe(instructions="Fill the email input")
action = obs.space.first()  # AI finds the right element
session.execute(action.with_value("user@example.com"))
data = session.scrape(instructions="Extract all product names")
These methods use Notte’s backend to execute actions, with built-in AI capabilities, observability, and error handling.

Key Differences

FeaturePlaywright (session.page)Notte SDK (execute/observe/scrape)
API SurfaceFull Playwright APIStreamlined action-based API
DependenciesRequires playwright packageJust notte-sdk
Element SelectionManual CSS/XPath selectorsAI-powered natural language + selectors
Page UnderstandingManual interpretationAI describes page with observe()
Data ExtractionManual parsingStructured LLM-powered scrape()
ObservabilityManual loggingSession replay, action recording, live viewer
Error HandlingManual try/exceptAutomatic retries and validation
Network Control✅ Intercept, modify requests❌ Not available
LatencyLower (WebSocket)Higher (HTTP API)
Action CoverageEverythingEverything via extensive action library

Why Use Playwright?

Choose session.page when you need:
  • Network control - Intercept, block, or modify requests and responses
  • Event monitoring - Listen to console logs, network events, page errors
  • Lowest latency - Direct WebSocket communication for high-speed operations
  • Standard patterns - Use familiar Playwright code and examples
  • Fine-grained control - Access to every Playwright feature
from notte_sdk import NotteClient
from playwright.sync_api import sync_playwright

client = NotteClient()

with client.Session() as session:
    page = session.page

    # Block images for faster loading
    page.route("**/*.{png,jpg,jpeg}", lambda route: route.abort())

    # Listen to network requests
    page.on("request", lambda req: print(f"→ {req.url}"))
    page.on("response", lambda res: print(f"← {res.url} ({res.status})"))

    page.goto("https://example.com")

Why Use Notte SDK?

Choose session.execute(), observe(), and scrape() when you need:
  • AI-powered automation - Let AI find elements and understand pages
  • Structured data extraction - Extract data into Pydantic models automatically
  • Built-in observability - Session replays, trajectory tracking, live viewer
  • Simpler API - Smaller learning curve, no Playwright knowledge required
  • Production reliability - Automatic retries, error handling, validation
  • Agent workflows - Designed for AI agents with semantic action spaces
from notte_sdk import NotteClient
from pydantic import BaseModel

client = NotteClient()

class Product(BaseModel):
    name: str
    price: float

with client.Session() as session:
    session.execute(type="goto", url="https://example.com/products")

    # AI understands the page
    obs = session.observe(instructions="Find the search box")
    action = obs.space.first()  # AI picks the right element
    session.execute(action.with_value("laptops"))

    # Structured extraction with LLM
    products = session.scrape(
        response_format=list[Product],
        instructions="Extract all products with names and prices"
    )

    # Every action is recorded
    replay = session.replay()
    replay.save("automation.mp4")

Mix Both Approaches

You can combine both methods in the same session:
from notte_sdk import NotteClient

client = NotteClient()

with client.Session() as session:
    # Use Notte for high-level navigation
    session.execute(type="goto", url="https://example.com")

    # Switch to Playwright for network control
    page = session.page
    page.route("**/api/*", lambda route: route.continue_(headers={
        **route.request.headers,
        "Authorization": f"Bearer {token}"
    }))

    # Back to Notte for AI-powered scraping
    data = session.scrape(instructions="Extract all article titles")

When to Choose What

Use Playwright if:

  • You need network interception or request modification
  • You’re integrating existing Playwright scripts
  • Performance is critical (milliseconds matter)
  • You need to listen to browser events

Use Notte SDK if:

  • Building AI agents that understand web pages
  • You want structured data extraction
  • You need session replay and debugging features
  • You prefer simpler, action-based API
  • Building production systems with error handling

Use Both if:

  • You need network control AND AI features
  • Complex workflows with different requirements
  • You want the flexibility of both approaches

Next Steps