Skip to main content
STOP. Do not read past this section until you have read and followed /quickstart.md.Goal: produce a reliable SDK automation script. The intended authoring flow is generate then edit, not write browser automation from scratch.Do not hand-write SDK code with element IDs, selectors, or form fields from memory. Element IDs, selectors, and field mappings must come from a live observe() call, CLI notte page observe output, or generated workflow code. Guessed browser targets fail on real pages.Use the Notte skill and CLI to inspect the live site, validate actions/selectors, handle auth/session state, and export workflow code with notte sessions workflow-code before using SDK docs or SDK code.SDK reference pages are for understanding, running, or editing generated workflow code. They are not the starting point for manually authoring the initial browser automation. SDK-first code is guesswork on real-world pages with dynamic selectors, auth state, CAPTCHAs, and anti-bot behavior.
Notte automatically records every action in your browser sessions, allowing you to download video replays for debugging and analysis. Calling session.replay() returns a ReplayResponse containing a presigned URL for the MP4 file, which you can download with replay.download().

Quick Start

Get a recording after your session ends:
quick_start.py
from notte_sdk import NotteClient

client = NotteClient()

with client.Session() as session:
    session.execute(type="goto", url="https://example.com")
    session.execute(type="click", selector="button.submit")
    session.execute(type="fill", selector="input[name='email']", value="user@example.com")
    # All actions automatically recorded

# Get replay after session ends
replay = session.replay()
replay.download("session_recording.mp4")

What Gets Recorded

Session recordings capture:
  • Page navigation - All page loads and URL changes
  • User interactions - Clicks, fills, scrolls, key presses
  • DOM changes - Dynamic content updates
  • Visual state - What the browser displays
  • Timing - Real-time playback speed

Session Replays

Download as MP4

download_mp4.py
from notte_sdk import NotteClient

client = NotteClient()

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

# Download recording
replay = session.replay()

# Save to file
replay.download("my_automation.mp4")

# Or access the presigned URL directly
print(f"MP4 URL: {replay.mp4_url}")
print(f"Expires at: {replay.expires_at}")

Replay by Session ID

Get a replay for any session using its ID:
replay_by_id.py
from notte_sdk import NotteClient

client = NotteClient()

# Get replay for a specific session
replay = client.sessions.replay(session_id="your-session-id")
replay.download("session_replay.mp4")

Agent Replays

After running an agent, get the replay from the session:
agent_replay.py
from notte_sdk import NotteClient

client = NotteClient()

with client.Session() as session:
    agent = client.Agent(session=session, max_steps=10)
    result = agent.run(task="Find the contact email on example.com")

# Get replay from the session
replay = session.replay()
replay.download("agent_run.mp4")
agent_replay_alt.py
from notte_sdk import NotteClient

client = NotteClient()

with client.Session() as session:
    pass  # session actions here

# Get replay after session ends
replay = session.replay()
replay.download("agent_run.mp4")

Debugging Failed Runs

Use recordings to understand what went wrong:
debug_failed.py
from notte_sdk import NotteClient

client = NotteClient()

session_id = None

try:
    with client.Session() as session:
        session_id = session.session_id
        session.execute(type="goto", url="https://example.com")
        session.execute(type="click", selector="button.sometimes-missing")

except Exception as e:
    print(f"Automation failed: {e}")

    if session_id:
        # Get recording to see what happened
        replay = client.sessions.replay(session_id=session_id)
        replay.download(f"failed_{session_id}.mp4")
        print("Replay saved for analysis")

Best Practices

1. Name Recordings Meaningfully

Use descriptive filenames:
name_recordings.py
from datetime import datetime

from notte_sdk import NotteClient

client = NotteClient()

with client.Session() as session:
    session.execute(type="goto", url="https://example.com")
    replay = session.replay()
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    replay.download(f"login_test_{session.session_id}_{timestamp}.mp4")

2. Record Only on Failures

For production, save recordings only when something goes wrong:
record_on_failures.py
from notte_sdk import NotteClient

client = NotteClient()

try:
    with client.Session() as session:
        session.execute(type="goto", url="https://example.com")
        # ... automation ...
except Exception:
    if "session" in locals():
        try:
            replay = session.replay()
            replay.download(f"error_{session.session_id}.mp4")
        except Exception:
            pass
    raise

3. Clean Up Old Recordings

Remove old recordings to save disk space:
cleanup_old.py
import time
from pathlib import Path


def cleanup_old_recordings(directory: str, days: int = 7):
    """Remove recordings older than specified days."""
    cutoff = time.time() - (days * 86400)

    for recording in Path(directory).glob("*.mp4"):
        if recording.stat().st_mtime < cutoff:
            recording.unlink()
            print(f"Deleted: {recording}")


cleanup_old_recordings("recordings/", days=7)

Recording Limitations

What’s Recorded

  • All page interactions
  • Visual state changes
  • Navigation and reloads
  • Dynamic content

What’s NOT Recorded

  • Audio
  • Network request details (use CDP for this)
  • Console logs (use logging)
  • Session state before first action

Storage

Recordings are:
  • Stored on Notte’s servers after the session ends
  • Accessed via presigned URLs (returned by session.replay())
  • Retained for 24 hours
  • Downloadable as MP4 via replay.download()
Recordings are deleted after 24 hours. Download them promptly if needed for later analysis. Presigned URLs also expire — check replay.expires_at for the expiration time.

Next Steps

Live View

Watch sessions in real-time

Session Lifecycle

Understand session management

Playwright

Connect with Playwright via CDP

Agent Replay

Agent-specific replay features