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

# Browser Controls

> Complete reference of all browser actions available in sessions

<Tip>
  Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow.
</Tip>

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.

<CodeGroup>
  ```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")
  ```

  ```typescript goto.ts theme={null}
  import { NotteClient } from 'notte-sdk';

  const client = new NotteClient();

  const session = client.Session();
  await session.use(async () => {
    await session.execute({ type: "goto", url: "https://example.com" });
  });
  ```
</CodeGroup>

**Parameters:**

* `url` (str): The URL to navigate to
* `wait_until` (str, optional): Navigation event to wait for: `load` (default), `domcontentloaded`, `commit` or `networkidle`. `commit` and `domcontentloaded` skip the post-load settle wait, which makes them the cheap choice when the page is only needed as an origin for `session.fetch()`

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

***

### GotoNewTab

Open a URL in a new browser tab.

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

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

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

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

<CodeGroup>
  ```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")
  ```

  ```typescript reload.ts theme={null}
  import { NotteClient } from 'notte-sdk';

  const client = new NotteClient();

  const session = client.Session();
  await session.use(async () => {
    await session.execute({ type: "goto", url: "https://example.com" });
    await session.execute({ type: "reload" });
  });
  ```
</CodeGroup>

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

***

## Interaction Actions

### Click

Click on an element.

```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")

    # Pseudo observe output: [B1] button "Submit"
    # Only use IDs that appear in your live observe() output.
    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.

```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")

    # Pseudo observe output: [I1] input "Email"
    # Only use IDs that appear in your live observe() output.
    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.

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

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

<CodeGroup>
  ```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")
  ```

  ```typescript press_key.ts theme={null}
  import { NotteClient } from 'notte-sdk';

  const client = new NotteClient();

  const session = client.Session();
  await session.use(async () => {
    await session.execute({ type: "goto", url: "https://example.com" });

    // Press Enter
    await session.execute({ type: "press_key", key: "Enter" });

    // Press Escape
    await session.execute({ type: "press_key", key: "Escape" });

    // Press Tab
    await session.execute({ type: "press_key", key: "Tab" });
  });
  ```
</CodeGroup>

**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. `session.evaluate_js(code)` returns the evaluated string directly (objects and arrays as JSON); a failing script raises with the actual JavaScript error.

<CodeGroup>
  ```python eval_js.py theme={null}
  import json

  from notte_sdk import NotteClient

  client = NotteClient()

  with client.Session() as session:
      session.execute(type="goto", url="https://notte.cc/")
      # evaluate_js returns the evaluated string; failures raise with the JS error
      title = session.evaluate_js("document.title")
      # objects and arrays come back as JSON
      links = json.loads(session.evaluate_js("Array.from(document.querySelectorAll('a')).map(a => a.href)"))
  ```

  ```typescript eval_js.ts theme={null}
  import { NotteClient } from 'notte-sdk';

  const client = new NotteClient();

  const session = client.Session();
  await session.use(async () => {
    await session.execute({ type: 'goto', url: 'https://notte.cc/' });
    // evaluateJs returns the evaluated string; failures raise with the JS error
    const title = await session.evaluateJs('document.title');
    // objects and arrays come back as JSON
    const links = JSON.parse(await session.evaluateJs("Array.from(document.querySelectorAll('a')).map(a => a.href)"));
  });
  ```
</CodeGroup>

**Parameters:**

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

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

***

### Fetch

Issue an HTTP request from the page the session is on. `session.fetch(url)` runs the browser's own `fetch()` inside the current page, so the request carries the page's cookies, the session's proxy and the browser's network fingerprint. A relative URL resolves against the current page, which also keeps it same-origin; a cross-origin URL is subject to CORS as in any browser tab, so `goto` the target origin first. The result is a standard `requests.Response`: `status_code`, `ok`, `headers`, `text`, `url`, `json()` and `raise_for_status()` work as usual.

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

client = NotteClient()

with client.Session() as session:
    session.execute(type="goto", url="https://en.wikipedia.org/wiki/Main_Page")
    # fetch runs inside the page: same cookies, proxy and fingerprint as the browser
    response = session.fetch("/api/rest_v1/page/summary/Main_Page")
    response.raise_for_status()
    summary = response.json()
