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.
Geographic proxy location (Cloud only). See 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. Default: false. See Save a session’s profile
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.
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.
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.
import asynciofrom skyvern import Skyvernasync 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())
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.
import asynciofrom skyvern import Skyvernasync 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())
You cannot use both browser_session_id and browser_profile_id in the same request. Choose one or the other.
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}).
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.
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.
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.
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.
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.
# 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 approvalsession = await client.create_browser_session(timeout=60)# Long-running agent that monitors a dashboardsession = await client.create_browser_session(timeout=480) # 8 hours
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.
# 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)
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.
# Block ads that overlay content and interfere with clickssession = await client.create_browser_session(extensions=["ad-blocker"])# Auto-solve captchas (Cloud only)session = await client.create_browser_session(extensions=["captcha-solver"])
Skyvern also offers 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:
Repeated logins, scheduled agents, shared auth state
You can create a Browser Profile from a completed session to save its authenticated state for future reuse. The session must have generate_browser_profile enabled or have been started from a profile.