Files
Dorod-Sky/docs/running-automations/run-a-task.mdx
Naman 734e0e6398 feat: new workflows docs (#4565)
Co-authored-by: Kunal Mishra <kunalm2345@gmail.com>
Co-authored-by: Suchintan <suchintan@users.noreply.github.com>
2026-02-04 22:04:57 +00:00

487 lines
16 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Run a Task
subtitle: Execute a single browser automation with natural language
slug: running-automations/run-a-task
---
A **Task** is the simplest way to automate a browser action.
You describe what you want in natural language, and Skyvern's AI navigates the web to complete it.
---
## Call `run_task`
A task has one required parameter and one commonly used optional parameter:
- **`prompt`** (required) — Natural language instructions describing what the AI should do
- **`url`** (optional) — The starting page for the automation
For additional parameters like engines, proxies, and extraction schemas, see [Task Parameters](/running-automations/task-parameters).
When you call `run_task`, Skyvern spins up a cloud browser, navigates to the URL, and executes your prompt. A typical task takes 3090 seconds depending on complexity.
<CodeGroup>
```python Python
import os
import asyncio
from skyvern import Skyvern
async def main():
client = Skyvern(api_key=os.getenv("SKYVERN_API_KEY"))
result = await client.run_task(
prompt="Get the title of the top post",
url="https://news.ycombinator.com",
)
print(f"Run ID: {result.run_id}")
print(f"Status: {result.status}")
asyncio.run(main())
```
```typescript TypeScript
import { SkyvernClient } from "@skyvern/client";
async function main() {
const client = new SkyvernClient({
apiKey: process.env.SKYVERN_API_KEY,
});
const result = await client.runTask({
body: {
prompt: "Get the title of the top post",
url: "https://news.ycombinator.com",
},
});
console.log(`Run ID: ${result.run_id}`);
console.log(`Status: ${result.status}`);
}
main();
```
```bash cURL
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
-H "x-api-key: $SKYVERN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Get the title of the top post",
"url": "https://news.ycombinator.com"
}'
```
</CodeGroup>
**Example response:**
```json
{
"run_id": "tsk_v2_486305187432193504",
"status": "queued",
"output": null,
"downloaded_files": null,
"recording_url": null,
"screenshot_urls": null,
"failure_reason": null,
"created_at": "2026-01-20T11:52:29.276851",
"modified_at": "2026-01-20T11:52:29.484284",
"app_url": "https://app.skyvern.com/runs/wr_486305187432193510",
"run_type": "task_v2"
}
```
The response includes a `run_id`. Use this ID to check status, fetch results, and retrieve artifacts.
<Warning>
`run_task` returns immediately—the task is queued, not finished. Always poll or use webhooks to get results.
</Warning>
---
## Get results
The `run_task` call queues the task and returns immediately.
Use the `run_id` to fetch results once the task reaches a terminal state.
| Status | Description |
|--------|-------------|
| `created` | Task initialized, not yet queued |
| `queued` | Waiting for an available browser |
| `running` | AI is navigating and executing |
| `completed` | Task finished successfully—check `output` for results |
| `failed` | Task encountered an error—check `failure_reason` and retry or adjust your prompt |
| `terminated` | Task was manually stopped |
| `timed_out` | Task exceeded time limit—increase `max_steps` or simplify the task |
| `canceled` | Task was canceled before starting |
You have three options for retrieving results:
### Option 1: Polling
Poll `get_run` until status is terminal (`completed`, `failed`, `terminated`, `timed_out`, or `canceled`).
<CodeGroup>
```python Python
run_id = result.run_id
while True:
run = await client.get_run(run_id)
if run.status in ["completed", "failed", "terminated", "timed_out", "canceled"]:
break
await asyncio.sleep(5)
print(f"Output: {run.output}")
```
```typescript TypeScript
const runId = result.run_id;
while (true) {
const run = await client.getRun(runId);
if (["completed", "failed", "terminated", "timed_out", "canceled"].includes(run.status)) {
console.log(`Output: ${JSON.stringify(run.output)}`);
break;
}
await new Promise((resolve) => setTimeout(resolve, 5000));
}
```
```bash cURL
#!/bin/bash
RUN_ID="YOUR_RUN_ID"
while true; do
RESPONSE=$(curl -s -X GET "https://api.skyvern.com/v1/runs/$RUN_ID" \
-H "x-api-key: $SKYVERN_API_KEY")
STATUS=$(echo "$RESPONSE" | jq -r '.status')
echo "Status: $STATUS"
if [[ "$STATUS" == "completed" || "$STATUS" == "failed" || "$STATUS" == "terminated" || "$STATUS" == "timed_out" || "$STATUS" == "canceled" ]]; then
echo "$RESPONSE" | jq '.output'
break
fi
sleep 5
done
```
</CodeGroup>
<Warning>
Your polling loop must check **all** terminal states: `completed`, `failed`, `terminated`, `timed_out`, `canceled`. Missing one causes infinite loops.
</Warning>
### Option 2: Webhooks
Pass a `webhook_url` when creating the task. Skyvern sends a POST request to your URL when the task completes.
<CodeGroup>
```python Python
result = await client.run_task(
prompt="Get the title of the top post",
url="https://news.ycombinator.com",
webhook_url="https://your-server.com/webhook",
)
```
```typescript TypeScript
const result = await client.runTask({
body: {
prompt: "Get the title of the top post",
url: "https://news.ycombinator.com",
webhook_url: "https://your-server.com/webhook",
},
});
```
```bash cURL
curl -X POST "https://api.skyvern.com/v1/run/tasks" \
-H "x-api-key: $SKYVERN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Get the title of the top post",
"url": "https://news.ycombinator.com",
"webhook_url": "https://your-server.com/webhook"
}'
```
</CodeGroup>
Skyvern sends a POST request with the full run data when the task completes or fails.
### Option 3: Wait for completion (Python only)
Block until the task finishes instead of polling manually.
```python Python
result = await client.run_task(
prompt="Get the title of the top post",
url="https://news.ycombinator.com",
wait_for_completion=True,
)
print(result.output)
```
---
## Understand the response
The response from polling (`get_run`) and webhooks have slightly different structures. Both contain the core task data, but webhooks include additional metadata.
<CodeGroup>
```json Polling Response
{
"run_id": "tsk_v2_486305187432193504",
"status": "completed",
"output": {
"top_post_title": "Linux kernel framework for PCIe device emulation, in userspace"
},
"downloaded_files": [],
"recording_url": "https://skyvern-artifacts.s3.amazonaws.com/v1/production/.../recording.webm?...",
"screenshot_urls": ["https://skyvern-artifacts.s3.amazonaws.com/.../screenshot_final.png?..."],
"failure_reason": null,
"errors": [],
"step_count": 2,
"run_type": "task_v2",
"app_url": "https://app.skyvern.com/runs/wr_486305187432193510",
"browser_session_id": null,
"browser_profile_id": null,
"created_at": "2026-01-20T11:52:29.276851",
"modified_at": "2026-01-20T11:54:08.822807",
"queued_at": "2026-01-20T11:52:29.483922",
"started_at": "2026-01-20T11:52:31.835337",
"finished_at": "2026-01-20T11:54:08.821985",
"run_request": {
"prompt": "Get the title of the top post",
"url": "https://news.ycombinator.com/",
"engine": "skyvern-2.0"
}
}
```
```json Webhook Payload
{
"task_id": "tsk_v2_486306851394503256",
"run_id": "tsk_v2_486306851394503256",
"status": "completed",
"output": {
"top_post_title": "Linux kernel framework for PCIe device emulation, in userspace"
},
"summary": "I have successfully navigated to Hacker News and extracted the title of the top post.",
"prompt": "Get the title of the top post",
"url": "https://news.ycombinator.com/",
"downloaded_files": [],
"recording_url": "https://skyvern-artifacts.s3.amazonaws.com/v1/production/.../recording.webm?...",
"screenshot_urls": ["https://skyvern-artifacts.s3.amazonaws.com/.../screenshot_final.png?..."],
"failure_reason": null,
"errors": [],
"step_count": 2,
"run_type": "task_v2",
"app_url": "https://app.skyvern.com/runs/wr_486306851394503262",
"organization_id": "o_485917350850524254",
"workflow_run_id": "wr_486306851394503262",
"proxy_location": "RESIDENTIAL",
"webhook_callback_url": "https://your-server.com/webhook",
"created_at": "2026-01-20T11:58:57.414123",
"modified_at": "2026-01-20T12:00:31.513449",
"queued_at": "2026-01-20T11:58:57.607233",
"started_at": "2026-01-20T11:58:59.395028",
"finished_at": "2026-01-20T12:00:31.512692"
}
```
</CodeGroup>
**Common fields (both polling and webhook):**
| Field | Type | Description |
|-------|------|-------------|
| `run_id` | string | Unique identifier for this run |
| `status` | string | Current status: `queued`, `running`, `completed`, `failed`, `terminated`, `timed_out`, `canceled` |
| `output` | object \| null | Extracted data from the task |
| `downloaded_files` | array | Files downloaded during execution |
| `recording_url` | string \| null | Video recording of the browser session |
| `screenshot_urls` | array \| null | Screenshots captured (latest first) |
| `failure_reason` | string \| null | Error message if the run failed |
| `errors` | array | List of errors encountered |
| `step_count` | integer \| null | Number of steps executed |
| `run_type` | string | Type of run: `task_v2`, `openai_cua`, `anthropic_cua` |
| `app_url` | string | Link to view this run in Skyvern Cloud |
| `created_at` | datetime | When the run was created |
| `modified_at` | datetime | When the run was last updated |
| `queued_at` | datetime \| null | When the run entered the queue |
| `started_at` | datetime \| null | When execution began |
| `finished_at` | datetime \| null | When execution completed |
**Polling-only fields:**
| Field | Type | Description |
|-------|------|-------------|
| `run_request` | object | Original request parameters (prompt, url, engine, etc.) |
| `browser_session_id` | string \| null | ID of the browser session used |
| `browser_profile_id` | string \| null | ID of the browser profile used |
| `max_screenshot_scrolls` | integer \| null | Number of scrolls for screenshots |
| `script_run` | object \| null | Script run result if AI fallback triggered |
**Webhook-only fields:**
| Field | Type | Description |
|-------|------|-------------|
| `task_id` | string | Same as `run_id` |
| `summary` | string | AI-generated description of what was done |
| `prompt` | string | The prompt from the original request |
| `url` | string | The URL from the original request |
| `organization_id` | string | Your organization ID |
| `workflow_run_id` | string | Associated workflow run ID |
| `proxy_location` | string | Proxy location used (e.g., `RESIDENTIAL`) |
| `webhook_callback_url` | string | The webhook URL that received this payload |
---
## Get artifacts
The run response contains high-level data like `output`, `recording_url`, and `screenshot_urls`.
Every run also generates Artifacts, such as screenshots, reasoning logs, downloaded files, for observability. To get them, use `get_run_artifacts`.
<CodeGroup>
```python Python
artifacts = await client.get_run_artifacts(run_id)
for artifact in artifacts:
print(f"{artifact.artifact_type}: {artifact.signed_url}")
```
```typescript TypeScript
const artifacts = await client.getRunArtifacts(runId);
for (const artifact of artifacts) {
console.log(`${artifact.artifact_type}: ${artifact.signed_url}`);
}
```
```bash cURL
curl -X GET "https://api.skyvern.com/v1/runs/RUN_ID/artifacts" \
-H "x-api-key: $SKYVERN_API_KEY"
```
</CodeGroup>
This returns a list of artifacts.
**Example response:**
```json
[
{
"artifact_id": "a_486305284826607484",
"artifact_type": "recording",
"uri": "s3://skyvern-artifacts/v1/production/.../recording.webm",
"signed_url": "https://skyvern-artifacts.s3.amazonaws.com/v1/production/.../recording.webm?...",
"task_id": "tsk_486305246171901814",
"step_id": "stp_486305250466869112",
"workflow_run_id": "wr_486305187432193510",
"workflow_run_block_id": null,
"run_id": "tsk_v2_486305187432193504",
"organization_id": "o_485917350850524254",
"created_at": "2026-01-20T11:52:52.083001",
"modified_at": "2026-01-20T11:52:52.083003"
},
{
"artifact_id": "a_486305516754841578",
"artifact_type": "screenshot_final",
"uri": "s3://skyvern-artifacts/v1/production/.../screenshot_final.png",
"signed_url": "https://skyvern-artifacts.s3.amazonaws.com/v1/production/.../screenshot_final.png?...",
"task_id": "tsk_486305439445430190",
"step_id": "stp_486305439445430192",
"workflow_run_id": "wr_486305187432193510",
"workflow_run_block_id": null,
"run_id": "tsk_v2_486305187432193504",
"organization_id": "o_485917350850524254",
"created_at": "2026-01-20T11:53:46.468908",
"modified_at": "2026-01-20T11:53:46.468910"
}
]
```
**Artifact fields:**
| Field | Type | Description |
|-------|------|-------------|
| `artifact_id` | string | Unique identifier for the artifact |
| `artifact_type` | string | Type of artifact (see table below) |
| `uri` | string | Internal storage path |
| `signed_url` | string \| null | Pre-signed URL for downloading |
| `task_id` | string \| null | Associated task ID |
| `step_id` | string \| null | Associated step ID |
| `run_id` | string \| null | Associated run ID (e.g., `tsk_v2_...`) |
| `workflow_run_id` | string \| null | Associated workflow run ID |
| `workflow_run_block_id` | string \| null | Associated workflow block ID |
| `organization_id` | string | Organization that owns this artifact |
| `created_at` | datetime | When the artifact was created |
| `modified_at` | datetime | When the artifact was last modified |
**Artifact types:**
| Type | Description |
|------|-------------|
| `recording` | Full video of the browser session |
| `screenshot` | Screenshot captured during execution |
| `screenshot_action` | Screenshot taken after an action |
| `screenshot_final` | Final screenshot when task completed |
| `screenshot_llm` | Screenshot sent to the LLM for analysis |
| `html` | Page HTML at various points |
| `html_scrape` | Scraped HTML content |
| `html_action` | HTML captured after an action |
| `har` | HTTP Archive file for network debugging |
| `trace` | Execution trace data |
| `pdf` | PDF files generated or downloaded |
| `script_file` | Generated script files |
| `browser_console_log` | Browser console output |
| `skyvern_log` | Skyvern execution logs |
| `skyvern_log_raw` | Raw Skyvern execution logs |
| `llm_prompt` | Prompt sent to the LLM |
| `llm_request` | Full request sent to the LLM |
| `llm_response` | Response from the LLM |
| `llm_response_parsed` | Parsed LLM response |
| `llm_response_rendered` | Rendered LLM response |
| `visible_elements_tree` | DOM tree of visible elements |
| `visible_elements_tree_trimmed` | Trimmed DOM tree |
| `visible_elements_tree_in_prompt` | DOM tree included in prompt |
| `visible_elements_id_css_map` | CSS selector map for elements |
| `visible_elements_id_frame_map` | Frame map for elements |
| `visible_elements_id_xpath_map` | XPath map for elements |
| `hashed_href_map` | Hashed href mapping |
You can filter by artifact type using query parameters:
```bash
curl -X GET "https://api.skyvern.com/v1/runs/RUN_ID/artifacts?artifact_type=screenshot&artifact_type=recording" \
-H "x-api-key: $SKYVERN_API_KEY"
```
---
## Next steps
<CardGroup cols={2}>
<Card
title="Task Parameters"
icon="sliders"
href="/running-automations/task-parameters"
>
Configure engines, proxies, extraction schemas, etc when running a task
</Card>
<Card
title="Extract Structured Data"
icon="database"
href="/running-automations/extract-structured-data"
>
Define a schema to get typed JSON output from your automations
</Card>
</CardGroup>