Back to Skills

Skyvern Browser Automation

AI-powered browser automation — navigate sites, fill forms, extract structured data, log in with stored credentials, and build reusable workflows

browserautomationscrapingaiworkflows
By Skyvern AI
22k2.0kUpdated 2 weeks agoPythonAGPL-3.0

Skill Content

# Skyvern Browser Automation -- CLI Judgment Procedure

Skyvern uses AI to navigate and interact with websites. Every command below is a runnable `skyvern <command>` invocation.

## Step 1: Classify Your Task (ALWAYS do this first)

| Classification | Signal | CLI Command | Cost | What Happens |
|---|---|---|---|---|
| Quick check (yes/no) | "is the user logged in?" | `skyvern browser validate` | 1 LLM + screenshots | Lightweight validation (2 steps max), returns boolean. Cheapest AI option. |
| Quick inspection | "what does the page show?" | `skyvern browser extract` | 1 LLM + screenshots | Dedicated extraction LLM + schema validation + caching. |
| Single action (known target) | "click #submit" | `skyvern browser click/type` | 0 LLM | Deterministic Playwright. No AI. Fastest. |
| Single action (unknown target) | "click the submit button" | `skyvern browser act` | 2-3 LLM, no screenshots | No screenshots in reasoning. Economy a11y tree. For visual targets, use hybrid mode (selector + intent). |
| Same-page multi-step | "fill the form and submit" | `skyvern browser act` or primitive chain | 2-3 LLM or 0 LLM | Use `act` when labels are clear. Use click/type/select directly when you know selectors. |
| Throwaway autonomous trial | "try this once", "see if this works" | `skyvern browser run-task` | Higher | One-off autonomous agent for exploration. Do not use for recurring or multi-page production automations. |
| Multi-page or reusable automation | "navigate a multi-page wizard", "set this up", "automate this weekly" | `skyvern workflow create` + `run` | N LLM + screenshots | Build a workflow with one block per step. Each block gets visual reasoning, verification, and reusable run history. |

**MCP note:** if you are using the Skyvern MCP instead of the CLI, prefer `observe + execute` for same-page multi-step UI work. The CLI does not expose that pair directly.

## Step 2: Apply These Decision Rules

1. If the prompt includes a selector, id, XPath, or exact field target, use browser primitives -- not `act`.
2. If you only need a yes/no answer, use `validate` -- not `extract` or `act`.
3. If the work stays on one page and labels are clear, use `act` or a primitive chain.
4. If the user says `try this once`, `see if this works`, or clearly wants a one-off exploratory trial, use `run-task`.
5. If the task spans multiple pages and is meant to be reusable, scheduled, repeatable, or explicitly `set up` as automation, use `workflow create`.
6. Never type passwords. Always use stored credentials with `skyvern browser login`.

## Step 3: Create a Session

Every browser command needs a session. Create one first:

```bash
# Cloud session (default -- works for public URLs)
skyvern browser session create --timeout 30

# Local session (for localhost URLs or self-hosted mode)
skyvern browser session create --local --timeout 30

# Connect to existing browser via CDP
skyvern browser session connect --cdp "ws://localhost:9222"
```

Session state persists between commands. After `session create`, subsequent commands auto-attach.
Override with `--session pbs_...`. Close when done: `skyvern browser session close`.

## Step 4: Execute by Classification

### Quick check (yes/no)

```bash
skyvern browser validate --prompt "Is the user logged in? Look for a dashboard or avatar."
```

Returns true/false. Cheapest AI option -- prefer over extract or act for boolean checks.

### Quick inspection

```bash
skyvern browser extract   --prompt "Extract all product names and prices"   --schema '{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"price":{"type":"string"}}}}}}'
```

Uses screenshots + dedicated extraction LLM. Better than screenshot+read because Skyvern's LLM interprets the page.

### Single action (known target)

```bash
skyvern browser click --selector "#submit-btn"
skyvern browser type --text "user@co.com" --selector "#email"
skyvern browser select --value "US" --intent "the country dropdown"
```

Deterministic. No AI. Three targeting modes:
1. **Intent**: `--intent "the Submit button"` (AI finds element)
2. **Selector**: `--selector "#submit-btn"` (CSS/XPath, deterministic)
3. **Hybrid**: both (selector narrows, AI confirms)

