docs: new cloud ui workflows + new captcha page (#4698)

Co-authored-by: Ritik Sahni <ritiksahni0203@gmail.com>
Co-authored-by: Suchintan <suchintan@users.noreply.github.com>
This commit is contained in:
Naman
2026-02-11 18:15:37 +05:30
committed by GitHub
parent 0c7b18cf56
commit 5e9c1f4f68
32 changed files with 1324 additions and 106 deletions

View File

@@ -0,0 +1,153 @@
---
title: Workflow Parameters
subtitle: Pass dynamic values into your workflows at runtime
slug: cloud/add-parameters
---
Parameters let you create reusable workflows that accept different input values each time they run. Instead of hardcoding a URL or search term into a block, reference a parameter and fill in the value when you run the workflow.
---
## Opening the parameters panel
In the [workflow editor](/cloud/build-a-workflow), click the **Parameters** button in the header bar. A panel appears below the header showing all defined parameters and controls to add new ones.
<img src="/images/cloud/parameters-panel-open.png" alt="Parameters panel" />
---
## Adding a parameter
Click **Add Parameter** in the panel. Two types are available:
| Type | Use for |
|------|---------|
| **Input Parameter** | Values the user provides when running the workflow (text, numbers, JSON, etc.) |
| **Credential Parameter** | Securely inject login credentials from a vault (Bitwarden, 1Password, Azure, AWS, or Skyvern) |
Each parameter requires a unique **key**. This is the name you use to reference it in blocks. Keys cannot contain spaces and cannot use [reserved names](#reserved-variables).
You can also add an optional **description** (shown as help text when running) and a **default value**.
---
## Parameter value types
Input parameters support these value types:
| Type | Input control | Example |
|------|---------------|---------|
| **String** | Text field | `"https://example.com"` |
| **Integer** | Number field | `10` |
| **Float** | Number field | `19.99` |
| **Boolean** | Toggle switch | `true` |
| **JSON** | Code editor | `{"key": "value"}` |
| **File URL** | Text field (paste a URL) | `"https://example.com/data.csv"` |
| **Credential ID** | Dropdown selector (shown at runtime) | Selected from stored credentials |
---
## Referencing parameters in blocks
Use Jinja2 double-brace syntax to reference parameters inside block fields like prompts, URLs, and data schemas.
**Basic reference:**
```
{{ url }}
```
**Nested field access** (for JSON parameters):
```
{{ config.search_term }}
```
**Convert to JSON string:**
```
{{ my_data | tojson }}
```
**Example in a Navigation block prompt:**
```
Navigate to {{ url }} and search for {{ search_term }}
```
Any block field that accepts text supports parameter references.
---
## Credential parameters
Credential parameters securely inject login credentials into blocks without exposing them in prompts or logs.
| Source | What it provides |
|--------|-----------------|
| **Skyvern Credential** | Username and password stored on the Skyvern Credentials page |
| **Bitwarden Login** | Username, password, and optional TOTP from your Bitwarden vault |
| **Bitwarden Credit Card** | Card number, holder name, expiry, and CVV from Bitwarden |
| **Bitwarden Sensitive Information** | Sensitive data fields from Bitwarden |
| **1Password** | Username, password, card data, or TOTP from 1Password |
| **Azure Key Vault** | Secrets stored in Azure Key Vault |
| **AWS Secret** | Secrets stored in AWS Secrets Manager |
| **Azure Secret** | Secrets stored in Azure Secret |
When you add a credential parameter, you configure the source and connection details (collection ID, vault ID, etc.). At runtime, Skyvern fetches the real credentials from the vault and injects them into the workflow. Credential values are masked in logs and outputs.
---
## Output parameters
Every block automatically produces an **output parameter** containing its results. You can reference a previous block's output in any downstream block.
The syntax uses the block's label (lowercased, spaces replaced with underscores) followed by `_output`:
```
{{ extraction_block_output.extracted_information }}
```
```
{{ login_output.success }}
```
This is how you chain data between blocks. Extract data in one block, then use it in the next.
---
## Reserved variables
These variable names are built-in and cannot be used as parameter keys:
| Variable | Available in | Description |
|----------|-------------|-------------|
| `current_value` | Loop blocks | The current item being iterated |
| `current_item` | Loop blocks | Alias for `current_value` |
| `current_index` | Loop blocks | Zero-based index of the current iteration |
| `workflow_run_id` | All blocks | Unique ID of the current run |
| `workflow_id` | All blocks | The workflow's ID |
| `workflow_permanent_id` | All blocks | The workflow's permanent ID |
| `workflow_title` | All blocks | The workflow's title |
**Example in a loop:**
```
Process item {{ current_index }}: {{ current_value.name }}
```
---
## What's next
<CardGroup cols={2}>
<Card
title="Block Reference"
icon="cube"
href="/cloud/configure-blocks"
>
Configuration fields for every block type
</Card>
<Card
title="Run Your Workflow"
icon="play"
href="/cloud/run-a-workflow"
>
Execute workflows and fill in parameter values
</Card>
</CardGroup>

View File

@@ -0,0 +1,298 @@
---
title: Build a Workflow
subtitle: Create multi-step automations with the visual workflow editor
slug: cloud/build-a-workflow
---
A task handles one goal on one page. When your automation needs multiple steps, you need a workflow. This page explains how workflows work, walks you through building one from scratch, and covers the editor's features.
## How workflows work
A workflow is a sequence of **blocks** that run one after another. Each block does one thing: navigate to a page, extract data, send an email, run custom code, loop, or branch. You connect blocks on a visual canvas, pass data between them, and run the whole chain with one click.
```
[Browser Task] → [Extraction] → [Loop] → [Send Email]
↓ ↓ ↓ ↓
opens the page JSON output per-item digest sent
processing
```
### How data flows between blocks
Every block produces an output. Downstream blocks reference it using the pattern `{{ block_label_output }}`.
For example, an Extraction block labeled `scrape_listings` produces output that later blocks access as `{{ scrape_listings_output }}`. This is how you chain steps together. One block's output becomes the next block's input.
### Block categories
| Category | What it does | Examples |
|----------|-------------|----------|
| **Browser Automation** | Interact with web pages using AI | Browser Task, Extraction, Browser Action, Login, File Download |
| **Data Processing** | Transform data without a browser | Text Prompt, File Parser, Code |
| **Control Flow** | Branch, loop, validate, or pause | Loop, Conditional, AI Validation, Wait |
| **Communication** | Send data to external services | Send Email, HTTP Request |
See [Block Reference](/cloud/configure-blocks) for every block type and its configuration fields.
<Tip>
If your block needs a browser, pick a browser automation block. If it just needs to process data, use Text Prompt or Code. If you need to repeat or branch, use control flow.
</Tip>
---
## Tutorial: Build a job listing tracker
Let's build a real workflow. You'll create an automation that finds the top 5 job listings from Hacker News's monthly "Who is Hiring" thread, summarizes each one, and emails you a digest.
This uses 5 blocks across 3 categories: browser automation, data processing, and communication.
<Steps>
<Step title="Create a new workflow">
Go to **Workflows** in the left sidebar and click **Create → Blank Workflow**.
<img src="/images/cloud/create-workflow-dropdown.png" alt="Create workflow dropdown showing Blank Workflow and From Template options" />
The editor opens with an empty canvas showing a single start node. Click the workflow title at the top left and rename it to **HN Job Tracker**.
</Step>
<Step title="Add a Browser Task block">
Hover over the **+** button on the edge below the start node and select **Add Block**. A searchable block library opens on the right. Find and select **Browser Task Block**.
The block appears on the canvas with a configuration panel on the right. Fill in:
| Field | Value |
|-------|-------|
| **Label** | `find_hiring_thread` |
| **URL** | `https://news.ycombinator.com` |
| **Prompt** | `Find and open the latest monthly "Ask HN: Who is hiring?" thread. The task is complete when the thread is open and job listing comments are visible.` |
The Browser Task block uses AI to navigate the page and accomplish the goal described in your prompt. Include your success criteria directly in the prompt so the AI knows when it's done.
<img src="/images/cloud/tutorial-browser-task.png" alt="Browser Task block configured with find_hiring_thread label, URL, and prompt" />
<Accordion title="Why Browser Task instead of Go to URL?">
The URL for the latest hiring thread changes every month. The Browser Task block uses AI to find the right link on the page. Use Go to URL when you know the exact destination URL upfront.
</Accordion>
</Step>
<Step title="Add an Extraction block">
Hover over the **+** on the edge after `find_hiring_thread`, select **Add Block**, then choose **Extraction Block**.
Configure:
| Field | Value |
|-------|-------|
| **Label** | `scrape_listings` |
| **Data Extraction Goal** | `Extract the top 5 job listings. For each listing, get the company name, role title, and a brief description of the position.` |
Now enable the **Data Schema** checkbox to reveal the JSON editor, and paste:
```json
{
"type": "object",
"properties": {
"listings": {
"type": "array",
"items": {
"type": "object",
"properties": {
"company": { "type": "string" },
"role": { "type": "string" },
"description": { "type": "string" }
}
}
}
}
}
```
The schema tells Skyvern exactly what structure to return. Without it, the AI picks its own format. You can also click **Generate with AI** next to the schema field to have Skyvern suggest a schema based on your extraction goal.
<img src="/images/cloud/tutorial-extraction.png" alt="Extraction block configured with scrape_listings label, extraction goal, Data Schema checkbox enabled, and JSON schema" />
<Tip>
Label your blocks descriptively. The label determines the output variable name. `scrape_listings` means downstream blocks reference its data as `{{ scrape_listings_output }}`.
</Tip>
</Step>
<Step title="Add a Loop with a Text Prompt inside">
Hover over the **+** after `scrape_listings`, select **Add Block**, then choose **Loop Block**.
Configure the loop:
| Field | Value |
|-------|-------|
| **Label** | `process_each` |
| **Loop Value** | `{{ scrape_listings_output.listings }}` |
This iterates over the 5 listings extracted in the previous step. Now add a block *inside* the loop. Hover over the **+** inside the loop body, select **Add Block**, and choose **Text Prompt Block**.
Configure the Text Prompt:
| Field | Value |
|-------|-------|
| **Label** | `summarize` |
| **Prompt** | `Summarize this job listing in one sentence. Company: {{ current_value.company }}, Role: {{ current_value.role }}, Description: {{ current_value.description }}` |
Enable the **Data Schema** checkbox and paste:
```json
{
"type": "object",
"properties": {
"summary": { "type": "string" }
}
}
```
The Text Prompt block sends text to the LLM without opening a browser. It processes data only. Each iteration produces a one-line summary of that job listing.
<img src="/images/cloud/tutorial-loop-text-prompt.png" alt="Loop block with process_each label containing a summarize Text Prompt block inside" />
<Accordion title="What are current_value and current_index?">
Inside a loop, two reserved variables are available:
- `{{ current_value }}`: the current item from the list being iterated
- `{{ current_index }}`: the item's position, starting from 0
These only exist inside loop blocks. In this example, `{{ current_value.company }}` gives you the company name for the current listing.
</Accordion>
</Step>
<Step title="Add a Send Email block">
Hover over the **+** on the edge *after* the loop (back on the main flow, not inside it), select **Add Block**, then choose **Send Email Block**.
Configure:
| Field | Value |
|-------|-------|
| **Label** | `send_digest` |
| **Recipients** | Your email address |
| **Subject** | `HN Job Digest - Top 5 Listings` |
| **Body** | `Here are today's top job listings from Hacker News:\n\n{{ process_each_output }}` |
The `{{ process_each_output }}` reference pulls in the collected summaries from every loop iteration.
</Step>
<Step title="Save and run">
<Warning>
Workflows are **not** auto-saved. Click the **Save** button (disk icon) in the header bar before navigating away or you'll lose your work.
</Warning>
Click **Save**, then click **Run** in the top right. A parameters page opens where you can review and confirm the workflow's settings. Click **Run Workflow** to start execution.
The [live execution view](/cloud/monitor-a-run) opens. Watch as Skyvern navigates Hacker News, extracts listings, summarizes each one, and sends your email.
</Step>
</Steps>
### What you built
```
[find_hiring_thread] → [scrape_listings] → [process_each (loop)] → [send_digest]
Browser Task Extraction └─ [summarize] Send Email
Text Prompt
```
Five blocks, three categories, zero code. You can now re-run this workflow anytime, tweak the extraction schema to pull different fields, swap the email for an HTTP Request to post to Slack, or add a Conditional block to only email when listings match certain criteria.
---
## Editor reference
### Layout
<img src="/images/cloud/workflow-editor-overview.png" alt="Workflow editor overview" />
| Area | What it shows |
|------|---------------|
| **Header bar** (top) | Workflow title (click to rename), Parameters button, Save button, Template toggle, History button, Run button |
| **Canvas** (center) | Visual graph of blocks connected in sequence. Zoom with the scroll wheel, pan by dragging the background. |
| **Configuration panel** (right) | Opens when you click a block. Shows that block's settings form. |
### Adding blocks
Hover over the **+** button on any edge (the connecting line between blocks) to reveal the menu. Select **Add Block** to open the block library, a searchable list of all available block types. Click a block to insert it at that position.
The menu also offers **Record Browser** (record actions in a live browser to generate blocks) and **Upload SOP** (upload a PDF procedure to auto-generate a workflow).
When you create a blank workflow, hover over the **+** on the start edge to add your first block.
<img src="/images/cloud/add-block-panel.png" alt="Add block panel" />
### Configuring blocks
Click any block on the canvas to open its configuration panel on the right. Each block has a **Label** field (which determines its output variable name) and block-specific settings. Browser-based blocks share additional fields like URL, Engine, and Max Retries.
See [Block Reference](/cloud/configure-blocks) for the full list of fields on each block type.
### Connecting and reordering blocks
Blocks auto-connect when you insert them via the **+** button. They execute top to bottom in the order shown on the canvas.
**Conditional blocks** create branches. Each branch connects to a different sequence of blocks and merges back at a common point.
**Loop blocks** contain child blocks that repeat for each item in the loop's list.
To reorder blocks, delete the block you want to move and re-add it at the desired position using the **+** button.
### Deleting blocks
Click the **three-dot menu** on a block's header and select **Delete Block**. Downstream blocks reconnect to the previous block automatically.
### Saving
<Warning>
Workflows are **not** auto-saved. Click the **Save** button (disk icon) in the header bar to persist your changes. The editor warns you if you try to navigate away with unsaved work.
</Warning>
The **Run** button also saves before starting execution.
### Header bar actions
| Button | Description |
|--------|-------------|
| **Save** (disk icon) | Save the current workflow definition |
| **Template** (bookmark icon) | Toggle whether this workflow is saved as an organization template |
| **History** (clock icon) | View past runs of this workflow |
| **Parameters** | Open the parameters panel (see [Workflow Parameters](/cloud/add-parameters)) |
| **Run** (play icon) | Save and start a new execution (see [Running Workflows](/cloud/run-a-workflow)) |
---
## What's next
<CardGroup cols={3}>
<Card
title="Block Reference"
icon="cube"
href="/cloud/configure-blocks"
>
Configuration fields for every block type
</Card>
<Card
title="Add Parameters"
icon="sliders"
href="/cloud/add-parameters"
>
Pass dynamic values into your workflows
</Card>
<Card
title="Run Your Workflow"
icon="play"
href="/cloud/run-a-workflow"
>
Execute workflows and track results
</Card>
</CardGroup>

View File

@@ -0,0 +1,361 @@
---
title: Block Types and Configuration
subtitle: Reference for every block available in the workflow editor
slug: cloud/configure-blocks
---
Workflows are built from blocks. Each block performs one specific operation: navigating a page, extracting data, making an API call, or branching logic. This page covers every block type available in the [editor](/cloud/build-a-workflow), grouped by category.
## Quick reference
| Category | Blocks |
|----------|--------|
| [Browser Automation](#browser-automation) | Browser Task, Browser Action, Extraction, Login, Go to URL, Print Page |
| [Data and Extraction](#data-and-extraction) | Text Prompt, File Parser |
| [Control Flow](#control-flow) | Loop, Conditional, AI Validation, Code, Wait |
| [Files](#files) | File Download, Cloud Storage Upload |
| [Communication](#communication) | Send Email, HTTP Request, Human Interaction |
---
## Common fields
These fields appear on most blocks:
| Field | Description |
|-------|-------------|
| **Label** | Display name on the canvas. Also determines how downstream blocks reference this block's output (`{{ label_output }}`). |
| **Continue on Failure** | Allow the workflow to continue if this block fails |
| **Next Loop on Failure** | Only inside loops. Skip to the next iteration on failure. |
| **Model** | Override the default LLM model for this block (Advanced Settings on most blocks) |
Browser-based blocks (Browser Task, Browser Action, Extraction, Login, File Download) share these additional fields:
| Field | Description |
|-------|-------------|
| **URL** | Starting URL. Leave blank to continue from the previous block's page. |
| **Engine** | AI engine: Skyvern 1.0 or Skyvern 2.0 |
| **Max Steps Override** | Cap the number of AI reasoning steps |
| **Disable Cache** | Skip cached script execution |
| **TOTP Identifier** | Link TOTP credentials for 2FA handling |
| **TOTP Verification URL** | Endpoint for fetching TOTP codes |
| **Error Code Mapping** | Map error conditions to custom error codes (JSON) |
---
## Browser Automation
### Browser Task
The primary block for browser automation. Accepts a natural-language prompt and autonomously navigates the browser to accomplish the goal.
The block has two engine modes, selected via the **Engine** dropdown. The fields shown change depending on which engine you choose.
**Skyvern 2.0** (recommended):
| Field | Type | Description |
|-------|------|-------------|
| **URL** | text | Starting URL (optional) |
| **Prompt** | text | Natural language instructions for the AI |
| **Max Steps** | number | Maximum AI steps |
| **Disable Cache** | boolean | Skip cached script execution |
**Skyvern 1.0:**
| Field | Type | Description |
|-------|------|-------------|
| **URL** | text | Starting URL (optional) |
| **Prompt** | text | Natural language instructions for the AI |
Additional fields in **Advanced Settings** (Skyvern 1.0 only):
| Field | Type | Description |
|-------|------|-------------|
| **Complete if...** | text | Condition that signals the block is done |
| **Include Action History in Verification** | boolean | Include prior actions when verifying completion |
| **Complete on Download** | switch | Mark the block as complete when a file download occurs |
| **File Name** | text | Custom filename for downloaded files |
*Plus [common browser fields](#common-fields).*
<Tip>
Browser Task is the recommended block for most browser automation. Use it for anything from form filling to multi-page navigation. Include your success criteria directly in the prompt so the AI knows when it's done.
</Tip>
### Browser Action
Execute a single browser action. Best for precise, one-step operations like clicking a specific button or entering text in a field.
| Field | Type | Description |
|-------|------|-------------|
| **URL** | text | Starting URL (optional) |
| **Action Instruction** | text | Specify the single action to perform |
Additional fields in **Advanced Settings:**
| Field | Type | Description |
|-------|------|-------------|
| **Complete on Download** | switch | Mark the block as complete when a file download occurs |
| **File Name** | text | Custom filename for downloaded files |
*Plus [common browser fields](#common-fields).*
### Extraction
Extract structured data from the current page using AI.
| Field | Type | Description |
|-------|------|-------------|
| **Data Extraction Goal** | text | What data to extract |
| **Data Schema** | JSON | [JSON Schema](https://json-schema.org/) defining the output format. Enable the checkbox to reveal the editor. Click **Generate with AI** to auto-suggest a schema from your extraction goal. |
*Plus [common browser fields](#common-fields).*
### Login
Authenticate to a website using stored credentials. Pre-filled with a default login goal that handles common login flows including 2FA.
| Field | Type | Description |
|-------|------|-------------|
| **URL** | text | Login page URL |
| **Login Goal** | text | Login instructions (pre-filled with a comprehensive default) |
| **Credential** | selector | Select stored credentials for authentication |
Additional fields in **Advanced Settings:**
| Field | Type | Description |
|-------|------|-------------|
| **Complete if...** | text | How to know login succeeded |
*Plus [common browser fields](#common-fields).*
### Go to URL
Navigate the browser directly to a specific URL without AI interaction.
| Field | Type | Description |
|-------|------|-------------|
| **URL** | text | **(Required)** The URL to navigate to. Supports [parameter references](/cloud/add-parameters#referencing-parameters-in-blocks). |
### Print Page
Print the current browser page to a PDF file. The PDF is saved as a downloadable artifact.
| Field | Type | Description |
|-------|------|-------------|
| **Page Format** | select | Paper size: A4, Letter, Legal, or Tabloid |
| **Print Background** | boolean | Include CSS background colors and images in the PDF |
| **Headers & Footers** | boolean | Add date, title, URL, and page numbers to the PDF |
Additional fields in **Advanced Settings:**
| Field | Type | Description |
|-------|------|-------------|
| **Custom Filename** | text | Custom name for the generated PDF |
| **Landscape** | boolean | Use landscape orientation |
---
## Data and Extraction
### Text Prompt
Send text to the LLM for processing without browser interaction. Useful for summarizing, transforming, or analyzing data between browser steps.
| Field | Type | Description |
|-------|------|-------------|
| **Prompt** | text | The text prompt to send to the LLM |
| **Model** | selector | Which LLM model to use |
| **Data Schema** | JSON | Expected output structure. Enable the checkbox to reveal the editor. Click **Generate with AI** to auto-suggest a schema. |
### File Parser
Parse PDFs, CSVs, Excel files, and images to extract structured data.
| Field | Type | Description |
|-------|------|-------------|
| **File URL** | text | URL or parameter reference to the file |
| **Data Schema** | JSON | Schema for the extracted output. Enable the checkbox to reveal the editor. |
| **Model** | selector | Which LLM model to use |
---
## Control Flow
### Loop
Repeat a sequence of blocks for each item in a list. Child blocks are placed inside the loop on the canvas.
| Field | Type | Description |
|-------|------|-------------|
| **Loop Value** | text | The list to iterate over. Use a parameter reference (e.g., `{{ my_list }}`) or a natural language description (e.g., "Extract links of the top 5 posts") which triggers automatic extraction. |
| **Continue if Empty** | boolean | Mark the loop as complete if the list is empty |
Inside loop blocks, use these [reserved variables](/cloud/add-parameters#reserved-variables):
- `{{ current_value }}`: the current item
- `{{ current_index }}`: the iteration number (0-based)
<img src="/images/cloud/block-loop-config.png" alt="Loop block configuration" />
### Conditional
Branch the workflow based on conditions. The UI shows branches as tabs (A, B, C, etc.). Each branch has an expression that determines when it executes. Expressions can be Jinja2 templates or natural language prompts.
| Field | Type | Description |
|-------|------|-------------|
| **Branches** | tabs | One or more conditions. Each branch has an **Expression** field. Click **+** to add branches. |
| **Else branch** | auto | Automatically added. Executes when no other condition matches. |
**Example Jinja2 expression:**
```
{{ extraction_output.price > 100 }}
```
<img src="/images/cloud/block-conditional-config.png" alt="Conditional block configuration" />
### AI Validation
Assert conditions using AI and halt the workflow on failure. Useful for checking that a previous block produced expected results before continuing.
| Field | Type | Description |
|-------|------|-------------|
| **Complete if...** | text | Condition that means validation passed |
| **Terminate if...** | text | Condition that means validation failed |
Additional fields in **Advanced Settings:**
| Field | Type | Description |
|-------|------|-------------|
| **Error Code Mapping** | JSON | Custom error codes for failure reasons |
| **Input Parameters** | select | Parameters to evaluate |
### Code
Execute custom Python code. Input parameters are available as global variables. Top-level variables in your code become the block's output.
| Field | Type | Description |
|-------|------|-------------|
| **Code** | code editor | Python code to execute |
| **Input Parameters** | select | Parameters available as globals in the code |
### Wait
Pause workflow execution for a specified duration.
| Field | Type | Description |
|-------|------|-------------|
| **Wait in Seconds** | number | Seconds to wait (0300) |
---
## Files
### File Download
Navigate the browser to download a file.
| Field | Type | Description |
|-------|------|-------------|
| **URL** | text | Starting URL (optional) |
| **Download Goal** | text | Instructions for finding and downloading the file |
| **Download Timeout (sec)** | number | Seconds to wait for the download to complete |
Additional fields in **Advanced Settings:**
| Field | Type | Description |
|-------|------|-------------|
| **File Name** | text | Custom filename for the download |
*Plus [common browser fields](#common-fields).*
### Cloud Storage Upload
Upload downloaded files to S3 or Azure Blob Storage.
| Field | Type | Description |
|-------|------|-------------|
| **Storage Type** | select | `Amazon S3` or `Azure Blob Storage` |
| **Folder Path** | text | Upload path/prefix (optional) |
<Accordion title="S3 fields">
| Field | Description |
|-------|-------------|
| **S3 Bucket** | Bucket name |
| **AWS Access Key ID** | AWS credential |
| **AWS Secret Access Key** | AWS credential |
| **Region Name** | AWS region |
</Accordion>
<Accordion title="Azure fields">
| Field | Description |
|-------|-------------|
| **Storage Account Name** | Storage account name |
| **Storage Account Key** | Storage account key |
| **Blob Container Name** | Container name |
</Accordion>
---
## Communication
### Send Email
Send an email notification, optionally with file attachments from previous blocks.
| Field | Type | Description |
|-------|------|-------------|
| **Recipients** | text | Comma-separated email addresses |
| **Subject** | text | Email subject line |
| **Body** | text | Email body. Supports [parameter references](/cloud/add-parameters#referencing-parameters-in-blocks). |
| **File Attachments** | text | Path to files to attach |
### HTTP Request
Make an API call to an external service. Click **Import cURL** in the block header to populate fields from a cURL command.
| Field | Type | Description |
|-------|------|-------------|
| **Method** | select | GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS |
| **URL** | text | Request URL. Supports parameter references. |
| **Headers** | JSON | HTTP headers. Use **Quick Headers** to add common headers. |
| **Body** | JSON | Request body (POST/PUT/PATCH only) |
| **Files** | JSON | File uploads (POST/PUT/PATCH only) |
Additional fields in **Advanced Settings:**
| Field | Type | Description |
|-------|------|-------------|
| **Timeout** | number | Request timeout in seconds (1300, default: 30) |
| **Follow Redirects** | boolean | Automatically follow HTTP redirects (default: true) |
| **Continue on Failure** | boolean | Continue workflow if the request fails |
| **Save Response as File** | boolean | Save the response body as a downloadable file |
| **Download Filename** | text | Filename for the saved response (shown when Save Response as File is enabled) |
### Human Interaction
Pause the workflow and request human input. Optionally sends an email notification to reviewers.
| Field | Type | Description |
|-------|------|-------------|
| **Instructions For Human** | text | Instructions displayed to the reviewer |
| **Timeout (minutes)** | number | Minutes to wait before auto-continuing (default: 120 minutes / 2 hours) |
**Email notification fields:**
| Field | Type | Description |
|-------|------|-------------|
| **Recipients** | text | Email addresses to notify (comma-separated) |
| **Subject** | text | Notification email subject |
| **Body** | text | Notification email body |
Additional fields in **Advanced Settings:**
| Field | Type | Description |
|-------|------|-------------|
| **Positive Button Label** | text | Label for the approval action (default: "Approve") |
| **Negative Button Label** | text | Label for the rejection action (default: "Reject") |

View File

@@ -0,0 +1,106 @@
---
title: Managing Workflows
subtitle: Create, organize, clone, import, and export reusable automations
slug: cloud/manage-workflows
---
Once you've [built a workflow](/cloud/build-a-workflow), the **Workflows** page is where you organize, share, and manage them. Each workflow is a reusable sequence of blocks that you can run with different inputs each time.
Click **Workflows** in the left sidebar to open it.
<img src="/images/cloud/workflows-page-overview.png" alt="Workflows page overview" />
---
## The workflows table
The table lists all workflows in your organization with the following columns:
| Column | Description |
|--------|-------------|
| **ID** | Unique workflow identifier |
| **Title** | Display name (click to open in the editor) |
| **Folder** | Folder assignment, if any |
| **Created At** | When the workflow was created |
| **Actions** | Inline buttons and three-dot menu |
Each row also has inline action buttons: folder assignment, parameter toggle, open in editor (pencil icon), run (play icon), and a three-dot menu for additional actions.
---
## Organizing with folders
The top of the page shows your recent folders as cards. Use folders to group related workflows.
- Click **+ New folder** to create one
- Click a folder card to filter the table to that folder's workflows
- Assign a workflow to a folder using the folder icon in the table row
- Click **View all** to see all folders when you have more than five
<img src="/images/cloud/workflow-folders.png" alt="Workflow folders" />
---
## Searching and filtering
Use the search bar above the table to filter workflows by title or parameter. The results highlight matching text and auto-expand parameter rows when a parameter matches.
The items-per-page selector at the bottom lets you choose 5, 10, 20, or 50 rows per page.
---
## Workflow actions
Click the **three-dot menu** on any workflow row to access these actions:
| Action | What it does |
|--------|-------------|
| **Clone Workflow** | Creates a copy named "Copy of ..." with the original title |
| **Save as Template** | Makes this workflow available in the organization template gallery. A bookmark icon appears next to the title. |
| **Remove from Templates** | Removes the workflow from the template gallery (appears instead of "Save as Template" for templates) |
| **Export as... > YAML** | Downloads the workflow definition as a `.yaml` file |
| **Export as... > JSON** | Downloads the workflow definition as a `.json` file |
| **Delete Workflow** | Opens a confirmation dialog, then permanently deletes the workflow |
<img src="/images/cloud/workflow-actions-menu.png" alt="Workflow actions menu" />
<Warning>
Deleting a workflow is permanent. Clone it first if you want to keep a backup.
</Warning>
---
## Importing workflows
Click the **Import** button to upload workflow files.
| Format | Behavior |
|--------|----------|
| `.yaml` / `.yml` | Parsed and created as a new workflow |
| `.json` | Converted to YAML internally, then created |
| `.pdf` | Sent to the AI to generate a workflow from a Standard Operating Procedure document |
<Tip>
Upload a PDF of your Standard Operating Procedure and Skyvern generates a workflow from it automatically.
</Tip>
---
## What's next
<CardGroup cols={2}>
<Card
title="Open the Editor"
icon="pen-to-square"
href="/cloud/build-a-workflow"
>
Build automations visually with the drag-and-drop canvas
</Card>
<Card
title="Add Parameters"
icon="sliders"
href="/cloud/add-parameters"
>
Make workflows reusable with dynamic input values
</Card>
</CardGroup>

View File

@@ -0,0 +1,92 @@
---
title: Watching Live Execution
subtitle: Monitor, interact with, and control running tasks
slug: cloud/monitor-a-run
---
When you run a task from the [Discover page](/cloud/run-a-task), you're taken to the live execution screen where you can watch the browser in real time.
<img src="/images/cloud/live-execution-overview.png" alt="Live execution screen" />
---
## The execution screen
The execution view has three panels:
| Panel | What it shows |
|-------|---------------|
| **Left: Task configuration** | The block being executed, its URL, and prompt. A status badge shows the current state. |
| **Center: Live browser** | Real-time view of the browser. You see pages load, forms fill, and buttons click. |
| **Right: Agent logs** | Real-time LLM reasoning and action decisions. Shows why the AI made each choice. |
---
## When the live view is available
The live browser stream is active while the task is still in progress:
| Status | Live view |
|--------|-----------|
| `created` | Waiting to start |
| `queued` | Waiting for a browser |
| `running` | **Active**: the browser is navigating |
| `paused` | Waiting for human interaction |
| `completed` | Stream closed. View the recording instead. |
| `failed` | Stream closed. View the recording instead. |
| `terminated` | Stream closed |
| `timed_out` | Stream closed |
| `canceled` | Stream closed |
Once a task reaches a final state, the live stream closes. Open the run from **Runs** in the sidebar to access the full recording, screenshots, and action history.
---
## Taking control of the browser
The **Take Control** button lets you interact directly with the browser. This is useful when:
- A CAPTCHA appears that the AI can't solve
- The site has an unusual login flow
- You need to navigate past an unexpected popup
Click **Take Control** to start interacting. Your mouse and keyboard input goes directly to the browser. Click **Stop Controlling** to hand control back to the AI.
<Warning>
Taking control pauses the AI agent. Remember to release control so the agent can resume.
</Warning>
---
## Stopping a running task
You can cancel a task at any time while it's running or queued. Click the **Cancel** button in the task header. A confirmation dialog appears before the task is stopped. The task transitions to `canceled` and any configured webhook fires with the canceled status.
---
## Reviewing results
Once a task finishes, open it from **Runs** to see the full results.
### Actions tab
Step-by-step breakdown of every action the AI took. Each entry shows:
- **Action type**: Click, Type, Scroll, Select, etc.
- **Success or failure** indicator
- **AI reasoning**: Why the agent chose this action
- **Input details**: For type actions, the text that was entered
### Recording tab
Full video replay of the browser session. Every task is recorded automatically.
### Parameters tab
The configuration you submitted: URL, prompt, engine, proxy location, webhook URL, data schema, and other settings.
### Diagnostics tab
Debug information for troubleshooting:
- **LLM prompts**: The exact prompts sent to the AI model
- **Element trees**: The DOM structure the AI analyzed
- **Annotated screenshots**: Screenshots with element labels the AI used for decisions

View File

@@ -1,10 +1,10 @@
---
title: UI Overview
slug: cloud/ui-overview
slug: cloud/overview
subtitle: Navigate the Skyvern Cloud dashboard
---
Skyvern Cloud ([app.skyvern.com](https://app.skyvern.com)) lets you automate any website from your browser. Describe what you want in plain English, watch an AI-powered browser do it live, and get structured results back — no code required.
Skyvern Cloud ([app.skyvern.com](https://app.skyvern.com)) lets you automate any website from your browser. Describe what you want in plain English, watch an AI-powered browser do it live, and get structured results back. No code required.
<Note>
Looking to integrate Skyvern into your own app? See the [API Quickstart](/getting-started/quickstart) instead.
@@ -12,7 +12,7 @@ Looking to integrate Skyvern into your own app? See the [API Quickstart](/gettin
## The dashboard
Sign in and you'll land on the **Discover** page the starting point for running automations.
Sign in and you'll land on the **Discover** page, the starting point for running automations.
<img src="/images/cloud/skyvern-cloud-discover.png" alt="Skyvern Cloud dashboard showing the Discover page" />
@@ -34,7 +34,7 @@ Where you create and monitor automations.
{/* TODO: Replace with screenshot of Agents section */}
<img src="/images/cloud/placeholder-agents-section.png" alt="Agents page showing pre-built automation templates" />
Ready-made automation templates. Each agent is preconfigured with a prompt, target URL, and settings — pick one to see it work or use it as a starting point for your own task.
Ready-made automation templates. Each agent is preconfigured with a prompt, target URL, and settings. Pick one to see it work or use it as a starting point for your own task.
### General
@@ -50,10 +50,10 @@ Every automation in Skyvern Cloud follows the same pattern:
<Steps>
<Step title="Describe your task">
Type what you want into the prompt bar — include the target URL and your instructions in one go. Something like "Get the top post from https://news.ycombinator.com" or "Fill out the contact form at https://example.com/contact with my details."
Type what you want into the prompt bar. Include the target URL and your instructions in one go. Something like "Get the top post from https://news.ycombinator.com" or "Fill out the contact form at https://example.com/contact with my details."
</Step>
<Step title="Watch it happen">
A cloud browser opens and you see it navigate in real time. Pages load, elements highlight, actions fire. An agent log streams the AI's reasoning every Thought and Decision so you can follow along. If the AI gets stuck, hit **Take Control** to jump in and help.
A cloud browser opens and you see it navigate in real time. Pages load, elements highlight, actions fire. An agent log streams the AI's reasoning, showing every Thought and Decision, so you can follow along. If the AI gets stuck, hit **Take Control** to jump in and help.
</Step>
<Step title="Get your results">
Extracted data appears as structured JSON on the run detail page. Every run also includes an output view, full recording, the parameters you submitted, and auto-generated code to reproduce the task via API.
@@ -70,7 +70,7 @@ That's it. The next guide walks you through this flow with a real example.
<Card
title="Run Your First Task"
icon="play"
href="/cloud/your-first-task"
href="/cloud/run-your-first-task"
>
Follow along with a real example to see Skyvern Cloud in action
</Card>

144
docs/cloud/run-a-task.mdx Normal file
View File

@@ -0,0 +1,144 @@
---
title: The Discover Page
subtitle: Run ad-hoc browser automations with natural language
slug: cloud/run-a-task
---
The **Discover** page is where you run one-off browser automations. Type what you want done in plain language, and Skyvern opens a browser and does it for you.
<img src="/images/cloud/discover-page-overview.png" alt="Discover page overview" />
---
## The prompt box
Type a natural language instruction describing what you want automated. Be specific about the goal and any data you want extracted.
**Examples:**
- "Go to amazon.com and find the price of the MacBook Air M4"
- "Fill out the contact form at example.com/contact with name John Doe and email john@example.com"
- "Get an insurance quote from geico.com for a 2020 Toyota Camry"
<img src="/images/cloud/prompt-box-filled.png" alt="Prompt box with a sample prompt" />
Click the **send button** or press **Enter** to start.
Below the prompt box, **quick-action buttons** offer pre-built examples like "Add a product to cart" or "Get an insurance quote." Click one to run it immediately or use it as a starting point.
---
## Choosing an engine
The dropdown next to the send button controls which engine runs the task.
| Engine | Best for |
|--------|----------|
| **Skyvern 2.0 with Code** | Complex, multi-step tasks. Generates reusable scripts. **(Default)** |
| **Skyvern 2.0** | Complex tasks without script generation |
| **Skyvern 1.0** | Simple, single-objective tasks. Faster and cheaper. |
<Tip>
Start with the default. Switch to Skyvern 1.0 when you have a straightforward, single-page task and want faster execution.
</Tip>
---
## Advanced settings
Click the **gear icon** next to the prompt box to expand the settings panel.
<img src="/images/cloud/advanced-settings-panel.png" alt="Advanced settings panel" />
| Setting | What it does |
|---------|-------------|
| **Proxy Location** | Route the browser through a residential proxy in a specific country. Default is `RESIDENTIAL` (US). Set to `NONE` to disable. Available: US, UK, Germany, France, Spain, Ireland, India, Japan, Australia, Canada, Brazil, Mexico, Argentina, New Zealand, South Africa, Italy, Netherlands, Philippines, Turkey. |
| **Webhook URL** | URL that receives a POST request when the task finishes. The payload includes status, extracted data, screenshots, and recording URL. |
| **Browser Session ID** | Run inside an existing persistent browser session (`pbs_xxx`). Preserves cookies and login state across multiple tasks. |
| **CDP Address** | Connect to your own browser via Chrome DevTools Protocol (e.g., `http://127.0.0.1:9222`). For local development. |
| **2FA Identifier** | Links your TOTP credentials to this task. Skyvern uses it to retrieve the correct code when a 2FA prompt appears. |
| **Extra HTTP Headers** | Custom headers sent with every browser request, as JSON (e.g., `{"Authorization": "Bearer token"}`). |
| **Publish Workflow** | Save a reusable workflow alongside the task run. Re-run the same automation later from the Workflows page. |
| **Max Steps Override** | Cap the number of AI reasoning steps. Each step = one screenshot-analyze-act cycle. Useful for controlling cost during development. |
| **Max Screenshot Scrolls** | Number of scrolls for post-action screenshots. Increase for pages with lazy-loaded content. `0` = viewport only. |
---
## Data extraction schema
The **Data Schema** field in advanced settings lets you define the structure of extracted output as [JSON Schema](https://json-schema.org/).
Without a schema, the AI returns data in whatever format it chooses. With a schema, output conforms to your structure, making it predictable for downstream use.
<img src="/images/cloud/data-schema-field.png" alt="Data schema field with JSON" />
```json
{
"type": "object",
"properties": {
"product_name": {
"type": "string",
"description": "The name of the product"
},
"price": {
"type": "number",
"description": "The price in USD"
},
"in_stock": {
"type": "boolean",
"description": "Whether the product is in stock"
}
}
}
```
Use the `description` field on each property to guide the AI on what to extract.
<Accordion title="Example: Extracting a list of items">
```json
{
"type": "object",
"properties": {
"quotes": {
"type": "array",
"items": {
"type": "object",
"properties": {
"premium_amount": {
"type": "string",
"description": "Total premium in USD (e.g., '$321.57')"
},
"coverage_type": {
"type": "string",
"description": "Type of coverage (e.g., 'Full Coverage')"
},
"deductible": {
"type": "string",
"description": "Deductible amount"
}
}
}
}
}
}
```
</Accordion>
---
## Workflow templates
Below the prompt box, the Discover page shows a gallery of **workflow templates**: pre-built automations for common use cases.
<img src="/images/cloud/workflow-templates.png" alt="Workflow template gallery" />
Click any template to launch it with pre-filled configuration, or use it as a starting point and customize.
---
## What happens next
1. Your prompt is sent to Skyvern
2. A cloud browser opens and navigates to the target URL (or finds one from your prompt)
3. The AI analyzes the page, plans actions, and executes them step by step
4. You're taken to the [live execution view](/cloud/monitor-a-run) where you can watch it happen in real time
5. When complete, results appear on the run detail page under **Runs**

View File

@@ -0,0 +1,107 @@
---
title: Running Workflows
subtitle: Execute workflows, fill parameters, and track status
slug: cloud/run-a-workflow
---
Once you've built and saved a workflow, you can run it from the editor or the workflows list. Each run creates an independent execution with its own status, logs, and output.
## Starting a run
Two ways to start:
1. **From the editor**: Click the **Run** button (play icon) in the header bar. The editor saves your workflow first.
2. **From the workflows list**: Click the **play icon** on the workflow's row.
Both take you to the parameters page where you fill in runtime values before the run starts.
## Filling in parameters
The parameters page shows all [workflow parameters](/cloud/add-parameters) defined in the editor. Fill in a value for each one, or leave them at their defaults. Parameters without defaults must be filled in before running.
## Run settings
Below the parameters, you can configure settings for this specific run:
| Setting | Description |
|---------|-------------|
| **Proxy Location** | Route browser traffic through a proxy in a specific country. Default: US Residential. |
| **Webhook Callback URL** | URL that receives a POST request when the run completes |
| **Max Screenshot Scrolls** | Override screenshot scroll depth for this run |
| **Extra HTTP Headers** | Custom headers included in all browser requests (JSON) |
| **CDP Address** | Connect to your own browser for local development |
---
## Monitoring a run
After clicking **Run**, you're taken to the live execution view, the same interface described in [Watching Live Execution](/cloud/monitor-a-run).
For workflows, the left panel also shows a **block timeline**: a list of all blocks in the workflow. Completed blocks show a checkmark. The currently executing block is highlighted.
<img src="/images/cloud/workflow-run-timeline.png" alt="Workflow run block timeline" />
---
## Run statuses
| Status | Description |
|--------|-------------|
| `created` | Run initialized |
| `queued` | Waiting for an available browser |
| `running` | Blocks are executing |
| `completed` | All blocks finished successfully |
| `failed` | A block failed and the workflow stopped |
| `canceled` | You canceled the run |
| `timed_out` | The run exceeded its time limit |
| `terminated` | The run was terminated by the system |
---
## Viewing results
After a run completes, open it from **Runs** in the sidebar. The run detail page shows:
- **Block-by-block results**: Each block's output, status, and execution time
- **Recording**: Full video replay of the browser session
- **Parameters**: The values you submitted for this run
See [Reviewing results](/cloud/monitor-a-run#reviewing-results) for details on the Actions, Recording, Parameters, and Diagnostics tabs.
---
## Canceling a run
Click the **Cancel** button during execution. A confirmation dialog appears. The run moves to `canceled` status and any configured webhook fires.
---
## Run history
Access past runs from two places:
1. **Runs** in the left sidebar: shows all runs across all workflows
2. **History** button (clock icon) in the workflow editor: shows runs for this specific workflow
---
## What's next
<CardGroup cols={2}>
<Card
title="Build a Workflow"
icon="pen-to-square"
href="/cloud/build-a-workflow"
>
Create and edit workflows in the visual editor
</Card>
<Card
title="Block Reference"
icon="cube"
href="/cloud/configure-blocks"
>
Configuration fields for every block type
</Card>
</CardGroup>

View File

@@ -1,6 +1,6 @@
---
title: Your First Task
slug: cloud/your-first-task
slug: cloud/run-your-first-task
subtitle: Run a browser automation from start to finish
---

View File

@@ -80,8 +80,20 @@
{
"group": "Getting Started",
"pages": [
"cloud/ui-overview",
"cloud/your-first-task"
"cloud/overview",
"cloud/run-your-first-task",
"cloud/run-a-task",
"cloud/monitor-a-run"
]
},
{
"group": "Building Workflows",
"pages": [
"cloud/build-a-workflow",
"cloud/manage-workflows",
"cloud/add-parameters",
"cloud/configure-blocks",
"cloud/run-a-workflow"
]
}
]

View File

@@ -6,7 +6,7 @@ slug: getting-started/quickstart
Run your first browser automation in 5 minutes. By the end of this guide, you'll scrape the top post from Hacker News using Skyvern's AI agent.
<Note>
Prefer a visual interface? Try the [Cloud UI](/cloud/ui-overview) instead — no code required.
Prefer a visual interface? Try the [Cloud UI](/cloud/overview) instead — no code required.
</Note>
## Step 1: Get your API key

View File

@@ -1,16 +1,14 @@
---
title: CAPTCHA & Bot Detection
subtitle: How Skyvern detects, solves, and avoids CAPTCHAs and anti-bot systems
subtitle: How Skyvern handles CAPTCHAs and avoids triggering anti-bot systems
slug: going-to-production/captcha-bot-detection
---
Websites use CAPTCHAs and bot detection to block automated traffic. Skyvern handles both — it detects CAPTCHAs using vision, solves them automatically on Skyvern Cloud, and configures browsers to avoid triggering anti-bot systems in the first place.
Skyvern detects CAPTCHAs using its vision model and solves them automatically.
---
However, CAPTCHA solving is not guaranteed. Skyvern's solvers can fail on novel challenges or rate-limited IPs.
## CAPTCHA detection
Skyvern detects CAPTCHAs using its LLM vision model. During each step, the AI analyzes the page screenshot and identifies whether a CAPTCHA is present and what type it is.
This guide helps you detect CAPTCHA failures and implement fallbacks to keep your automation running smoothly.
**Supported CAPTCHA types:**
@@ -24,17 +22,11 @@ Skyvern detects CAPTCHAs using its LLM vision model. During each step, the AI an
| `TEXT_CAPTCHA` | Distorted text/number images with an input field |
| `OTHER` | Unrecognized CAPTCHA types |
When the AI detects a CAPTCHA, it emits a `SOLVE_CAPTCHA` action with the identified `captcha_type`. What happens next depends on your deployment.
---
## CAPTCHA solving
## Use [`error_code_mapping`](/going-to-production/error-handling#step-3-use-error_code_mapping)
### Skyvern Cloud (automatic)
On [Skyvern Cloud](https://app.skyvern.com), CAPTCHAs are solved automatically. When the AI detects a CAPTCHA, Skyvern's solver service handles it in the background. No configuration needed — it works out of the box for all supported CAPTCHA types.
If the solver cannot resolve the CAPTCHA (rare edge cases or novel CAPTCHA types), the task continues with a `SOLVE_CAPTCHA` action failure. Handle this with [error code mapping](/going-to-production/error-handling):
When a CAPTCHA blocks your automation, this gives you a consistent error code instead of parsing free-text failure messages.
<CodeGroup>
```python Python
@@ -42,7 +34,7 @@ result = await client.run_task(
prompt="Submit the application form. COMPLETE when you see confirmation.",
url="https://example.com/apply",
error_code_mapping={
"captcha_failed": "Return this if a CAPTCHA blocks progress after multiple attempts",
"cant_solve_captcha": "return this error if captcha isn't solved after multiple retries",
},
)
```
@@ -53,7 +45,7 @@ const result = await client.runTask({
prompt: "Submit the application form. COMPLETE when you see confirmation.",
url: "https://example.com/apply",
error_code_mapping: {
captcha_failed: "Return this if a CAPTCHA blocks progress after multiple attempts",
cant_solve_captcha: "return this error if captcha isn't solved after multiple retries",
},
},
});
@@ -67,111 +59,64 @@ curl -X POST "https://api.skyvern.com/v1/run/tasks" \
"prompt": "Submit the application form. COMPLETE when you see confirmation.",
"url": "https://example.com/apply",
"error_code_mapping": {
"captcha_failed": "Return this if a CAPTCHA blocks progress after multiple attempts"
"cant_solve_captcha": "return this error if captcha isn't solved after multiple retries"
}
}'
```
</CodeGroup>
### Human Interaction block (workflows)
When a CAPTCHA blocks the run, the response includes `output.error = "cant_solve_captcha"`. You can branch your logic on this code.
For workflows where you want a human to solve the CAPTCHA manually, use the **Human Interaction** block. The workflow pauses and notifies you, then resumes after you solve it.
<Info>
For more on error code mapping and handling failures programmatically, see [Error Handling](/going-to-production/error-handling).
</Info>
```yaml
blocks:
- block_type: navigation
label: fill_form
url: https://example.com/form
navigation_goal: Fill out the registration form
## Take Control from the browser stream
- block_type: human_interaction
label: solve_captcha
message: "Please solve the CAPTCHA and click Continue"
In the Cloud UI, head to Runs > Click on *your run* > Click on the "Take Control" button over the browser stream.
- block_type: navigation
label: submit_form
navigation_goal: Click the submit button
```
This lets you manually solve CAPTCHAs.
<img src="/images/take-control.png" />
Release control when you're done and the agent resumes from where you left off.
---
## Bot detection avoidance
## Built-in bot detection avoidance
Skyvern automatically configures the browser to reduce bot detection triggers. These protections apply to every run — no configuration needed.
Skyvern automatically configures the browser to reduce bot detection triggers. These protections apply to every run. No configuration needed.
### Browser fingerprinting
Skyvern launches Chromium with settings that remove common automation signals:
- **`AutomationControlled` disabled** — Removes the Blink feature flag that marks the browser as automated
- **`navigator.webdriver` hidden** — The `enable-automation` flag is suppressed so JavaScript detection scripts don't see a webdriver
- **Viewport and user agent** — Set to match real consumer browsers
- **Locale and timezone** — Automatically matched to the proxy location (see [Proxy & Geolocation](/going-to-production/proxy-geolocation))
### Reducing detection risk
Beyond fingerprinting, how you structure your automation affects detection. Three patterns that help:
**1. Use residential proxies for sensitive sites.** Datacenter IPs are the most common bot signal. Residential proxies route through real ISP addresses. See [Proxy & Geolocation](/going-to-production/proxy-geolocation).
**2. Reuse browser sessions for multi-step flows.** Creating a fresh browser for every step looks suspicious. A persistent session maintains cookies, cache, and history — appearing as a returning user. See [Browser Sessions](/optimization/browser-sessions).
**3. Use browser profiles for repeat visits.** Profiles save browser state from a previous session. Starting with an existing profile means the site sees a known browser with familiar cookies, not a blank slate. See [Browser Profiles](/optimization/browser-profiles).
- **`AutomationControlled` disabled**: Removes the Blink feature flag that marks the browser as automated
- **`navigator.webdriver` hidden**: The `enable-automation` flag is suppressed so JavaScript detection scripts don't see a webdriver
- **Viewport and user agent**: Set to match real consumer browsers
- **Locale and timezone**: Automatically matched to the proxy location (see [Proxy & Geolocation](/going-to-production/proxy-geolocation))
---
## Self-hosted deployment
## Reducing detection risk
<Note>
The sections above apply to Skyvern Cloud. If you're running Skyvern locally, the following differences apply.
</Note>
Beyond fingerprinting, how you structure your automation affects detection:
### CAPTCHA solving
- **Use residential proxies for sensitive sites**: Datacenter IPs are the most common bot signal. Residential proxies route through real ISP addresses. Set `proxy_location="RESIDENTIAL"` or use `RESIDENTIAL_ISP` for static IPs.
- **Reuse browser sessions for multi-step flows**: Creating a fresh browser for every step looks suspicious. A persistent session maintains cookies, cache, and history. See [Browser Sessions](/optimization/browser-sessions).
- **Use browser profiles for repeat visits**: Profiles save browser state from a previous session. The site sees a known browser with familiar cookies instead of a blank slate. See [Browser Profiles](/optimization/browser-profiles).
- **Add wait blocks between rapid actions**: Instant actions can trigger behavioral detection. A short pause between steps looks more human.
The open-source version does **not** include automatic CAPTCHA solving. When a CAPTCHA is detected, the agent pauses for 30 seconds to allow manual intervention (e.g., solving it in the browser window yourself), then continues.
### If you get blocked
To handle CAPTCHAs in self-hosted workflows, use the Human Interaction block as described above.
### Browser extensions
Self-hosted deployments can load Chrome extensions for additional stealth or functionality:
```bash
# .env
EXTENSIONS=extension1,extension2
EXTENSIONS_BASE_PATH=/path/to/extensions
```
Extensions are loaded automatically when the browser launches.
### Proxies
Self-hosted deployments need their own proxy infrastructure. The `proxy_location` parameter is not available — configure proxies at the network level or via environment variables.
- **Increase `max_steps`**: Some bot challenges (like Cloudflare) loop through multiple verification pages. More steps give the solver more attempts.
- **Switch to a residential proxy**: `RESIDENTIAL_ISP` provides a static IP that services are more likely to trust.
- **Use a browser profile that previously passed**: If a profile has already cleared a Cloudflare challenge on a domain, it's more likely to pass again.
- **Load Chrome extensions**: Extensions can add additional stealth capabilities. Set `EXTENSIONS` and `EXTENSIONS_BASE_PATH` in your environment.
---
## Troubleshooting
## Self-hosted deployments
### CAPTCHA blocks the run
Automatic CAPTCHA solving is not available for self-hosted deployments.
**On Skyvern Cloud:** This is rare. If it happens, the CAPTCHA type may be unsupported or the site changed its challenge. Add an `error_code_mapping` entry to detect the failure, and contact [support@skyvern.com](mailto:support@skyvern.com).
**Self-hosted:** Use a Human Interaction block, or solve it manually within the 30-second window.
### Bot detection triggered (access denied)
1. Switch to a residential proxy — `proxy_location="RESIDENTIAL"` or `RESIDENTIAL_ISP` for static IPs
2. Reuse a browser session instead of creating fresh browsers
3. Use a browser profile with existing cookies
4. Add `wait` blocks between rapid actions to reduce behavioral signals
### Cloudflare challenge page loops
Cloudflare sometimes loops through multiple challenges. If a task gets stuck:
- Increase `max_steps` to give the solver more attempts
- Use `RESIDENTIAL_ISP` for a static IP that Cloudflare is more likely to trust
- Use a browser profile that has previously passed the Cloudflare challenge on that domain
Instead, when a CAPTCHA is detected, the agent pauses for 30 seconds to allow manual intervention. Solve it in the browser window yourself, then the agent continues automatically.
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 979 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 641 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 939 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 933 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 864 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 968 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB