> ## 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.

# Browser Controls

> Complete reference of all browser actions available in sessions

Sessions provide a comprehensive set of browser actions for interacting with web pages. All actions are executed through `session.execute()`.

## Navigation Actions

### Goto

Navigate to a URL.

{/* @sniptest testers/browser-controls/goto.py */}

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

client = NotteClient()

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

**Parameters:**

* `url` (str): The URL to navigate to

**Use for:** Opening pages, navigating between pages

***

### GotoNewTab

Open a URL in a new browser tab.

{/* @sniptest testers/browser-controls/goto_new_tab.py */}

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

client = NotteClient()

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

**Parameters:**

* `url` (str): The URL to open in a new tab

**Use for:** Opening multiple pages simultaneously, preserving context

***

### SwitchTab

Switch to a different browser tab.

{/* @sniptest testers/browser-controls/switch_tab.py */}

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

client = NotteClient()

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

    # Switch back to first tab
    session.execute(type="switch_tab", tab_index=0)
```

**Parameters:**

* `tab_index` (int): Zero-based index of the tab to switch to

**Use for:** Managing multiple tabs, comparing content across pages

***

### GoBack

Navigate back to the previous page.

{/* @sniptest testers/browser-controls/go_back.py */}

```python go_back.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="goto", url="https://example.com/products")

    # Go back to homepage
    session.execute(type="go_back")
```

**Use for:** Browser back button functionality, returning to previous pages

***

### GoForward

Navigate forward in browser history.

{/* @sniptest testers/browser-controls/go_forward.py */}

```python go_forward.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="goto", url="https://example.com/products")
    session.execute(type="go_back")
    # Now go forward again
    session.execute(type="go_forward")
```

**Use for:** Browser forward button functionality

***

### Reload

Reload the current page.

{/* @sniptest testers/browser-controls/reload.py */}

```python reload.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="reload")
```

**Use for:** Refreshing page content, retrying after errors

***

## Interaction Actions

### Click

Click on an element.

{/* @sniptest testers/browser-controls/click.py */}

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

client = NotteClient()

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

    # Click by CSS selector
    session.execute(type="click", selector="button#submit")

    # Click by ID from observe()
    session.execute(type="click", id="B1")

    # Click by text selector
    session.execute(type="click", selector="button:has-text('Submit')")
```

**Parameters:**

* `selector` (str): CSS selector for the element
* `id` (str): Element ID
* `text` (str): Exact text content
* `aria_label` (str): ARIA label attribute
* `placeholder` (str): Placeholder text
* `title` (str): Title attribute

**Use for:** Clicking buttons, links, checkboxes, any clickable element

***

### Fill

Fill a text input or textarea.

{/* @sniptest testers/browser-controls/fill.py */}

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

client = NotteClient()

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

    # Fill by selector
    session.execute(type="fill", selector="input[name='email']", value="user@example.com")

    # Fill by ID from observe()
    session.execute(type="fill", id="I1", value="user@example.com")

    # Fill by placeholder selector
    session.execute(type="fill", selector="input[placeholder='Enter your email']", value="user@example.com")
```

**Parameters:**

* `selector` (str): CSS selector for the input
* `id` (str): Element ID
* `placeholder` (str): Placeholder text
* `aria_label` (str): ARIA label
* `value` (str): The text to fill

**Use for:** Filling forms, search boxes, text inputs

***

### Check

Check or uncheck a checkbox.

{/* @sniptest testers/browser-controls/check.py */}

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

client = NotteClient()

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

    # Check a checkbox
    session.execute(type="check", selector="input[type='checkbox']#terms", value=True)

    # Uncheck a checkbox
    session.execute(type="check", selector="input[type='checkbox']#newsletter", value=False)
```

**Parameters:**

* `selector` (str): CSS selector for the checkbox
* `id` (str): Element ID
* `checked` (bool): True to check, False to uncheck

**Use for:** Toggling checkboxes, accepting terms, selecting options

***

### SelectDropdownOption

Select an option from a dropdown.

{/* @sniptest testers/browser-controls/select_dropdown_option.py */}

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

