A Workflow chains multiple automation steps into a reusable template. While a Task handles a single goal on one page, a Workflow orchestrates an entire process: filling forms, validating data, downloading files, and sending results.You define the workflow once with blocks, then run it with different parameters each time.
A workflow is defined as an ordered list of blocks. Blocks execute one after another, and each block can access the outputs of previous blocks.Here’s an IRS EIN registration workflow that fills out a government form, validates the summary, extracts the result, downloads the confirmation letter, and emails it to your team:
Here’s what each block does in this workflow:
Navigation takes the company information from ein_info and fills out the multi-page SS-4 form until it reaches the review page
Validation checks that the form summary matches the provided information and either continues (if correct) or terminates the workflow (if incorrect)
Extraction pulls the assigned EIN number and legal name from the confirmation page into structured JSON output
File Download navigates to and downloads the EIN confirmation letter as a PDF file
Send Email attaches the downloaded PDF and sends it to the specified recipients with company details in the email body
For detailed documentation on all available block types and their parameters, see Workflow Blocks Reference.
The parameters array (inside workflow_definition) defines the inputs your workflow accepts. Instead of hardcoding a resume URL or job page into the workflow definition, you define named inputs that accept different values each time the workflow runs.Each parameter needs three fields:
key — the name you reference later with {{ key }}
parameter_type — always "workflow" for input parameters
workflow_parameter_type — the data type (string, file_url, json, etc.)
This defines two inputs: a resume file and a job_url string. When you run the workflow later, you pass actual values for these parameters.Available parameter types:
The blocks array (inside workflow_definition) defines the steps your workflow executes. Each block has a block_type that determines what it does: navigate a page, extract data, download a file, send an email.Every block needs two fields: a label (a unique name) and a block_type. The remaining fields depend on the block type.
Copy
Ask AI
{ "blocks": [ { "label": "parse_resume", "block_type": "file_url_parser", "file_url": "{{ resume }}", "file_type": "pdf" }, { "label": "apply_to_job", "block_type": "navigation", "url": "{{ job_url }}", "navigation_goal": "Fill out the job application form using the candidate's information." } ]}
The first block (parse_resume) parses the resume file passed as an input parameter. The second block (apply_to_job) navigates to the job page and fills out the application.Notice {{ resume }} and {{ job_url }} — double curly braces reference the input parameters you defined in Step 2. Skyvern replaces these with actual values when the workflow runs.
Skyvern supports 23 block types: navigation, extraction, validation, file download, for loops, conditionals, and more. See Workflow Blocks Reference for the full list.
When a block completes, its output becomes available to subsequent blocks. This is how you chain steps together: one block extracts data, the next block uses it.Reference a block’s output with {{ label_output }} — the block’s label followed by _output. Access nested fields with dot notation: {{ parse_resume_output.name }}.Here, the apply_to_job block uses specific fields from the parse_resume block’s output:
{{ parse_resume_output.name }}, {{ parse_resume_output.email }}, and {{ parse_resume_output.work_experience }} are fields from the structured data the parse_resume block extracted from the PDF.
When a block produces a list, use a for_loop block to process each item. Set loop_over_parameter_key to the output field containing the array, and reference the current item with {{ loop_block_label.current_value }}.
The for_loop iterates over the order_ids array from the extraction block. Inside the loop, {{ download_invoice.current_value }} contains one order ID per iteration.
Send the complete workflow definition to the API. Skyvern validates the parameters, blocks, and template references, then returns a workflow_permanent_id you use to run the workflow.The API accepts two formats: pass a JSON object via json_definition, or pass a YAML string via yaml_definition.
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.