Skip to main content

Overview

After creating a task, you’ll want to monitor its progress, check its status, and retrieve results. Skyvern provides multiple ways to track and inspect task runs through the SDK, API, and web UI.

Task Run Lifecycle

Every task goes through a series of states during execution:

Status Values

StatusDescription
createdTask has been created but not yet queued
queuedTask is waiting to be executed
runningTask is currently executing
completedTask finished successfully
failedTask encountered an error and failed
terminatedTask was terminated due to specific conditions
timed_outTask exceeded the maximum allowed time
canceledTask was manually canceled

Final States

These statuses indicate the task has finished:
  • completed
  • failed
  • terminated
  • timed_out
  • canceled

Monitoring with Python SDK

Wait for Completion

The simplest way to monitor a task is to use wait_for_completion:
from skyvern import Skyvern

skyvern = Skyvern(api_key="your-api-key")

task = await skyvern.run_task(
    prompt="Fill out the contact form",
    url="https://example.com/contact",
    wait_for_completion=True,  # Blocks until task finishes
    timeout=300.0  # Maximum wait time in seconds (5 minutes)
)

print(f"Status: {task.status}")
print(f"Output: {task.output}")

Poll Manually

For more control, create a task and poll its status:
import asyncio
from skyvern import Skyvern
from skyvern.schemas.runs import RunStatus

skyvern = Skyvern(api_key="your-api-key")

# Create task without waiting
task = await skyvern.run_task(
    prompt="Process the order",
    url="https://example.com/orders"
)

print(f"Task created: {task.run_id}")

# Poll for status
while True:
    task = await skyvern.get_run(task.run_id)
    print(f"Current status: {task.status}")
    
    if RunStatus(task.status).is_final():
        break
    
    await asyncio.sleep(2)  # Check every 2 seconds

print(f"Final status: {task.status}")
if task.output:
    print(f"Extracted data: {task.output}")

Check Run Status

Retrieve detailed information about a specific run:
task = await skyvern.get_run("tsk_50da533e-3904-4401-8a07-c49adf88b5eb")

print(f"Run ID: {task.run_id}")
print(f"Status: {task.status}")
print(f"Created: {task.created_at}")
print(f"Started: {task.started_at}")
print(f"Finished: {task.finished_at}")
print(f"Steps: {task.step_count}")

if task.failure_reason:
    print(f"Failure reason: {task.failure_reason}")

Monitoring with TypeScript SDK

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

const skyvern = new Skyvern({ apiKey: "your-api-key" });

// Create task
const task = await skyvern.runTask({
  prompt: "Fill out the contact form",
  url: "https://example.com/contact"
});

console.log(`Task created: ${task.runId}`);

// Poll for completion
while (true) {
  const updatedTask = await skyvern.getRun(task.runId);
  console.log(`Status: ${updatedTask.status}`);
  
  const finalStates = ["completed", "failed", "terminated", "timed_out", "canceled"];
  if (finalStates.includes(updatedTask.status)) {
    console.log(`Final status: ${updatedTask.status}`);
    if (updatedTask.output) {
      console.log(`Output: ${JSON.stringify(updatedTask.output)}`);
    }
    break;
  }
  
  await new Promise(resolve => setTimeout(resolve, 2000)); // Wait 2 seconds
}

Monitoring via REST API

Get Run Status

curl -X GET "https://api.skyvern.com/api/v1/runs/tsk_50da533e-3904-4401-8a07-c49adf88b5eb" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

{
  "run_id": "tsk_50da533e-3904-4401-8a07-c49adf88b5eb",
  "status": "completed",
  "output": {
    "title": "Example Product",
    "price": 29.99
  },
  "downloaded_files": [
    {
      "name": "invoice.pdf",
      "url": "https://storage.skyvern.com/files/abc123.pdf",
      "size": 152048
    }
  ],
  "recording_url": "https://storage.skyvern.com/recordings/xyz789.mp4",
  "screenshot_urls": [
    "https://storage.skyvern.com/screenshots/screen1.png"
  ],
  "created_at": "2024-01-01T10:00:00Z",
  "started_at": "2024-01-01T10:00:02Z",
  "finished_at": "2024-01-01T10:02:15Z",
  "step_count": 12,
  "app_url": "https://app.skyvern.com/tasks/tsk_50da533e-3904-4401-8a07-c49adf88b5eb"
}

Viewing Artifacts

Screenshots

Access screenshots taken during task execution:
task = await skyvern.get_run("tsk_123456")

if task.screenshot_urls:
    # Screenshots are in reverse chronological order
    latest_screenshot = task.screenshot_urls[0]
    print(f"Latest screenshot: {latest_screenshot}")
    
    for i, url in enumerate(task.screenshot_urls):
        print(f"Screenshot {i+1}: {url}")

Recording

View the full browser recording of the task:
task = await skyvern.get_run("tsk_123456")

if task.recording_url:
    print(f"Watch recording: {task.recording_url}")

Downloaded Files

Access files downloaded during the task:
task = await skyvern.get_run("tsk_123456")

if task.downloaded_files:
    for file in task.downloaded_files:
        print(f"File: {file.name}")
        print(f"URL: {file.url}")
        print(f"Size: {file.size} bytes")
        print("---")

Error Information

Check for errors if the task failed:
task = await skyvern.get_run("tsk_123456")

if task.status in ["failed", "terminated"]:
    print(f"Failure reason: {task.failure_reason}")
    
    if task.errors:
        print("\nDetailed errors:")
        for error in task.errors:
            print(f"- {error}")