client = NotteClient()

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

    # Select by visible text
    session.execute(type="select_dropdown_option", selector="select#country", value="United States")

    # Select by value attribute
    session.execute(type="select_dropdown_option", selector="select#country", value="us")
```

**Parameters:**

* `selector` (str): CSS selector for the select element
* `option_text` (str): Visible text of the option
* `option_value` (str): Value attribute of the option

**Use for:** Selecting from dropdowns, choosing options

***

### PressKey

Press a keyboard key.

{/* @sniptest testers/browser-controls/press_key.py */}

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

client = NotteClient()

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

    # Press Enter
    session.execute(type="press_key", key="Enter")

    # Press Escape
    session.execute(type="press_key", key="Escape")

    # Press Tab
    session.execute(type="press_key", key="Tab")
```

**Parameters:**

* `key` (str): Key name (e.g., "Enter", "Escape", "Tab", "ArrowDown")

**Use for:** Keyboard navigation, submitting forms, triggering shortcuts

**Common keys:** Enter, Escape, Tab, ArrowUp, ArrowDown, ArrowLeft, ArrowRight, Backspace, Delete

***

### EvaluateJs

Evaluate JavaScript code on the current page and return the result.

{/* @sniptest testers/browser-controls/eval_js.py */}

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

client = NotteClient()

with client.Session() as session:
    session.execute(type="goto", url="https://notte.cc/")
    session.execute(type="evaluate_js", code="document.title")
```

**Parameters:**

* `code` (str): The JavaScript code to evaluate on the page

**Use for:** Evaluating JavaScript code, extracting data from the page

***

## Scrolling Actions

### ScrollUp

Scroll up on the page.

{/* @sniptest testers/browser-controls/scroll_up.py */}

```python scroll_up.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="scroll_up")
```

**Use for:** Scrolling to top of page, revealing content above

***

### ScrollDown

Scroll down on the page.

{/* @sniptest testers/browser-controls/scroll_down.py */}

```python scroll_down.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="scroll_down")
```

**Use for:** Loading lazy content, revealing content below, pagination

***

## File Actions

### UploadFile

Upload a file to a file input.

{/* @sniptest testers/browser-controls/upload_file.py */}

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

client = NotteClient()

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

    # Upload from local file
    session.execute(type="upload_file", selector="input[type='file']", file_path="/path/to/document.pdf")

    # Upload with ID
    session.execute(type="upload_file", id="file-upload", file_path="/path/to/image.jpg")
```

**Parameters:**

* `selector` (str): CSS selector for the file input
* `id` (str): Element ID
* `file_path` (str): Path to the file to upload

**Use for:** Uploading documents, images, any file input

***

### DownloadFile

Download a file from a link.

{/* @sniptest testers/browser-controls/download_file.py */}

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

client = NotteClient()

with client.Session() as session:
    session.execute(type="goto", url="https://example.com")
    result = session.execute(type="download_file", selector="a.download-link")
    print(f"Downloaded: {result}")
```

**Parameters:**

* `selector` (str): CSS selector for the download link
* `id` (str): Element ID

**Use for:** Downloading files, reports, documents

***

## Wait Action

### Wait

Pause execution for a specified duration.

{/* @sniptest testers/browser-controls/wait.py */}

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

client = NotteClient()

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

    # Wait 2 seconds
    session.execute(type="wait", time_ms=2000)

    # Wait 5 seconds for page to load
    session.execute(type="wait", time_ms=5000)
```

**Parameters:**

* `duration` (int): Time to wait in milliseconds

**Use for:** Waiting for page loads, animations, dynamic content

<Note>
  **Tip:** Use sparingly. Notte automatically waits for page loads and element visibility. Only use Wait for specific timing requirements.
</Note>

***

## Data Extraction

### Scrape

Extract data from the current page.

{/* @sniptest testers/browser-controls/scrape.py */}

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

    # Get page markdown
    markdown = session.scrape()

    # Extract with instructions
    data = session.scrape(instructions="Extract all product names and prices")

    # Structured extraction (wrap list in a model)
    products = session.scrape(response_format=Product, instructions="Extract all products")