```

**Parameters:**

* `url` (str): The URL to request, absolute or relative to the current page
* `method` (str): HTTP method, `GET` by default
* `headers` (dict): Extra request headers
* `params` (dict): Query parameters appended to the URL
* `json` (Any): Body serialised as JSON with an `application/json` content type
* `data` (str | dict): Body sent verbatim, or form-encoded when a dict
* `timeout` (float): Seconds before the request is aborted

**Use for:** Calling a site's own JSON endpoints with the session's cookies and IP, without leaving the browser

***

## Scrolling Actions

Both scroll actions accept an optional `selector` for a scroll container, including iframe selectors.
For example, pass `selector="#results"` to scroll a results panel. The action calls `scrollBy`
on that container directly, emitting scroll events without sending a wheel event or moving the
pointer. If `amount` is omitted, the action scrolls by 70% of the container's height. Reaching the requested boundary succeeds without moving or scrolling the parent page.
A missing target or a blocked scroll before the boundary still fails.

Without a selector, the action sends a wheel event at the current pointer position and fails
if neither the page nor a container moves.

### ScrollUp

Scroll up on the page.

<CodeGroup>
  ```python scroll_up.py theme={null}
  from notte_sdk import NotteClient

  client = NotteClient()

  with client.Session() as session:
      session.execute(type="goto", url="https://en.wikipedia.org/wiki/Web_browser")
      session.execute(type="scroll_down")
      session.execute(type="scroll_up")
  ```

  ```typescript scroll_up.ts theme={null}
  import { NotteClient } from 'notte-sdk';

  const client = new NotteClient();

  const session = client.Session();
  await session.use(async () => {
    await session.execute({ type: "goto", url: "https://en.wikipedia.org/wiki/Web_browser" });
    await session.execute({ type: "scroll_down" });
    await session.execute({ type: "scroll_up" });
  });
  ```
</CodeGroup>

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

***

### ScrollDown

Scroll down on the page.

<CodeGroup>
  ```python scroll_down.py theme={null}
  from notte_sdk import NotteClient

  client = NotteClient()

  with client.Session() as session:
      session.execute(type="goto", url="https://en.wikipedia.org/wiki/Web_browser")
      session.execute(type="scroll_down")
  ```

  ```typescript scroll_down.ts theme={null}
  import { NotteClient } from 'notte-sdk';

  const client = new NotteClient();

  const session = client.Session();
  await session.use(async () => {
    await session.execute({ type: "goto", url: "https://en.wikipedia.org/wiki/Web_browser" });
    await session.execute({ type: "scroll_down" });
  });
  ```
</CodeGroup>

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

***

## File Actions

### UploadFile

Upload a file to a file input.

```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 a local file to the cloud session, then attach it by filename.
    uploaded = session.storage.upload("/path/to/document.pdf")
    session.execute(type="upload_file", selector="input[type='file']", file_path=uploaded.filename)

    # Or attach a public HTTP(S) file URL directly. Signed URLs also work.
    session.execute(
        type="upload_file",
        selector="input[type='file']",
        file_path="https://example.com/document.pdf",
    )
```

**Parameters:**

* `selector` (str): CSS selector for the file input
* `id` (str): Element ID
* `file_path` (str): In cloud sessions, a stored filename or a public HTTP(S) file URL, including signed URLs.

URL files download on the API server without navigating away from the form. They do
not use browser cookies, browser proxy settings, or custom authentication headers,
and are not added to the persistent session file catalog. The cloud backend must
support URL uploads; no SDK update is required. Standalone local sessions keep
their existing storage/path behavior.

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

***

### DownloadFile

Download a file from a link.

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

<CodeGroup>
  ```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)
  ```

  ```typescript wait.ts theme={null}
  import { NotteClient } from 'notte-sdk';

  const client = new NotteClient();

  const session = client.Session();
  await session.use(async () => {
    await session.execute({ type: "goto", url: "https://example.com" });

    // Wait 2 seconds
    await session.execute({ type: "wait", time_ms: 2000 });

    // Wait 5 seconds for page to load
    await session.execute({ type: "wait", time_ms: 5000 });
  });
  ```
</CodeGroup>

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

```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 [Fetch](/concepts/scraping) for detailed documentation.

***

## Communication Actions

### SmsRead

Read SMS messages from a persona's phone number.

```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) for details.

***

### EmailRead

Read emails from a persona's email address.

```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) for details.

***

## Action Patterns

### Chaining Actions

Execute multiple actions in sequence:

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

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

<CodeGroup>
  ```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...")
  ```

  ```typescript conditional_actions.ts theme={null}
  import { NotteClient } from 'notte-sdk';

  const client = new NotteClient();

  const session = client.Session();
  await session.use(async () => {
    await session.execute({ type: 'goto', url: 'https://example.com' });

    // Check if element exists
    const result = await session.execute({ type: 'click', selector: 'button.optional' }, { raiseOnFailure: false });

    if (result.success) {
      // Element was there and clicked
      await session.execute({ type: 'click', selector: 'button.next' });
    } else {
      // Element wasn't there, skip
      console.log('Optional button not found, continuing...');
    }
  });
  ```
</CodeGroup>

## Selector Strategies

### CSS Selectors

Most flexible and commonly used:

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

```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")

    # Pseudo observe output: [B1] button "Submit"
    # Only use IDs that appear in your live observe() output.
    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:**

```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:**

```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

```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

```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

```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

```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">
    Configure session behavior
  </Card>

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

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

  <Card title="File Storage" icon="folder" href="/concepts/file-storage">
    Upload and download files in sessions
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.