Monitoring in the Web UI

Access the UI

Every task has an app_url that links to the Skyvern web interface:
task = await skyvern.run_task(
    prompt="Process the order",
    url="https://example.com/orders"
)

print(f"View in UI: {task.app_url}")
# Output: https://app.skyvern.com/tasks/tsk_50da533e-3904-4401-8a07-c49adf88b5eb

UI Features

  • Live Streaming: Watch the browser in real-time as the task executes
  • Step-by-step View: See each action taken by Skyvern
  • Screenshots: View screenshots at each step
  • Recordings: Play back the full execution
  • Extracted Data: View formatted output data
  • Error Details: Debug failures with detailed error messages
  • Timeline: See exact timestamps for each action

Using Webhooks

Instead of polling, receive automatic notifications when tasks complete:
task = await skyvern.run_task(
    prompt="Process the order",
    url="https://example.com/orders",
    webhook_url="https://your-domain.com/webhook"
)

print(f"Task created: {task.run_id}")
print("Will receive webhook when complete")

Webhook Payload

When the task finishes, Skyvern sends a POST request to your webhook URL:
{
  "run_id": "tsk_50da533e-3904-4401-8a07-c49adf88b5eb",
  "status": "completed",
  "output": {
    "extracted_field": "value"
  },
  "finished_at": "2024-01-01T10:02:15Z",
  "app_url": "https://app.skyvern.com/tasks/tsk_50da533e-3904-4401-8a07-c49adf88b5eb"
}
See Webhooks FAQ for more details.

Performance Metrics

Execution Time

Calculate how long a task took:
from datetime import datetime

task = await skyvern.get_run("tsk_123456")

if task.started_at and task.finished_at:
    duration = task.finished_at - task.started_at
    print(f"Execution time: {duration.total_seconds():.2f} seconds")

Step Count

Monitor how many steps were taken:
task = await skyvern.get_run("tsk_123456")

if task.step_count:
    print(f"Total steps: {task.step_count}")
    
    # Compare against max_steps if set
    if task.run_request and task.run_request.max_steps:
        efficiency = (task.step_count / task.run_request.max_steps) * 100
        print(f"Used {efficiency:.1f}% of max steps")

Advanced: Livestreaming

Skyvern supports livestreaming the browser viewport in real-time. This is available through the web UI when viewing a running task. To access livestreaming:
  1. Create a task and note the run_id
  2. Navigate to https://app.skyvern.com/tasks/{run_id}
  3. Click the “Live View” button while the task is running
This allows you to:
  • Watch the browser in real-time
  • Debug issues as they happen
  • Intervene manually if needed (on certain plans)

Best Practices

1. Set Appropriate Timeouts

# Good - reasonable timeout for the task complexity
task = await skyvern.run_task(
    prompt="Fill out simple form",
    wait_for_completion=True,
    timeout=120.0  # 2 minutes
)

# Adjust for complex multi-step tasks
task = await skyvern.run_task(
    prompt="Complete multi-page checkout process",
    wait_for_completion=True,
    timeout=600.0  # 10 minutes
)

2. Handle All Status Cases

task = await skyvern.get_run("tsk_123456")

if task.status == "completed":
    print("Success!", task.output)
elif task.status == "failed":
    print("Failed:", task.failure_reason)
elif task.status == "terminated":
    print("Terminated:", task.failure_reason)
elif task.status == "timed_out":
    print("Task took too long")
elif task.status == "canceled":
    print("Task was canceled")
else:
    print(f"Task still running: {task.status}")

3. Use Webhooks for Long-Running Tasks

# Better for long tasks - don't block
task = await skyvern.run_task(
    prompt="Download all invoices from last year",
    webhook_url="https://your-domain.com/webhook",
    # Don't wait - get webhook when done
)

print(f"Task {task.run_id} started, will notify webhook when complete")

4. Store Run IDs for Later Reference

import json

task = await skyvern.run_task(
    prompt="Process order",
    url="https://example.com/orders"
)

# Save run_id to your database or file
with open("tasks.json", "a") as f:
    json.dump({
        "run_id": task.run_id,
        "created_at": task.created_at.isoformat(),
        "prompt": "Process order"
    }, f)
    f.write("\n")

# Retrieve later
task = await skyvern.get_run(task.run_id)

5. Monitor Step Count vs. Max Steps

task = await skyvern.run_task(
    prompt="Complete the workflow",
    max_steps=50,  # Set a reasonable limit
    wait_for_completion=True
)

if task.step_count:
    print(f"Used {task.step_count} of 50 max steps")
    
    # Alert if getting close to limit
    if task.step_count > 40:
        print("Warning: Task used >80% of max steps")

Troubleshooting

Task Stuck in “Queued”

  • Check your account’s concurrent task limit
  • Verify your API key is valid
  • Contact support if issue persists

Task Fails Immediately

  • Check the failure_reason field
  • Verify the URL is accessible
  • Review error_code_mapping if used
  • Check screenshots for visual clues

Task Times Out

  • Increase max_steps if hitting the step limit
  • Simplify the task prompt
  • Break complex tasks into smaller steps
  • Use workflows for multi-step processes

No Output Data

  • Ensure data_extraction_schema is provided
  • Verify the schema matches the page content
  • Check if task completed successfully
  • Review screenshots to confirm data is visible

Next Steps

Creating Tasks

Learn how to create and run tasks

Webhooks

Set up webhook notifications for task completion

Build docs developers (and LLMs) love