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

# Browser Sessions

> Create and manage live browser sessions that persist cookies, local storage, and page state between task or agent runs. Use sessions for back-to-back tasks, human-in-the-loop approval, and real-time agents.

A **Browser Session** is a live browser instance that persists cookies, local storage, and page state between task or agent runs. Think of it as keeping a browser tab open. Use sessions when you need back-to-back tasks to share state, human-in-the-loop approval, or real-time agents.

***

## Create a session

Start a session with optional configuration for timeout, proxy, browser type, and extensions.

<CodeGroup>
  ```python Python theme={null}
  import asyncio
  from skyvern import Skyvern

  async def main():
      client = Skyvern(api_key="YOUR_API_KEY")

      session = await client.create_browser_session(
          timeout=60,                    # Max 60 minutes
          proxy_location="RESIDENTIAL",  # US residential proxy
          browser_type="chrome",         # Chrome or Edge
          extensions=["ad-blocker"],     # Optional extensions
      )

      print(f"Session ID: {session.browser_session_id}")
      print(f"Status: {session.status}")

  asyncio.run(main())
  ```

  ```typescript TypeScript theme={null}
  import { Skyvern } from "@skyvern/client";

  async function main() {
    const client = new Skyvern({
      apiKey: process.env.SKYVERN_API_KEY!,
    });

    const session = await client.createBrowserSession({
      timeout: 60,
      proxy_location: "RESIDENTIAL",
      browser_type: "chrome",
      extensions: ["ad-blocker"],
    });

    console.log(`Session ID: ${session.browser_session_id}`);
    console.log(`Status: ${session.status}`);
  }

  main();
  ```

  ```bash cURL theme={null}
  curl -X POST "https://api.skyvern.com/v1/browser_sessions" \
    -H "x-api-key: $SKYVERN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "timeout": 60,
      "proxy_location": "RESIDENTIAL",
      "browser_type": "chrome",
      "extensions": ["ad-blocker"]
    }'
  ```
</CodeGroup>

**Parameters:**