### Single action (unknown target)

```bash
skyvern browser act --prompt "Click the Sign In button"
skyvern browser act --prompt "Close the cookie banner, then click Sign In"
```

**Warning:** act has NO screenshots in its LLM reasoning. It uses an economy accessibility tree.
Fine for well-labeled elements. For visually complex targets, use MCP observe+click or hybrid mode.

### Same-page multi-step

```bash
skyvern browser act --prompt "Fill the shipping form and click Continue"
```

Use `act` when the fields and buttons are clearly labeled and the flow stays on one page.
If you need tighter control, break the work into `click`, `type`, `select`, `press-key`, and `wait`.

### Throwaway autonomous trial

```bash
skyvern browser run-task   --url "https://example.com"   --prompt "Check whether the checkout flow works end to end and extract the confirmation number"
```

Use `run-task` to prove feasibility or do one-off exploration. If the task becomes important enough
to rerun, debug, or share, convert it to a workflow.

### Multi-page or reusable automation — build a workflow with one block per step

```bash
skyvern workflow create --definition @checkout-workflow.yaml
skyvern workflow run --id wpid_123 --wait
skyvern workflow status --run-id wr_789
```

Each navigation block runs with visual reasoning + verification. Split complex flows into
multiple blocks (one per page/step). First run uses AI; subsequent runs replay cached scripts.

### Repeated/production

```bash
skyvern workflow create --definition @workflow.yaml
skyvern workflow run --id wpid_123 --params '{"email":"user@co.com"}'
skyvern workflow status --run-id wr_789
```

Split into one block per step. Use **navigation** blocks for actions, **extraction** for data.
First run uses AI; subsequent runs replay a cached script (10-100x faster).
Set `--run-with agent` to force AI mode for debugging.

## Step 5: Verify

Always verify after page-changing actions:

```bash
skyvern browser screenshot                          # visual check
skyvern browser validate --prompt "Was the form submitted successfully?"  # boolean assertion
skyvern browser evaluate --expression "document.title"                    # JS state check
```

## Step 6: Error Recovery

| Problem | Fix |
|---------|-----|
| Action clicked wrong element | Add context to prompt. Use hybrid mode (selector + intent). |
| Extraction returns empty | Wait for content. Relax required fields. Check row count first. |
| Login passes but next step fails | Ensure same session. Add post-login validate check. |
| Element not found | Add wait: `skyvern browser wait --selector "#el" --state visible` |
| Overloaded prompt | Split into smaller goals -- one intent per command. |

## Credentials

NEVER type passwords through `skyvern browser type` or `act`. Always use stored credentials:

```bash
skyvern credentials add --name "my-login" --type password --username "user@co.com"
skyvern credential list                          # find the credential ID
skyvern browser login --url "https://login.example.com" --credential-id cred_123
```

Types: `password`, `credit_card`, `secret`. Also supports bitwarden, 1password, and azure_vault providers.

## Workflow Quick Reference

```bash
skyvern workflow create --definition @workflow.yaml   # create
skyvern workflow run --id wpid_123 --wait             # run and wait
skyvern workflow status --run-id wr_789               # check status
skyvern workflow list --search "invoice"              # find workflows
skyvern block schema --type navigation                # discover block types
skyvern block validate --block-json @block.json       # validate before creating
```

Engine: known path = 1.0 (default). Dynamic planning = 2.0. Split into multiple 1.0 blocks when in doubt.
Status lifecycle: `created -> queued -> running -> completed | failed | canceled | terminated | timed_out`

## Common Patterns

**Login flow:**
```bash
skyvern credential list                          # find credential ID
skyvern browser session create
skyvern browser navigate --url "https://login.example.com"
skyvern browser login --url "https://login.example.com" --credential-id cred_123
skyvern browser validate --prompt "Is the user logged in?"
skyvern browser screenshot
```

**Pagination loop:**
```bash
skyvern browser extract --prompt "Extract all rows"
skyvern browser validate --prompt "Is there a Next button that is not disabled?"
# If true:
skyvern browser act --prompt "Click the Next page button"
# Repeat extraction. Stop when: no next button, duplicate first row, or max page limit.
```