```

**Parameters:**

* `instructions` (str): Natural language extraction instructions
* `response_format` (type\[BaseModel]): Pydantic model for structured output
* `only_main_content` (bool): Extract only main content, ignore headers/footers

**Use for:** Data extraction, web scraping, content analysis

See [Scraping](/concepts/scraping.md) for detailed documentation.

***

## Communication Actions

### SmsRead

Read SMS messages from a persona's phone number.

{/* @sniptest testers/browser-controls/sms_read.py */}

```python sms_read.py theme={null}
from collections.abc import Sequence

from notte_sdk import NotteClient
from notte_sdk.types import SMSResponse

client = NotteClient()


def extract_code(messages: Sequence[SMSResponse]) -> str:
    # Extract verification code from messages
    for msg in messages:
        if msg.body and "code" in msg.body.lower():
            return msg.body
    return ""


# Create persona with phone number
persona = client.Persona(create_phone_number=True)
phone_number = persona.info.phone_number

# Use in session
with client.Session() as session:
    # Trigger SMS (e.g., 2FA code)
    if phone_number:
        session.execute(type="fill", selector="input[name='phone']", value=phone_number)
        session.execute(type="click", selector="button.send-code")

        # Read SMS from persona
        messages = persona.sms()

        # Extract verification code
        code = extract_code(messages)
```

**Parameters:**

* `persona_id` (str): Persona ID with phone number

**Use for:** Reading 2FA codes, SMS verification, phone-based authentication

See [Personas](/concepts/personas.md) for details.

***

### EmailRead

Read emails from a persona's email address.

{/* @sniptest testers/browser-controls/email_read.py */}

```python email_read.py theme={null}
from collections.abc import Sequence

from notte_sdk import NotteClient
from notte_sdk.types import EmailResponse

client = NotteClient()


def extract_link(messages: Sequence[EmailResponse]) -> str:
    # Extract verification link from messages
    for msg in messages:
        if msg.text_content and "verify" in msg.text_content.lower():
            return msg.text_content
    return ""


# Create persona with email
persona = client.Persona()

# Use in session
with client.Session() as session:
    # Trigger email (e.g., verification email)
    session.execute(type="fill", selector="input[name='email']", value=persona.info.email)
    session.execute(type="click", selector="button.send-verification")

    # Read emails from persona
    messages = persona.emails()

    # Extract verification link
    link = extract_link(messages)
```

**Parameters:**

* `persona_id` (str): Persona ID with email address

**Use for:** Reading verification emails, email-based authentication

See [Personas](/concepts/personas.md) for details.

***

## Action Patterns

### Chaining Actions

Execute multiple actions in sequence:

{/* @sniptest testers/browser-controls/action_chaining.py */}

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

client = NotteClient()

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

    # Form filling
    session.execute(type="fill", selector="input[name='email']", value="user@example.com")
    session.execute(type="fill", selector="input[name='password']", value="password123")

    # Submission
    session.execute(type="click", selector="button[type='submit']")

    # Wait for redirect
    session.execute(type="wait", time_ms=2000)

    # Verify success
    content = session.scrape()
    print(content)
```

### Error Handling

Handle action failures:

{/* @sniptest testers/browser-controls/error_handling.py */}

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

client = NotteClient()

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

    # Don't raise on failure
    result = session.execute(type="click", selector="button.maybe-exists", raise_on_failure=False)

    if result.success:
        print("Button clicked successfully")
        session.execute(type="click", selector="button.next")
    else:
        print(f"Click failed: {result.message}")
        # Try alternative approach
        session.execute(type="click", selector="button.alternative")
```

### Conditional Actions

Execute actions based on conditions:

{/* @sniptest testers/browser-controls/conditional_actions.py */}

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

client = NotteClient()

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

    # Check if element exists
    result = session.execute(type="click", selector="button.optional", raise_on_failure=False)

    if result.success:
        # Element was there and clicked
        session.execute(type="click", selector="button.next")
    else:
        # Element wasn't there, skip
        print("Optional button not found, continuing...")
```

## Selector Strategies

### CSS Selectors

Most flexible and commonly used:

{/* @sniptest testers/browser-controls/css_selectors.py */}

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

