> ## Documentation Index
> Fetch the complete documentation index at: https://notte-experiment-visibility-md-links.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Recordings

> Record and replay your browser sessions for debugging and analysis

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:

{/* @sniptest testers/sessions/recordings/quick_start.py */}

```python quick_start.py theme={null}
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

{/* @sniptest testers/sessions/recordings/download_mp4.py */}

```python download_mp4.py theme={null}
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:

{/* @sniptest testers/sessions/recordings/replay_by_id.py */}

```python replay_by_id.py theme={null}
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:

{/* @sniptest testers/sessions/recordings/agent_replay.py */}

```python agent_replay.py theme={null}
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")
```

{/* @sniptest testers/sessions/capabilities/agent_replay_alt.py */}

```python agent_replay_alt.py theme={null}
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:

{/* @sniptest testers/sessions/recordings/debug_failed.py */}

```python debug_failed.py theme={null}
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:

{/* @sniptest testers/sessions/capabilities/name_recordings.py */}

```python name_recordings.py theme={null}
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:

{/* @sniptest testers/sessions/capabilities/record_on_failures.py */}

```python record_on_failures.py theme={null}
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:

{/* @sniptest testers/sessions/recordings/cleanup_old.py */}

```python cleanup_old.py theme={null}
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()`

<Warning>
  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.
</Warning>

## Next Steps

<CardGroup cols={2}>
  <Card title="Live View" icon="eye" href="/features/sessions/live-view.md">
    Watch sessions in real-time
  </Card>

  <Card title="Session Lifecycle" icon="clock" href="/features/sessions/lifecycle.md">
    Understand session management
  </Card>

  <Card title="Playwright" icon="code" href="/features/sessions/playwright.md">
    Connect with Playwright via CDP
  </Card>

  <Card title="Agent Replay" icon="robot" href="/features/agents/replay.md">
    Agent-specific replay features
  </Card>
</CardGroup>