**Debugging:**
```bash
skyvern browser screenshot                       # visual state
skyvern browser evaluate --expression "document.title"
skyvern browser evaluate --expression "document.querySelectorAll('table tr').length"
```

## Agent Mode

All commands accept `--json` for structured output. Set `SKYVERN_NON_INTERACTIVE=1` to prevent prompts.
Use `skyvern capabilities --json` for full command discovery. See `references/agent-mode.md`.

## Deep-Dive References

| Reference | Content |
|-----------|---------|
| `references/prompt-writing.md` | Prompt templates and anti-patterns |
| `references/engines.md` | When to use tasks vs workflows |
| `references/schemas.md` | JSON schema patterns for extraction |
| `references/pagination.md` | Pagination strategy and guardrails |
| `references/block-types.md` | Workflow block type details with examples |
| `references/parameters.md` | Parameter design and variable usage |
| `references/ai-actions.md` | AI action patterns and examples |
| `references/precision-actions.md` | Intent-only, selector-only, hybrid modes |
| `references/credentials.md` | Credential naming, lifecycle, safety |
| `references/sessions.md` | Session reuse and freshness decisions |
| `references/common-failures.md` | Failure pattern catalog with fixes |
| `references/screenshots.md` | Screenshot-led debugging workflow |
| `references/status-lifecycle.md` | Run status states and guidance |
| `references/rerun-playbook.md` | Rerun procedures and comparison |
| `references/complex-inputs.md` | Date pickers, uploads, dropdowns |
| `references/tool-map.md` | Complete tool inventory by outcome |
| `references/cli-parity.md` | CLI/MCP mapping and agent-aware features |

How to use

  1. Copy the skill content above
  2. Create a .claude/skills directory in your project
  3. Save as .claude/skills/skyvern-skill.md
  4. Use /skyvern-skill in Claude Code to invoke this skill
<!-- DOCTOC SKIP --> <h1 align="center"> <a href="https://www.skyvern.com"> <picture> <source media="(prefers-color-scheme: dark)" srcset="fern/images/skyvern_logo.png"/> <img height="120" src="fern/images/skyvern_logo_blackbg.png"/> </picture> </a> <br /> </h1> <p align="center"> 🐉 Automate Browser-based workflows using LLMs and Computer Vision 🐉 </p> <p align="center"> <a href="https://www.skyvern.com/"><img src="https://img.shields.io/badge/Website-blue?logo=googlechrome&logoColor=black"/></a> <a href="https://www.skyvern.com/docs/"><img src="https://img.shields.io/badge/Docs-yellow?logo=gitbook&logoColor=black"/></a> <a href="https://discord.gg/fG2XXEuQX3"><img src="https://img.shields.io/discord/1212486326352617534?logo=discord&label=discord"/></a> <!-- <a href="https://pepy.tech/project/skyvern" target="_blank"><img src="https://static.pepy.tech/badge/skyvern" alt="Total Downloads"/></a> --> <a href="https://github.com/skyvern-ai/skyvern"><img src="https://img.shields.io/github/stars/skyvern-ai/skyvern" /></a> <a href="https://github.com/Skyvern-AI/skyvern/blob/main/LICENSE"><img src="https://img.shields.io/github/license/skyvern-ai/skyvern"/></a> <a href="https://twitter.com/skyvernai"><img src="https://img.shields.io/twitter/follow/skyvernai?style=social"/></a> <a href="https://www.linkedin.com/company/95726232"><img src="https://img.shields.io/badge/Follow%20 on%20LinkedIn-8A2BE2?logo=linkedin"/></a> </p>

Skyvern automates browser-based workflows using LLMs and computer vision. It provides a Playwright-compatible SDK that adds AI functionality on top of playwright, as well as a no-code workflow builder to help both technical and non-technical users automate manual workflows on any website, replacing brittle or unreliable automation solutions.

<p align="center"> <img src="fern/images/geico_shu_recording_cropped.gif"/> </p>

Traditional approaches to browser automations required writing custom scripts for websites, often relying on DOM parsing and XPath-based interactions which would break whenever the website layouts changed.

Instead of only relying on code-defined XPath interactions, Skyvern relies on Vision LLMs to learn and interact with the websites.

How it works

