Overview
Persistent Browser Sessions (PBS) allow you to maintain browser state across multiple tasks and workflow runs. This is essential for workflows that require maintaining login state, cookies, or other browser context between operations.
Key Benefits
- State Persistence: Maintain login sessions, cookies, and local storage across tasks
- Performance: Skip repeated authentication and navigation steps
- Cost Efficiency: Reduce the number of steps and LLM calls by reusing authenticated sessions
- Workflow Continuity: Chain multiple tasks together while preserving context
Browser Session Lifecycle
Browser sessions go through the following states:
class PersistentBrowserSessionStatus(StrEnum):
created = "created" # Session initialized
running = "running" # Session actively being used
failed = "failed" # Session encountered an error
completed = "completed" # Session finished successfully
timeout = "timeout" # Session exceeded timeout limit
retry = "retry" # Session is being retried
Creating a Browser Session
Via SDK (Python)
from skyvern import Skyvern
skyvern = Skyvern(api_key="your-api-key")
# Create a new browser session
browser = await skyvern.launch_cloud_browser()
page = await browser.get_working_page()
# Perform actions
await page.goto("https://example.com")
await page.agent.login(
credential_type="skyvern",
credential_id="cred_123"
)
# Get the session ID for reuse
session_id = browser.browser_session_id
print(f"Browser session: {session_id}")
# Keep browser open for reuse
# Don't call browser.close() if you want to reuse the session
Via SDK (TypeScript)
import { Skyvern } from "@skyvern/client";
const skyvern = new Skyvern({ apiKey: "your-api-key" });
// Create a new browser session
const browser = await skyvern.launchCloudBrowser();
const page = await browser.getWorkingPage();
// Perform actions
await page.goto("https://example.com");
await page.agent.login("skyvern", { credentialId: "cred_123" });
// Get the session ID for reuse
const sessionId = browser.browserSessionId;
console.log(`Browser session: ${sessionId}`);
Reusing Browser Sessions
Once you have a browser session ID, you can reuse it in subsequent tasks:
In Task Runs
from skyvern import Skyvern
skyvern = Skyvern(api_key="your-api-key")
# Reuse existing session
task = await skyvern.run_task(
prompt="Navigate to account settings and update email",
url="https://example.com/settings",
browser_session_id="pbs_123456789" # Reuse session
)
In Workflow Runs
workflow_run = await skyvern.run_workflow(
workflow_id="wpid_123",
parameters={"user_email": "[email protected]"},
browser_session_id="pbs_123456789" # Reuse session
)
Via API
curl -X POST https://api.skyvern.com/api/v1/tasks \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Check order status",
"url": "https://example.com/orders",
"browser_session_id": "pbs_123456789"
}'
Session Configuration
Timeout Settings
Browser sessions have configurable timeout periods:
# Configure session timeout when creating
session = await skyvern.create_browser_session(
timeout=45 # 45 minute timeout
)
Proxy and Geolocation
Browser sessions can be configured with specific proxy locations:
workflow_run = await skyvern.run_workflow(
workflow_id="wpid_123",
browser_session_id="pbs_123",
proxy_location="RESIDENTIAL_GB" # UK residential proxy
)
Managing Sessions
Listing Active Sessions
# Get all active browser sessions
sessions = await skyvern.get_browser_sessions()
for session in sessions:
print(f"Session: {session.browser_session_id}")
print(f"Status: {session.status}")
print(f"Started: {session.started_at}")
Closing Sessions
# Close a specific session
await skyvern.close_browser_session("pbs_123456789")
# Or close via browser object
await browser.close()
Via CLI
# Create a session
skyvern browser session create --timeout 30
# List sessions
skyvern browser session list
# Get session details
skyvern browser session get pbs_123
# Close a session
skyvern browser session close pbs_123
Best Practices
Session Reuse Patterns
- Login Once, Use Many Times
# First task: Login and get session
browser = await skyvern.launch_cloud_browser()
page = await browser.get_working_page()
await page.goto("https://example.com")
await page.agent.login("skyvern", "cred_123")
session_id = browser.browser_session_id
# Subsequent tasks: Reuse session
for action in ["view_orders", "update_profile", "download_invoice"]:
await skyvern.run_task(
prompt=f"Perform {action}",
browser_session_id=session_id
)
- Multi-Step Workflows
# Step 1: Search and add to cart
task1 = await skyvern.run_task(
prompt="Search for laptop and add to cart",
url="https://store.com",
)
# Step 2: Checkout using same session
task2 = await skyvern.run_task(
prompt="Complete checkout with saved payment",
browser_session_id=task1.browser_session_id
)
Error Handling
from skyvern.exceptions import BrowserSessionNotRenewable
try:
await skyvern.run_task(
prompt="Check account",
browser_session_id="pbs_old"
)
except BrowserSessionNotRenewable:
# Session expired, create new one
browser = await skyvern.launch_cloud_browser()
# Retry task with new session
Resource Management
# Always close sessions when done
try:
browser = await skyvern.launch_cloud_browser()
# ... perform tasks ...
finally:
await browser.close()
Browser sessions include compute and cost information:
session = await skyvern.get_browser_session("pbs_123")
print(f"Instance type: {session.instance_type}")
print(f"Duration: {session.duration_ms}ms")
print(f"Cost: ${session.compute_cost}")
print(f"Browser type: {session.browser_type}") # chrome, msedge
print(f"IP address: {session.ip_address}")
Advanced: Custom Browser Connection
Connect to your own browser instance:
from skyvern import Skyvern
# Connect to local Chrome via CDP
skyvern = Skyvern(
cdp_url="http://127.0.0.1:9222"
)
# Or specify Chrome path
skyvern = Skyvern(
browser_path="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
)
task = await skyvern.run_task(
prompt="Navigate and extract data",
url="https://example.com"
)
Since Chrome 136, Chrome refuses CDP connections using the default user_data_dir. Skyvern automatically copies your default user_data_dir to ./tmp/user_data_dir the first time connecting to your local browser.
Troubleshooting
Session Not Found
If you get a session not found error, the session may have expired or been closed:
# Check if session exists and is active
try:
session = await skyvern.get_browser_session("pbs_123")
if session.status in ["completed", "failed", "timeout"]:
# Create new session
browser = await skyvern.launch_cloud_browser()
except NotFoundError:
# Session doesn't exist
browser = await skyvern.launch_cloud_browser()
Session Timeout
Increase timeout for long-running workflows:
session = await skyvern.create_browser_session(
timeout=120 # 2 hour timeout
)