client = NotteClient()

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

    # By ID
    session.execute(type="click", selector="#submit-button")

    # By class
    session.execute(type="click", selector=".btn-primary")

    # By attribute
    session.execute(type="click", selector="button[type='submit']")

    # By combination
    session.execute(type="click", selector="form#login button.submit")

    # By nth-child
    session.execute(type="click", selector="ul li:nth-child(2)")
```

### Direct Attributes

Use direct attribute parameters when available:

{/* @sniptest testers/browser-controls/direct_attributes.py */}

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

client = NotteClient()

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

    # By ID from observe()
    session.execute(type="click", id="B1")

    # By selector
    session.execute(type="click", selector="button[type='submit']")

    # By placeholder selector
    session.execute(type="fill", selector="input[placeholder='Enter email']", value="user@example.com")

    # By ARIA label selector
    session.execute(type="click", selector="button[aria-label='Close dialog']")
```

### Best Practices

**Prefer stable selectors:**

{/* @sniptest testers/browser-controls/stable_selectors.py */}

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

client = NotteClient()

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

    # Good - uses ID (stable)
    session.execute(type="click", id="submit-btn")

    # Good - uses data attribute
    session.execute(type="click", selector="button[data-testid='submit']")

    # Avoid - fragile position-based
    session.execute(type="click", selector="div > div > button:nth-child(3)")
```

**Use specific selectors:**

{/* @sniptest testers/browser-controls/specific_selectors.py */}

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

client = NotteClient()

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

    # Good - specific
    session.execute(type="fill", selector="form#login input[name='email']", value="user@example.com")

    # Less specific - might match wrong element
    session.execute(type="fill", selector="input", value="user@example.com")
```

## Common Workflows

### Form Submission

{/* @sniptest testers/browser-controls/form_submission.py */}

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

client = NotteClient()

with client.Session() as session:
    session.execute(type="goto", url="https://example.com/contact")
    session.execute(type="fill", id="name", value="John Doe")
    session.execute(type="fill", id="email", value="john@example.com")
    session.execute(type="fill", id="message", value="Hello!")
    session.execute(type="click", selector="button[type='submit']")
```

### Search and Extract

{/* @sniptest testers/browser-controls/search_extract.py */}

```python search_extract.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="fill", selector="input[name='search']", value="laptop")
    session.execute(type="press_key", key="Enter")
    session.execute(type="wait", time_ms=2000)

    results = session.scrape(instructions="Extract search results")
    print(results)
```

### Multi-Tab Workflow

{/* @sniptest testers/browser-controls/multi_tab.py */}

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

client = NotteClient()


def process_data(data):
    print(f"Processed: {data[:100]}...")


with client.Session() as session:
    # Open multiple tabs
    session.execute(type="goto", url="https://site1.com")
    session.execute(type="goto_new_tab", url="https://site2.com")
    session.execute(type="goto_new_tab", url="https://site3.com")

    # Extract from each tab
    for tab_index in range(3):
        session.execute(type="switch_tab", tab_index=tab_index)
        data = session.scrape()
        process_data(data)
```

### File Upload and Download

{/* @sniptest testers/browser-controls/file_upload_download.py */}

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

client = NotteClient()

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

    # Upload file
    session.execute(type="upload_file", selector="input[type='file']", file_path="/path/to/document.pdf")
    session.execute(type="click", selector="button.submit")

    # Wait for processing
    session.execute(type="wait", time_ms=3000)

    # Download result
    result = session.execute(type="download_file", selector="a.download")
    print(f"Downloaded: {result}")
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Session Configuration" icon="sliders" href="/features/sessions/configuration.md">
    Configure session behavior
  </Card>

  <Card title="Session Lifecycle" icon="rotate" href="/features/sessions/lifecycle.md">
    Manage session states
  </Card>

  <Card title="SDK Actions Reference" icon="code" href="/sdk-reference/manual/session.md">
    Detailed API documentation
  </Card>

  <Card title="Agent Mode" icon="sparkles" href="/concepts/agents.md">
    Let AI handle actions automatically
  </Card>
</CardGroup>