Skyvern was inspired by the Task-Driven autonomous agent design popularized by BabyAGI and AutoGPT -- with one major bonus: we give Skyvern the ability to interact with websites using browser automation libraries like Playwright.

Skyvern uses a swarm of agents to comprehend a website, and plan and execute its actions:

<picture> <source media="(prefers-color-scheme: dark)" srcset="fern/images/skyvern_2_0_system_diagram.png" /> <img src="fern/images/skyvern_2_0_system_diagram.png" /> </picture>

This approach has a few advantages:

  1. Skyvern can operate on websites it's never seen before, as it's able to map visual elements to actions necessary to complete a workflow, without any customized code
  2. Skyvern is resistant to website layout changes, as there are no pre-determined XPaths or other selectors our system is looking for while trying to navigate
  3. Skyvern is able to take a single workflow and apply it to a large number of websites, as it's able to reason through the interactions necessary to complete the workflow A detailed technical report can be found here.

Demo

<!-- Redo demo -->

https://github.com/user-attachments/assets/5cab4668-e8e2-4982-8551-aab05ff73a7f

Quickstart

Skyvern Cloud

Skyvern Cloud is a managed cloud version of Skyvern that allows you to run Skyvern without worrying about the infrastructure. It allows you to run multiple Skyvern instances in parallel and comes bundled with anti-bot detection mechanisms, proxy network, and CAPTCHA solvers.

If you'd like to try it out, navigate to app.skyvern.com and create an account.

Run Locally (UI + Server)

Choose your preferred setup method:

Database default: As of skyvern 1.0.31+, skyvern run server defaults to a SQLite database at ~/.skyvern/data.db so it works out of the box with no Postgres setup. To use Postgres instead, set DATABASE_STRING in .env or pass --database-string to skyvern quickstart. Docker Compose always uses the bundled Postgres service.

Option A: pip install (Recommended)

Dependencies needed:

Additionally, for Windows:

  • Rust
  • VS Code with C++ dev tools and Windows SDK

1. Install Skyvern

pip install skyvern

2. Run Skyvern

skyvern quickstart

Option B: Docker Compose

Use this option if you want everything containerized (Postgres, API, UI) and don't want to install Python/Node locally.

  1. Install Docker Desktop
  2. Clone the repository:
    git clone https://github.com/skyvern-ai/skyvern.git && cd skyvern
  3. Configure your LLM provider in .env (the quickstart --docker-compose command below will create it from .env.example if missing):
    cp .env.example .env  # if not already created
    # edit .env to add your LLM API key
  4. Start everything:
    docker compose up -d
  5. Open http://localhost:8080

Troubleshooting

(sqlite3.OperationalError) table organizations already exists — You hit a known bug in pip install skyvern==1.0.31. Fix:

rm ~/.skyvern/data.db   # remove the leftover SQLite file
pip install --upgrade skyvern   # 1.0.32+ contains the fix
skyvern quickstart

If you are still on 1.0.31 and cannot upgrade, install via uv instead:

uv pip install skyvern

pip install skyvern fails with ResolutionImpossible (litellm / fastmcp) — You hit a dependency-resolution conflict in 1.0.31. Either upgrade to 1.0.32+ or use uv: uv pip install skyvern.

SDK

Skyvern is a Playwright extension that adds AI-powered browser automation. It gives you the full power of Playwright with additional AI capabilities—use natural language prompts to interact with elements, extract data, and automate complex multi-step workflows.

Installation:

  • Python: pip install skyvern then run skyvern quickstart for local setup
  • TypeScript: npm install @skyvern/client

AI-Powered Page Commands

Skyvern adds four core AI commands directly on the page object:

CommandDescription
page.act(prompt)Perform actions using natural language (e.g., "Click the login button")
page.extract(prompt, schema)Extract structured data from the page with optional JSON schema
page.validate(prompt)Validate page state, returns bool (e.g., "Check if user is logged in")
page.prompt(prompt, schema)Send arbitrary prompts to the LLM with optional response schema

Additionally, page.agent provides higher-level workflow commands:

CommandDescription
page.agent.run_task(prompt)Execute complex multi-step tasks
page.agent.login(credential_type, credential_id)Authenticate with stored credentials (Skyvern, Bitwarden, 1Password)
page.agent.download_files(prompt)Navigate and download files
page.agent.run_workflow(workflow_id)Execute pre-built workflows