| Parameter                  | Type    | Description                                                                                                                                                                                                                                                                                                                                |
| -------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `timeout`                  | integer | Session lifetime in minutes. Min: 5, Max: 1440 (24 hours). Default: `60`                                                                                                                                                                                                                                                                   |
| `proxy_location`           | string  | Geographic proxy location (Cloud only). See [Proxy & Geolocation](/developers/going-to-production/proxy-geolocation) for available options                                                                                                                                                                                                 |
| `browser_type`             | string  | Browser type: `chrome` or `msedge`                                                                                                                                                                                                                                                                                                         |
| `extensions`               | array   | Extensions to install: `ad-blocker`, `captcha-solver`                                                                                                                                                                                                                                                                                      |
| `generate_browser_profile` | boolean | REST API only for now — not yet accepted by the SDK methods. Save the session's browser profile (cookies, localStorage, session files) when the session ends, so it can be turned into a reusable [browser profile](/developers/optimization/browser-profiles). Default: `false`. See [Save a session's profile](#save-a-sessions-profile) |

**Example response:**

```json theme={null}
{
  "browser_session_id": "pbs_490705123456789012",
  "organization_id": "o_485917350850524254",
  "status": "running",
  "timeout": 60,
  "browser_type": "chrome",
  "extensions": ["ad-blocker"],
  "vnc_streaming_supported": true,
  "app_url": "https://app.skyvern.com/browser-session/pbs_490705123456789012",
  "started_at": "2026-02-01T10:30:03.110Z",
  "created_at": "2026-02-01T10:30:00.000Z",
  "modified_at": "2026-02-01T10:30:03.251Z"
}
```

**Session statuses:**

| Status    | Description                                                                                                        |
| --------- | ------------------------------------------------------------------------------------------------------------------ |
| `running` | Browser is live and accepting tasks. This is the status returned on creation. The browser launches within seconds. |
| `closed`  | Session was closed manually or by timeout. No further tasks can run.                                               |

<Warning>
  Sessions close automatically when the timeout expires, **even if a task is still running**. The timeout countdown begins when the browser launches. Set timeouts with enough margin for your longest expected task.
</Warning>

***

## Run tasks with a session

Pass `browser_session_id` to `run_task` to execute tasks in an existing session. Each task continues from where the previous one left off: same page, same cookies, same form data.

<CodeGroup>
  ```python Python theme={null}
  import asyncio
  from skyvern import Skyvern

  async def main():
      client = Skyvern(api_key="YOUR_API_KEY")

      # Create session
      session = await client.create_browser_session(timeout=30)
      session_id = session.browser_session_id

      try:
          # Task 1: Login (wait for completion before continuing)
          await client.run_task(
              prompt="Login with username 'support@company.com'",
              url="https://dashboard.example.com/login",
              browser_session_id=session_id,
              wait_for_completion=True,
          )

          # Task 2: Search (already logged in from Task 1)
          result = await client.run_task(
              prompt="Find customer with email 'customer@example.com'",
              browser_session_id=session_id,
              wait_for_completion=True,
          )

          print(f"Customer: {result.output}")

      finally:
          # Always close when done
          await client.close_browser_session(browser_session_id=session_id)

  asyncio.run(main())
  ```

  ```typescript TypeScript theme={null}
  import { Skyvern } from "@skyvern/client";

  async function main() {
    const client = new Skyvern({ apiKey: process.env.SKYVERN_API_KEY! });

    const session = await client.createBrowserSession({ timeout: 30 });
    const sessionId = session.browser_session_id;

    try {
      // Task 1: Login (wait for completion)
      await client.runTask({
        body: {
          prompt: "Login with username 'support@company.com'",
          url: "https://dashboard.example.com/login",
          browser_session_id: sessionId,
        },
        waitForCompletion: true,
      });

      // Task 2: Search (reuses login state)
      const result = await client.runTask({
        body: {
          prompt: "Find customer with email 'customer@example.com'",
          browser_session_id: sessionId,
        },
        waitForCompletion: true,
      });

      console.log(`Customer: ${JSON.stringify(result.output)}`);

    } finally {
      await client.closeBrowserSession(sessionId);
    }
  }

  main();
  ```

  ```bash cURL theme={null}
  # Create session
  SESSION_ID=$(curl -s -X POST "https://api.skyvern.com/v1/browser_sessions" \
    -H "x-api-key: $SKYVERN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"timeout": 30}' | jq -r '.browser_session_id')

  echo "Session: $SESSION_ID"

  # Task 1: Login
  RUN_ID=$(curl -s -X POST "https://api.skyvern.com/v1/run/tasks" \
    -H "x-api-key: $SKYVERN_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{
      \"prompt\": \"Login with username 'support@company.com'\",
      \"url\": \"https://dashboard.example.com/login\",
      \"browser_session_id\": \"$SESSION_ID\"
    }" | jq -r '.run_id')

  # Poll until complete
  while true; do
    STATUS=$(curl -s "https://api.skyvern.com/v1/runs/$RUN_ID" \
      -H "x-api-key: $SKYVERN_API_KEY" | jq -r '.status')
    [ "$STATUS" != "created" ] && [ "$STATUS" != "queued" ] && [ "$STATUS" != "running" ] && break
    sleep 5
  done

  # Task 2: Search (reuses login state)
  curl -s -X POST "https://api.skyvern.com/v1/run/tasks" \
    -H "x-api-key: $SKYVERN_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{
      \"prompt\": \"Find customer with email 'customer@example.com'\",
      \"browser_session_id\": \"$SESSION_ID\"
    }"

  # Close session when done
  curl -s -X POST "https://api.skyvern.com/v1/browser_sessions/$SESSION_ID/close" \
    -H "x-api-key: $SKYVERN_API_KEY"
  ```
</CodeGroup>

***

## Run agents with a session

Pass `browser_session_id` to `run_workflow` to execute an agent in an existing session. This is useful when you need to run a predefined agent but want it to continue from your current browser state.

<CodeGroup>
  ```python Python theme={null}
  import asyncio
  from skyvern import Skyvern

  async def main():
      client = Skyvern(api_key="YOUR_API_KEY")

      # Create session
      session = await client.create_browser_session(timeout=60)
      session_id = session.browser_session_id

      try:
          # First, login manually via a task
          await client.run_task(
              prompt="Login with username 'admin@company.com'",
              url="https://app.example.com/login",
              browser_session_id=session_id,
              wait_for_completion=True,
          )

          # Then run a workflow in the same session (already logged in)
          result = await client.run_workflow(
              workflow_id="wpid_export_monthly_report",
              browser_session_id=session_id,
              wait_for_completion=True,
          )

          print(f"Workflow completed: {result.status}")

      finally:
          await client.close_browser_session(browser_session_id=session_id)

  asyncio.run(main())
  ```

  ```typescript TypeScript theme={null}
  import { Skyvern } from "@skyvern/client";

  async function main() {
    const client = new Skyvern({ apiKey: process.env.SKYVERN_API_KEY! });

    const session = await client.createBrowserSession({ timeout: 60 });
    const sessionId = session.browser_session_id;

    try {
      // First, login manually via a task
      await client.runTask({
        body: {
          prompt: "Login with username 'admin@company.com'",
          url: "https://app.example.com/login",
          browser_session_id: sessionId,
        },
        waitForCompletion: true,
      });

      // Then run a workflow in the same session (already logged in)
      const result = await client.runWorkflow({
        body: {
          workflow_id: "wpid_export_monthly_report",
          browser_session_id: sessionId,
        },
        waitForCompletion: true,
      });

      console.log(`Workflow completed: ${result.status}`);

    } finally {
      await client.closeBrowserSession(sessionId);
    }
  }

  main();
  ```

  ```bash cURL theme={null}
  # Create session
  SESSION_ID=$(curl -s -X POST "https://api.skyvern.com/v1/browser_sessions" \
    -H "x-api-key: $SKYVERN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"timeout": 60}' | jq -r '.browser_session_id')

  # Login via a task
  RUN_ID=$(curl -s -X POST "https://api.skyvern.com/v1/run/tasks" \
    -H "x-api-key: $SKYVERN_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{
      \"prompt\": \"Login with username 'admin@company.com'\",
      \"url\": \"https://app.example.com/login\",
      \"browser_session_id\": \"$SESSION_ID\"
    }" | jq -r '.run_id')

  # Poll until login completes
  while true; do
    STATUS=$(curl -s "https://api.skyvern.com/v1/runs/$RUN_ID" \
      -H "x-api-key: $SKYVERN_API_KEY" | jq -r '.status')
    [ "$STATUS" != "created" ] && [ "$STATUS" != "queued" ] && [ "$STATUS" != "running" ] && break
    sleep 5
  done

  # Run workflow in the same session (already logged in)
  curl -s -X POST "https://api.skyvern.com/v1/run/workflows" \
    -H "x-api-key: $SKYVERN_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{
      \"workflow_id\": \"wpid_export_monthly_report\",
      \"browser_session_id\": \"$SESSION_ID\"
    }"

  # Close session when done
  curl -s -X POST "https://api.skyvern.com/v1/browser_sessions/$SESSION_ID/close" \
    -H "x-api-key: $SKYVERN_API_KEY"
  ```
</CodeGroup>

<Note>
  You cannot use both `browser_session_id` and `browser_profile_id` in the same request. Choose one or the other.
</Note>

***

## Save a session's profile

By default, a browser session does **not** save its browser profile when it ends. To capture the session's state (cookies, localStorage, session files) for reuse, opt in with `generate_browser_profile`. Python and TypeScript SDK support for this flag is rolling out; until your SDK version includes it, call the REST API directly (the Python SDK can also pass it via `request_options` with `additional_body_parameters={"generate_browser_profile": True}`).

```bash theme={null}
curl -X POST "https://api.skyvern.com/v1/browser_sessions" \
  -H "x-api-key: $SKYVERN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "timeout": 60,
    "generate_browser_profile": true
  }'
```

You can also toggle the flag on a live session. The value is read when the session ends, so the update takes effect as long as the session is still open. Updating a session that has already closed returns a `409` error.

```bash theme={null}
curl -X PATCH "https://api.skyvern.com/v1/browser_sessions/pbs_abc123" \
  -H "x-api-key: $SKYVERN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"generate_browser_profile": true}'
```

To confirm the setting on an existing session, fetch it with `GET /v1/browser_sessions/{browser_session_id}` — the response includes `generate_browser_profile`.

Once the session closes and its profile finishes uploading, turn it into a reusable profile with [`create_browser_profile`](/developers/optimization/browser-profiles#from-a-browser-session).

<Note>
  Sessions started from a saved profile (`browser_profile_id`) always save their profile when they end, regardless of this flag. This does not update the original profile — to keep the refreshed login state, create a new profile from the closed session and use the new profile's ID in future runs.
</Note>

<Warning>
  **Behavior change:** sessions previously saved their profile automatically. Creating a browser profile from a closed session now fails with a `400` error unless the session had `generate_browser_profile` enabled or was started from a profile — retrying does not help. Update API scripts and integrations that create profiles from closed sessions; n8n users may need updated Skyvern nodes. Creating profiles from workflow runs (`persist_browser_session`) is unaffected.
</Warning>

***

## Close a session

Close a session to release resources and stop billing. The browser shuts down immediately.

<CodeGroup>
  ```python Python theme={null}
  await client.close_browser_session(
      browser_session_id="pbs_490705123456789012"
  )
  ```

  ```typescript TypeScript theme={null}
  await client.closeBrowserSession("pbs_490705123456789012");
  ```

  ```bash cURL theme={null}
  curl -X POST "https://api.skyvern.com/v1/browser_sessions/pbs_490705123456789012/close" \
    -H "x-api-key: $SKYVERN_API_KEY"
  ```
</CodeGroup>

<Warning>
  **Always close sessions when done.** Active sessions continue billing even when idle. Use try/finally blocks to ensure cleanup.
</Warning>

<CodeGroup>
  ```python Python theme={null}
  try:
      session = await client.create_browser_session(timeout=30)
      session_id = session.browser_session_id

      # Do work...
      await client.run_task(
          prompt="...",
          browser_session_id=session_id,
          wait_for_completion=True,
      )

  finally:
      # Always close, even if task fails
      await client.close_browser_session(browser_session_id=session_id)
  ```

  ```typescript TypeScript theme={null}
  const session = await client.createBrowserSession({ timeout: 30 });
  const sessionId = session.browser_session_id;

  try {
    await client.runTask({
      body: {
        prompt: "...",
        browser_session_id: sessionId,
      },
      waitForCompletion: true,
    });

  } finally {
    // Always close, even if task fails
    await client.closeBrowserSession(sessionId);
  }
  ```
</CodeGroup>

***

## Example: Human-in-the-loop

A shopping bot that pauses for human approval before completing a purchase.

<CodeGroup>
  ```python Python theme={null}
  import asyncio
  from skyvern import Skyvern

  async def shopping_with_approval():
      client = Skyvern(api_key="YOUR_API_KEY")

      session = await client.create_browser_session(timeout=15)
      session_id = session.browser_session_id

      try:
          # Step 1: Add to cart
          await client.run_task(
              prompt="Find wireless headphones under $100, add top result to cart",
              url="https://shop.example.com",
              browser_session_id=session_id,
              wait_for_completion=True,
          )

          # Step 2: Wait for human approval
          approval = input("Approve purchase? (yes/no): ")

          if approval.lower() == "yes":
              # Step 3: Checkout (cart persists from Step 1)
              result = await client.run_task(
                  prompt="Complete checkout and confirm order",
                  browser_session_id=session_id,
                  wait_for_completion=True,
              )
              print(f"Order placed: {result.output}")
          else:
              print("Purchase cancelled")

      finally:
          await client.close_browser_session(browser_session_id=session_id)

  asyncio.run(shopping_with_approval())
  ```

  ```typescript TypeScript theme={null}
  import { Skyvern } from "@skyvern/client";
  import * as readline from "readline";

  async function shoppingWithApproval() {
    const client = new Skyvern({ apiKey: process.env.SKYVERN_API_KEY! });

    const session = await client.createBrowserSession({ timeout: 15 });
    const sessionId = session.browser_session_id;

    try {
      // Step 1: Add to cart
      await client.runTask({
        body: {
          prompt: "Find wireless headphones under $100, add top result to cart",
          url: "https://shop.example.com",
          browser_session_id: sessionId,
        },
        waitForCompletion: true,
      });

      // Step 2: Wait for human approval
      const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
      const approval = await new Promise<string>((resolve) =>
        rl.question("Approve purchase? (yes/no): ", resolve)
      );
      rl.close();

      if (approval.toLowerCase() === "yes") {
        // Step 3: Checkout (cart persists from Step 1)
        const result = await client.runTask({
          body: {
            prompt: "Complete checkout and confirm order",
            browser_session_id: sessionId,
          },
          waitForCompletion: true,
        });
        console.log(`Order placed: ${JSON.stringify(result.output)}`);
      } else {
        console.log("Purchase cancelled");
      }

    } finally {
      await client.closeBrowserSession(sessionId);
    }
  }

  shoppingWithApproval();
  ```
</CodeGroup>

The browser maintains the cart contents during the approval pause. No state is lost.

***

## Best practices

### Set appropriate timeouts

Sessions bill while open, so match the timeout to your use case. A task typically completes in 30 to 90 seconds, so a 10-minute timeout covers most multi-step sequences with margin. Human-in-the-loop flows need longer timeouts to account for wait time.

<CodeGroup>
  ```python Python theme={null}
  # Quick multi-step task (2-3 tasks back to back)
  session = await client.create_browser_session(timeout=10)

  # Human-in-the-loop with wait time for approval
  session = await client.create_browser_session(timeout=60)

  # Long-running agent that monitors a dashboard
  session = await client.create_browser_session(timeout=480)  # 8 hours
  ```

  ```typescript TypeScript theme={null}
  // Quick multi-step task (2-3 tasks back to back)
  const session1 = await client.createBrowserSession({ timeout: 10 });

  // Human-in-the-loop with wait time for approval
  const session2 = await client.createBrowserSession({ timeout: 60 });

  // Long-running agent that monitors a dashboard
  const session3 = await client.createBrowserSession({ timeout: 480 }); // 8 hours
  ```

  ```bash cURL theme={null}
  # Quick multi-step task (2-3 tasks back to back)
  curl -s -X POST "https://api.skyvern.com/v1/browser_sessions" \
    -H "x-api-key: $SKYVERN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"timeout": 10}'

  # Human-in-the-loop with wait time for approval
  curl -s -X POST "https://api.skyvern.com/v1/browser_sessions" \
    -H "x-api-key: $SKYVERN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"timeout": 60}'

  # Long-running agent that monitors a dashboard
  curl -s -X POST "https://api.skyvern.com/v1/browser_sessions" \
    -H "x-api-key: $SKYVERN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"timeout": 480}'
  ```
</CodeGroup>

### Use agents for predetermined sequences

If your steps don't need pauses between them, an agent runs them in a single browser instance without the overhead of creating and managing a session. Each task in a session incurs its own startup cost, while agent blocks share one browser.

<CodeGroup>
  ```python Python theme={null}
  # Less efficient: multiple tasks in a session (each task has startup overhead)
  session = await client.create_browser_session()
  await client.run_task(prompt="Step 1", browser_session_id=session.browser_session_id, wait_for_completion=True)
  await client.run_task(prompt="Step 2", browser_session_id=session.browser_session_id, wait_for_completion=True)

  # More efficient: single workflow (blocks share one browser, no inter-task overhead)
  await client.run_workflow(workflow_id="wpid_abc", wait_for_completion=True)
  ```

  ```typescript TypeScript theme={null}
  // Less efficient: multiple tasks in a session (each task has startup overhead)
  const session = await client.createBrowserSession({});
  await client.runTask({ body: { prompt: "Step 1", browser_session_id: session.browser_session_id }, waitForCompletion: true });
  await client.runTask({ body: { prompt: "Step 2", browser_session_id: session.browser_session_id }, waitForCompletion: true });

  // More efficient: single workflow (blocks share one browser, no inter-task overhead)
  await client.runWorkflow({ body: { workflow_id: "wpid_abc" }, waitForCompletion: true });
  ```
</CodeGroup>

### Choose the right browser type

Chrome has the widest compatibility. Use Edge only when a site requires or detects it specifically.

<CodeGroup>
  ```python Python theme={null}
  # Chrome (default) - widest compatibility
  session = await client.create_browser_session(browser_type="chrome")

  # Edge - for sites that require or fingerprint Edge
  session = await client.create_browser_session(browser_type="msedge")
  ```

  ```typescript TypeScript theme={null}
  // Chrome (default) - widest compatibility
  const chromeSession = await client.createBrowserSession({ browser_type: "chrome" });

  // Edge - for sites that require or fingerprint Edge
  const edgeSession = await client.createBrowserSession({ browser_type: "msedge" });
  ```

  ```bash cURL theme={null}
  # Chrome (default) - widest compatibility
  curl -s -X POST "https://api.skyvern.com/v1/browser_sessions" \
    -H "x-api-key: $SKYVERN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"browser_type": "chrome"}'

  # Edge - for sites that require or fingerprint Edge
  curl -s -X POST "https://api.skyvern.com/v1/browser_sessions" \
    -H "x-api-key: $SKYVERN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"browser_type": "msedge"}'
  ```
</CodeGroup>

### Use extensions strategically

Extensions add startup time, so only enable them when needed. The ad-blocker removes overlay ads that can interfere with automation. The captcha-solver handles CAPTCHAs automatically but is only available on Cloud.

<CodeGroup>
  ```python Python theme={null}
  # Block ads that overlay content and interfere with clicks
  session = await client.create_browser_session(extensions=["ad-blocker"])

  # Auto-solve captchas (Cloud only)
  session = await client.create_browser_session(extensions=["captcha-solver"])
  ```

  ```typescript TypeScript theme={null}
  // Block ads that overlay content and interfere with clicks
  const adBlockSession = await client.createBrowserSession({ extensions: ["ad-blocker"] });

  // Auto-solve captchas (Cloud only)
  const captchaSession = await client.createBrowserSession({ extensions: ["captcha-solver"] });
  ```

  ```bash cURL theme={null}
  # Block ads that overlay content and interfere with clicks
  curl -s -X POST "https://api.skyvern.com/v1/browser_sessions" \
    -H "x-api-key: $SKYVERN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"extensions": ["ad-blocker"]}'

  # Auto-solve captchas (Cloud only)
  curl -s -X POST "https://api.skyvern.com/v1/browser_sessions" \
    -H "x-api-key: $SKYVERN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"extensions": ["captcha-solver"]}'
  ```
</CodeGroup>

***

## Sessions vs Profiles

Skyvern also offers [Browser Profiles](/developers/optimization/browser-profiles), saved snapshots of browser state (cookies, storage, session files) that you can reuse across days or weeks. Choose based on your use case:

| Aspect         | Browser Session                                         | Browser Profile                                      |
| -------------- | ------------------------------------------------------- | ---------------------------------------------------- |
| **What it is** | Live browser instance                                   | Saved snapshot of browser state                      |
| **Lifetime**   | Minutes to hours                                        | Days to months                                       |
| **State**      | Current page, cookies, open connections                 | Cookies, storage, session files                      |
| **Billing**    | Charged while open                                      | No cost when not in use                              |
| **Best for**   | Back-to-back tasks, human-in-the-loop, real-time agents | Repeated logins, scheduled agents, shared auth state |

<Tip>
  You can create a [Browser Profile](/developers/optimization/browser-profiles) from a completed session to save its authenticated state for future reuse. The session must have [`generate_browser_profile` enabled](#save-a-sessions-profile) or have been started from a profile.
</Tip>

***

## Next steps

<CardGroup cols={2}>
  <Card title="Connect Your Local Browser" icon="laptop" href="/developers/optimization/browser-tunneling">
    Let Skyvern Cloud use your local browser with your existing logins
  </Card>

  <Card title="Browser Profiles" icon="floppy-disk" href="/developers/optimization/browser-profiles">
    Save session state for reuse across days
  </Card>

  <Card title="Cost Control" icon="dollar-sign" href="/developers/optimization/cost-control">
    Optimize costs with max\_steps and efficient prompts
  </Card>
</CardGroup>
