Skip to main content
Every Notte session follows a predictable lifecycle from creation to termination. Understanding this lifecycle helps you build reliable automation workflows and manage resources effectively.

Session States

Sessions transition through these states:
  • active - Session is running and ready to accept operations
  • closed - Session has been terminated normally
  • error - Session encountered an error and terminated unexpectedly
  • timed_out - Session exceeded its timeout duration

Creating a Session

Create a new session using the context manager pattern (recommended):
from notte_sdk import NotteClient

client = NotteClient()

# Recommended: Use context manager for automatic cleanup
with client.Session(
    headless=True,
    timeout_minutes=10,
    viewport_width=1920,
    viewport_height=1080
) as session:
    print(f"Session {session.session_id} is active")

    # Access Playwright page
    page = session.page
    page.goto("https://example.com")
    print(f"Page title: {page.title()}")

# Session automatically stopped here
Always use the context manager (with statement) to ensure sessions are properly stopped, even if errors occur.

Getting Session Details

Retrieve current information about your session:
from notte_sdk import NotteClient

client = NotteClient()

with client.Session() as session:
    # Get full session status
    status = session.status()

    print(f"Session ID: {status.session_id}")
    print(f"Status: {status.status}")
    print(f"Created at: {status.created_at}")
    print(f"Last accessed: {status.last_accessed_at}")
    print(f"Timeout: {status.timeout_minutes} minutes")
    print(f"Duration: {status.duration}")

    # Get CDP URL for external connections
    cdp_url = session.cdp_url()
    print(f"CDP WebSocket: {cdp_url}")
session_id
string
Unique identifier for the session
status
string
Current status: active, closed, error, or timed_out
created_at
datetime
Session creation timestamp
closed_at
datetime | None
Session closure timestamp (None if still active)
last_accessed_at
datetime
Last operation timestamp
timeout_minutes
integer
Session timeout in minutes
duration
timedelta
Total session duration

Listing Sessions

Query all your active sessions:
from notte_sdk import NotteClient

client = NotteClient()

# List all sessions
sessions = client.sessions.list()
print(f"Total sessions: {len(sessions)}")

for session in sessions:
    print(f"- {session.session_id} ({session.status})")
    print(f"  Created: {session.created_at}")
    print(f"  Duration: {session.duration}")

# Filter by status
active_sessions = client.sessions.list(status="active")
print(f"Active sessions: {len(active_sessions)}")

Stopping a Session

Sessions are automatically stopped when using the context manager, but you can also stop them manually:
from notte_sdk import NotteClient

client = NotteClient()

# Manual stop
session = client.Session()
session.start()

# ... do work ...

session.stop()
print("Session stopped successfully")
Stopping a session is idempotent - you can safely call it multiple times without errors.

Complete Lifecycle Example

Here’s a complete example demonstrating best practices for session management:
from notte_sdk import NotteClient
import time

client = NotteClient()

def run_automation():
    # 1. Create session with configuration
    print("Creating session...")

    with client.Session(
        headless=False,  # Opens live viewer
        timeout_minutes=10,
        cookie_file="cookies.json"  # Auto-load/save cookies
    ) as session:
        print(f"Session created: {session.session_id}")
        print("Live viewer opened in browser")

        # 2. Access Playwright page
        page = session.page

        # 3. Use the session
        print("Navigating to example.com...")
        page.goto("https://example.com")

        title = page.title()
        print(f"Page title: {title}")

        # Take a screenshot
        page.screenshot(path="screenshot.png")
        print("Screenshot saved")

        # Wait before closing
        time.sleep(3)

        # Cookies automatically saved to cookies.json
        print("Session will be stopped and cookies saved...")

    # Session automatically stopped here
    print("Session stopped successfully")

if __name__ == "__main__":
    run_automation()

Connecting to Existing Sessions

You can reconnect to an existing session using its session_id:
from notte_sdk import NotteClient

client = NotteClient()

# Connect to existing session
session_id = "550e8400-e29b-41d4-a716-446655440000"

with client.Session(session_id) as session:
    print(f"Connected to session: {session.session_id}")

    # Get current status
    status = session.status()
    print(f"Session status: {status.status}")

    # Continue using the session
    page = session.page
    page.goto("https://example.com")

Error Handling

The context manager automatically handles cleanup, even when errors occur:
from notte_sdk import NotteClient

client = NotteClient()

try:
    with client.Session() as session:
        page = session.page
        page.goto("https://example.com")

        # Simulate an error
        raise ValueError("Something went wrong!")

except ValueError as e:
    print(f"Automation failed: {e}")
    # Session is still automatically stopped

print("Session was cleaned up despite the error")

Best Practices

Follow these patterns to build reliable, cost-effective automation:

1. Always Use Context Managers

The with statement guarantees cleanup:
with client.Session() as session:
    # ... use session
# Automatically stopped here

2. Set Appropriate Timeouts

Match timeout to task duration with a buffer for delays:
  • Quick tasks: 3-5 minutes (default is 3)
  • Data scraping: 10-15 minutes
  • Long workflows: 20-30 minutes
with client.Session(timeout_minutes=15) as session:
    # Complex automation
    pass

3. Monitor Session State

Check session status before long-running operations:
with client.Session() as session:
    status = session.status()
    if status.status != 'active':
        raise Exception('Session is no longer active')

    # Continue with operations

4. Handle Cleanup Gracefully

Even with context managers, handle interrupts:
import signal
import sys

def signal_handler(sig, frame):
    print('Interrupt received, cleaning up...')
    sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)

with client.Session() as session:
    # Your automation
    pass

Session Lifecycle Diagram

┌─────────────────────────────────────────────────────────┐
│ 1. CREATE                                               │
│    session = client.Session(timeout_minutes=10)         │
│    Status: Not started (response = None)                │
└────────────────────┬────────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│ 2. START                                                │
│    with session: / session.start()                      │
│    Status: active                                       │
│    - Creates remote browser                             │
│    - Opens viewer if headless=False                     │
│    - Loads cookies from cookie_file                     │
└────────────────────┬────────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│ 3. ACTIVE OPERATIONS                                    │
│    - session.execute(action)                            │
│    - session.observe()                                  │
│    - session.scrape()                                   │
│    - session.page.goto(url)                             │
│    Status: active                                       │
└────────────────────┬────────────────────────────────────┘

            ┌────────┴────────┐
            ▼                 ▼
┌──────────────────┐  ┌──────────────────┐
│ 4a. TIMEOUT      │  │ 4b. STOP         │
│ (after N mins)   │  │ session.stop()   │
│ Status: timed_out│  │ Status: closed   │
└──────────────────┘  └──────────────────┘


┌─────────────────────────────────────────────────────────┐
│ 5. CLEANUP                                              │
│    - Saves cookies to cookie_file                       │
│    - Closes Playwright connections                      │
│    - Releases cloud resources                           │
└─────────────────────────────────────────────────────────┘

Next Steps