AI-Augmented Playwright Actions

All standard Playwright actions support an optional prompt parameter for AI-powered element location:

ActionPlaywrightAI-Augmented
Clickpage.click("#btn")page.click(prompt="Click login button")
Fillpage.fill("#email", "a@b.com")page.fill(prompt="Email field", value="a@b.com")
Selectpage.select_option("#country", "US")page.select_option(prompt="Country dropdown", value="US")
Uploadpage.upload_file("#file", "doc.pdf")page.upload_file(prompt="Upload area", files="doc.pdf")

Three interaction modes:

# 1. Traditional Playwright - CSS/XPath selectors
await page.click("#submit-button")

# 2. AI-powered - natural language
await page.click(prompt="Click the green Submit button")

# 3. AI fallback - tries selector first, falls back to AI if it fails
await page.click("#submit-btn", prompt="Click the Submit button")

Core AI Commands - Examples

# act - Perform actions using natural language
await page.act("Click the login button and wait for the dashboard to load")

# extract - Extract structured data with optional JSON schema
result = await page.extract("Get the product name and price")
result = await page.extract(
    prompt="Extract order details",
    schema={"order_id": "string", "total": "number", "items": "array"}
)

# validate - Check page state (returns bool)
is_logged_in = await page.validate("Check if the user is logged in")

# prompt - Send arbitrary prompts to the LLM
summary = await page.prompt("Summarize what's on this page")

Quick Start Examples

Run via UI:

skyvern run all

Navigate to http://localhost:8080 to run tasks through the web interface.

Python SDK:

from skyvern import Skyvern

# Local mode
skyvern = Skyvern.local()

# Or connect to Skyvern Cloud
skyvern = Skyvern(api_key="your-api-key")

# Launch browser and get page
browser = await skyvern.launch_cloud_browser()
page = await browser.get_working_page()

# Mix Playwright with AI-powered actions
await page.goto("https://example.com")
await page.click("#login-button")  # Traditional Playwright
await page.agent.login(credential_type="skyvern", credential_id="cred_123")  # AI login
await page.click(prompt="Add first item to cart")  # AI-augmented click
await page.agent.run_task("Complete checkout with: John Snow, 12345")  # AI task

TypeScript SDK:

import { Skyvern } from "@skyvern/client";

const skyvern = new Skyvern({ apiKey: "your-api-key" });
const browser = await skyvern.launchCloudBrowser();
const page = await browser.getWorkingPage();

// Mix Playwright with AI-powered actions
await page.goto("https://example.com");
await page.click("#login-button");  // Traditional Playwright
await page.agent.login("skyvern", { credentialId: "cred_123" });  // AI login
await page.click({ prompt: "Add first item to cart" });  // AI-augmented click
await page.agent.runTask("Complete checkout with: John Snow, 12345");  // AI task

await browser.close();

Simple task execution:

from skyvern import Skyvern

skyvern = Skyvern()
task = await skyvern.run_task(prompt="Find the top post on hackernews today")
print(task)

Advanced Usage

Control your own browser (Chrome)

Let Skyvern control your existing Chrome browser — with all your cookies, logins, and extensions.

Step 1: Enable remote debugging in Chrome

  1. Open Chrome and navigate to chrome://inspect/#remote-debugging
  2. Click Enable to start the debugging server
  3. You should see: Server running at: 127.0.0.1:9222

[!TIP] The skyvern init browser command can do this automatically — it opens chrome://inspect/#remote-debugging, waits for you to enable it, and saves the config.

Step 2: Connect Skyvern

Option A — Python Code:

from skyvern import Skyvern

skyvern = Skyvern(
    base_url="http://localhost:8000",
    api_key="YOUR_API_KEY",
    browser_address="http://127.0.0.1:9222",
)
task = await skyvern.run_task(
    prompt="Find the top post on hackernews today",
)

Option B — Skyvern Service:

Add two variables to your .env file:

BROWSER_TYPE=cdp-connect
BROWSER_REMOTE_DEBUGGING_URL=http://127.0.0.1:9222

Rest

View source on GitHub