Overview
Browser Profiles allow you to capture and reuse browser state (cookies, local storage, session data) across multiple workflow runs. Unlike browser sessions which are temporary, profiles are persistent snapshots that can be reused indefinitely.
Key Concepts
Browser Session vs Browser Profile:
- Browser Session (
browser_session_id): Temporary, active browser instance. Used for maintaining state during a single run or between related tasks.
- Browser Profile (
browser_profile_id): Persistent snapshot of browser state. Can be reused across multiple independent runs.
When to Use Browser Profiles
- Reusable Authentication: Save logged-in state for multiple workflow runs
- Pre-configured Environments: Start workflows with pre-filled forms or settings
- Testing Different States: Create profiles for different user scenarios
- Login-Free Workflows: Skip authentication steps entirely by starting from an authenticated profile
Creating Browser Profiles
From a Browser Session
Capture a browser session’s state as a profile:
from skyvern import Skyvern
skyvern = Skyvern(api_key="your-api-key")
# 1. Create a browser session and log in
browser = await skyvern.launch_cloud_browser()
page = await browser.get_working_page()
await page.goto("https://example.com")
await page.agent.login(
credential_type="skyvern",
credential_id="cred_123"
)
session_id = browser.browser_session_id
# 2. Create a profile from the session
profile = await skyvern.create_browser_profile(
name="Example.com Authenticated",
description="Logged in user profile for example.com",
browser_session_id=session_id
)
print(f"Created profile: {profile.browser_profile_id}")
From a Workflow Run
Capture the final state of a workflow run:
# 1. Run a workflow that performs login
workflow_run = await skyvern.run_workflow(
workflow_id="wpid_login_workflow",
parameters={"username": "user@example.com"}
)
# 2. Create profile from the workflow's final state
profile = await skyvern.create_browser_profile(
name="Post-login Profile",
description="Profile after completing login workflow",
workflow_run_id=workflow_run.run_id
)
Via API
curl -X POST https://api.skyvern.com/api/v1/browser-profiles \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"name": "Authenticated Profile",
"description": "Logged in state for production environment",
"browser_session_id": "pbs_123456789"
}'
You must provide either browser_session_id OR workflow_run_id, but not both.
Using Browser Profiles
In Task Runs
# Run task with existing profile - no login needed!
task = await skyvern.run_task(
prompt="Navigate to dashboard and extract metrics",
url="https://example.com/dashboard",
browser_profile_id="bp_123456789" # Start with saved profile
)
In Workflow Runs
workflow_run = await skyvern.run_workflow(
workflow_id="wpid_data_extraction",
browser_profile_id="bp_123456789", # Use saved profile
parameters={
"start_date": "2024-01-01",
"end_date": "2024-12-31"
}
)
Via API
curl -X POST https://api.skyvern.com/api/v1/workflows/wpid_123/run \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"browser_profile_id": "bp_123456789",
"parameters": {
"query": "laptop"
}
}'
You cannot specify both browser_session_id and browser_profile_id in the same request. They are mutually exclusive.
Managing Profiles
List All Profiles
# Get all browser profiles for your organization
profiles = await skyvern.list_browser_profiles()
for profile in profiles:
print(f"Profile: {profile.browser_profile_id}")
print(f"Name: {profile.name}")
print(f"Created: {profile.created_at}")
print(f"Description: {profile.description}")
Get Profile Details
profile = await skyvern.get_browser_profile("bp_123456789")
print(f"Profile ID: {profile.browser_profile_id}")
print(f"Organization: {profile.organization_id}")
print(f"Name: {profile.name}")
print(f"Created: {profile.created_at}")
print(f"Modified: {profile.modified_at}")
Update Profile
# Update profile name or description
updated_profile = await skyvern.update_browser_profile(
browser_profile_id="bp_123456789",
name="Updated Profile Name",
description="New description for this profile"
)
Delete Profile
# Delete a profile when no longer needed
await skyvern.delete_browser_profile("bp_123456789")
Profile Schema
class BrowserProfile(BaseModel):
browser_profile_id: str # e.g., "bp_123456789"
organization_id: str # Your organization ID
name: str # Profile name
description: str | None # Optional description
created_at: datetime # When profile was created
modified_at: datetime # Last modification time
deleted_at: datetime | None # Soft delete timestamp
Use Cases
1. Login-Free Workflow Testing
# Setup: Create authenticated profile once
browser = await skyvern.launch_cloud_browser()
page = await browser.get_working_page()
await page.goto("https://app.example.com")
await page.agent.login("skyvern", "cred_test_user")
test_profile = await skyvern.create_browser_profile(
name="Test User Profile",
browser_session_id=browser.browser_session_id
)
# Run: Execute tests without login step
for test_case in test_cases:
result = await skyvern.run_workflow(
workflow_id=test_case.workflow_id,
browser_profile_id=test_profile.browser_profile_id,
parameters=test_case.params
)
2. Multi-Account Management
# Create profiles for different accounts
profiles = {
"admin": await create_profile_for_user("admin@example.com"),
"user": await create_profile_for_user("user@example.com"),
"guest": await create_profile_for_user("guest@example.com"),
}
# Run workflows as different users
for role, profile_id in profiles.items():
await skyvern.run_workflow(
workflow_id="wpid_data_export",
browser_profile_id=profile_id,
parameters={"role": role}
)
# Create profile with specific settings
browser = await skyvern.launch_cloud_browser()
page = await browser.get_working_page()
# Configure browser state
await page.goto("https://example.com/settings")
await page.click(prompt="Enable dark mode")
await page.click(prompt="Set language to Spanish")
await page.fill(prompt="Notification email", value="alerts@company.com")
# Save configuration as profile
config_profile = await skyvern.create_browser_profile(
name="Production Configuration",
description="Dark mode, Spanish, email notifications enabled",
browser_session_id=browser.browser_session_id
)
# All future runs start with this configuration
await skyvern.run_workflow(
workflow_id="wpid_monitoring",
browser_profile_id=config_profile.browser_profile_id
)
Best Practices
Profile Naming Conventions
# Use descriptive names that indicate purpose and environment
profiles = [
"Production - Admin User - 2024-01",
"Staging - Test User 1 - Latest",
"Dev - Guest Access - No Auth",
"Customer Service - Support Rep - Full Access",
]
Profile Versioning
# Create versioned profiles for different states
profile_v1 = await skyvern.create_browser_profile(
name="User Profile v1.0",
description="Initial authenticated state",
browser_session_id=session_id
)
# Later, create updated version
profile_v2 = await skyvern.create_browser_profile(
name="User Profile v2.0",
description="With premium features enabled",
browser_session_id=new_session_id
)
Regular Profile Updates
import asyncio
from datetime import datetime, timedelta
async def refresh_profile_if_stale(profile_id: str, max_age_days: int = 30):
"""Refresh profile if older than max_age_days"""
profile = await skyvern.get_browser_profile(profile_id)
age = datetime.now() - profile.modified_at
if age > timedelta(days=max_age_days):
# Create new session and update profile
browser = await skyvern.launch_cloud_browser()
await perform_login(browser) # Your login logic
new_profile = await skyvern.create_browser_profile(
name=profile.name,
description=f"Refreshed on {datetime.now().date()}",
browser_session_id=browser.browser_session_id
)
# Delete old profile
await skyvern.delete_browser_profile(profile_id)
return new_profile.browser_profile_id
return profile_id
Troubleshooting
Profile State Not Persisting
Ensure the browser session was fully established before creating the profile:
# Wait for login to complete
await page.agent.login("skyvern", "cred_123")
await page.wait_for_load_state("networkidle")
# Now create profile
profile = await skyvern.create_browser_profile(
name="Fully Loaded Profile",
browser_session_id=browser.browser_session_id
)
Profile Contains Sensitive Data
Profiles capture all browser state including cookies and local storage. Be cautious:
# Clear sensitive data before creating profile
await page.evaluate("""
// Clear sensitive local storage items
localStorage.removeItem('credit_card');
localStorage.removeItem('ssn');
""")
profile = await skyvern.create_browser_profile(
name="Sanitized Profile",
browser_session_id=browser.browser_session_id
)