> ## Documentation Index
> Fetch the complete documentation index at: https://docs.notte.cc/llms.txt
> Use this file to discover all available pages before exploring further.

# Session Lifecycle

> Manage the lifecycle of your Notte browser sessions

<Tip>
  STOP. Do not read past this section until you have read and followed [/quickstart.md](/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.
</Tip>

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):

<CodeGroup>
  ```python Python - Context Manager theme={null}
  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
  ```

  ```python Python - Manual Management theme={null}
  from notte_sdk import NotteClient

  client = NotteClient()

  # Manual management (not recommended)
  session = client.Session(timeout_minutes=10)
  session.start()

  try:
      print(f"Session {session.session_id} is active")
      page = session.page
      page.goto("https://example.com")
  finally:
      # Always stop the session
      session.stop()
  ```
</CodeGroup>

<Tip>
  Always use the context manager (`with` statement) to ensure sessions are properly stopped, even if errors occur.
</Tip>

## Getting Session Details

Retrieve current information about your session:

<CodeGroup>
  ```python Python theme={null}
  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}")
  ```
</CodeGroup>

<ResponseField name="session_id" type="string">
  Unique identifier for the session
</ResponseField>

<ResponseField name="status" type="string">
  Current status: `active`, `closed`, `error`, or `timed_out`
</ResponseField>

<ResponseField name="created_at" type="datetime">
  Session creation timestamp
</ResponseField>

<ResponseField name="closed_at" type="datetime | None">
  Session closure timestamp (None if still active)
</ResponseField>

<ResponseField name="last_accessed_at" type="datetime">
  Last operation timestamp
</ResponseField>

<ResponseField name="timeout_minutes" type="integer">
  Session timeout in minutes
</ResponseField>

<ResponseField name="duration" type="timedelta">
  Total session duration
</ResponseField>

## Listing Sessions

Query all your active sessions:

<CodeGroup>
  ```python Python theme={null}
  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)}")
  ```
</CodeGroup>

## Stopping a Session

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

<CodeGroup>
  ```python Python theme={null}
  from notte_sdk import NotteClient

  client = NotteClient()

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

  # ... do work ...

  session.stop()
  print("Session stopped successfully")
  ```
</CodeGroup>

<Tip>
  Stopping a session is idempotent - you can safely call it multiple times without errors.
</Tip>

## Complete Lifecycle Example

Here's a complete example demonstrating best practices for session management:

<CodeGroup>
  ```python Python theme={null}
  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()
  ```
</CodeGroup>

## Connecting to Existing Sessions

You can reconnect to an existing session using its session\_id:

<CodeGroup>
  ```python Python theme={null}
  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")
  ```
</CodeGroup>

## Error Handling

The context manager automatically handles cleanup, even when errors occur:

<CodeGroup>
  ```python Python - Automatic Cleanup theme={null}
  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")
  ```

  ```python Python - Manual Error Handling theme={null}
  from notte_sdk import NotteClient

  client = NotteClient()

  session = None

  try:
      session = client.Session()
      session.start()

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

      # Your automation code here

  except Exception as error:
      print(f"Automation failed: {error}")
  finally:
      # This always runs, whether success or failure
      if session is not None:
          session.stop()
          print("Session stopped")
  ```
</CodeGroup>

## Best Practices

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

### 1. Always Use Context Managers

The `with` statement guarantees cleanup:

{/* @sniptest testers/sessions/lifecycle/context_manager.py */}

```python context_manager.py theme={null}
from notte_sdk import NotteClient

client = NotteClient()

with client.Session() as session:
    # ... use session
    pass
# 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

{/* @sniptest testers/sessions/lifecycle/timeout_example.py */}

```python timeout_example.py theme={null}
from notte_sdk import NotteClient

client = NotteClient()

with client.Session(idle_timeout_minutes=15) as session:
    # Complex automation
    pass
```

### 3. Monitor Session State

Check session status before long-running operations:

{/* @sniptest testers/sessions/lifecycle/monitor_state.py */}

```python monitor_state.py theme={null}
from notte_sdk import NotteClient

client = NotteClient()

with client.Session() as session:
    status = session.status()
    if status.status != "active":
        raise Exception("Session is no longer active")

    # Continue with operations
    pass
```

### 4. Handle Cleanup Gracefully

Even with context managers, handle interrupts:

{/* @sniptest testers/sessions/lifecycle/handle_interrupts.py */}

```python handle_interrupts.py theme={null}
import signal
import sys

from notte_sdk import NotteClient

client = NotteClient()


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

<CardGroup cols={2}>
  <Card title="Session Configuration" icon="gear" href="/features/sessions/configuration">
    Configure sessions with advanced options
  </Card>

  <Card title="Recordings" icon="video" href="/features/sessions/recordings">
    Record and replay session activity
  </Card>

  <Card title="Live View" icon="eye" href="/features/sessions/live-view">
    Watch sessions in real-time
  </Card>

  <Card title="Cookies" icon="cookie-bite" href="/features/sessions/cookies">
    Persist authentication across sessions
  </Card>
</CardGroup>
