Skip to main content
If you’ve built a workflow in the Cloud UI and want to trigger it from your codebase, this page shows how. You can run workflows on demand, poll for results, and set up recurring schedules using the Python SDK, TypeScript SDK, or REST API. This is for workflows defined in the visual editor. If you’re writing your entire automation in code (no workflow editor involved), see Browser Automation instead.

Run a workflow

Pass values for the workflow’s input parameters. The call returns immediately with a run_id — the workflow runs asynchronously in the background.
import os
import asyncio
from skyvern import Skyvern

async def main():
    client = Skyvern(api_key=os.getenv("SKYVERN_API_KEY"))

    run = await client.run_workflow(
        workflow_id="wpid_123456789",
        parameters={
            "resume": "https://example.com/resume.pdf",
            "job_url": "https://jobs.lever.co/company/position"
        }
    )

    print(f"Run ID: {run.run_id}")

asyncio.run(main())
Example response:
{
  "run_id": "wr_486305187432193510",
  "status": "created"
}

Run parameters

ParameterTypeRequiredDescription
workflow_idstringYesThe workflow_permanent_id returned when creating the workflow
parametersobjectNoValues for the workflow’s input parameters. Keys must match the key field in the workflow’s parameter definitions
titlestringNoDisplay name for this specific run
proxy_locationstring or objectNoOverride the workflow’s default proxy location
webhook_urlstringNoURL to receive a POST request when the workflow completes
browser_session_idstringNoReuse a persistent browser session (prefix pbs_)
browser_profile_idstringNoReuse a browser profile with saved cookies and storage (prefix bp_)

Get results

Workflows run asynchronously, so you need to check back for results. You have two options: poll the API, or receive a webhook when the workflow completes.

Option 1: Polling

Poll get_run until the status reaches a terminal state.
run_id = run.run_id

while True:
    result = await client.get_run(run_id)

    if result.status in ["completed", "failed", "terminated", "timed_out", "canceled"]:
        break

    await asyncio.sleep(5)

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

Option 2: Webhooks

Pass a webhook_url when running the workflow. Skyvern sends a POST request to your URL when the workflow reaches a terminal state.
run = await client.run_workflow(
    workflow_id="wpid_123456789",
    parameters={
        "resume": "https://example.com/resume.pdf",
        "job_url": "https://jobs.lever.co/company/position"
    },
    webhook_url="https://your-server.com/webhook"
)
The webhook payload contains the same data as the polling response. See Webhooks for authentication and retry options.

Response fields

{
  "run_id": "wr_486305187432193510",
  "run_type": "workflow_run",
  "status": "completed",
  "output": {
    "parse_resume_output": {
      "name": "John Smith",
      "email": "john@example.com",
      "work_experience": [...]
    },
    "apply_to_job_output": {
      "task_id": "tsk_123456",
      "status": "completed",
      "extracted_information": null
    }
  },
  "screenshot_urls": [
    "https://skyvern-artifacts.s3.amazonaws.com/.../screenshot_final.png"
  ],
  "recording_url": "https://skyvern-artifacts.s3.amazonaws.com/.../recording.webm",
  "failure_reason": null,
  "created_at": "2026-01-20T12:00:00.000000",
  "modified_at": "2026-01-20T12:05:00.000000"
}
FieldTypeDescription
run_idstringUnique identifier for this run (format: wr_*)
run_typestringAlways "workflow_run" for workflow runs
statusstringCurrent status: created, queued, running, completed, failed, terminated, timed_out, canceled
outputobjectOutput from each block, keyed by {label}_output
screenshot_urlsarrayFinal screenshots from the last blocks
recording_urlstringVideo recording of the browser session
failure_reasonstring | nullError description if the run failed
downloaded_filesarrayFiles downloaded during the run
app_urlstring | nullLink to view this run in the Skyvern UI
created_atdatetimeWhen the run started
modified_atdatetimeWhen the run was last updated
started_atdatetime | nullWhen execution started
finished_atdatetime | nullWhen execution finished

Schedule a workflow

Schedules let you run any workflow automatically on a recurring basis. Define a cron expression and timezone, and Skyvern triggers the workflow at each interval.

Create a schedule

import os
import asyncio
from skyvern import Skyvern

async def main():
    client = Skyvern(api_key=os.getenv("SKYVERN_API_KEY"))

    result = await client.agent.create_workflow_schedule(
        workflow_permanent_id="wpid_123456789",
        cron_expression="0 9 * * 1-5",
        timezone="America/New_York",
        name="Weekday morning report",
        description="Runs the data extraction workflow every weekday at 9 AM ET",
        parameters={
            "url": "https://example.com/dashboard",
            "output_format": "csv"
        }
    )

    print(f"Schedule ID: {result.schedule.workflow_schedule_id}")

asyncio.run(main())
Schedule parameters:
FieldTypeRequiredDescription
cron_expressionstringYes5-field cron expression (minimum 5-minute interval)
timezonestringYesIANA timezone identifier (e.g., America/New_York)
namestringNoHuman-readable name for the schedule
descriptionstringNoDescription of what this schedule does
parametersobjectNoWorkflow parameters to pass on each run
enabledbooleanNoWhether the schedule is active. Defaults to true

Enable and disable a schedule

# Disable
await client.agent.disable_workflow_schedule(
    workflow_permanent_id="wpid_123456789",
    workflow_schedule_id="wfs_abc123"
)

# Re-enable
await client.agent.enable_workflow_schedule(
    workflow_permanent_id="wpid_123456789",
    workflow_schedule_id="wfs_abc123"
)

Delete a schedule

Permanently remove a schedule. This cannot be undone. Runs that were already triggered by this schedule are not affected.
await client.agent.delete_workflow_schedule_route(
    workflow_permanent_id="wpid_123456789",
    workflow_schedule_id="wfs_abc123"
)

List workflows

Retrieve all workflows in your organization.
workflows = await client.get_workflows()

for workflow in workflows:
    print(f"{workflow.workflow_permanent_id}: {workflow.title}")