Build Mastra workflows with createWorkflow and createStep. Chain steps with .then, run them in parallel, branch on conditions, and start runs.
Learn how to build deterministic, multi-step business pipelines in Mastra using steps, chains, parallel branches, and workflow runs.
Previous lesson: Structured Output with Mastra | Next lesson: Using Agents and Tools Inside Mastra Workflows
An AI agent decides its own path dynamically by selecting tools in a loop. A workflow, by contrast, follows a fixed sequence of steps that you specify in advance.
Think of a workflow like an assembly line in a factory. Raw materials enter at one end, pass through dedicated stations in an exact order, and emerge as a finished product. Every station performs a precise task, validates the materials it receives, and passes its output to the next station.
Workflows give you complete predictability for business operations such as ticket triage, payment processing, and customer onboarding. You get schema validation at every transition, full execution traces, and built-in error handling.
Mastra workflows are directed graphs composed of steps. You can run steps in series, trigger multiple steps in parallel, or branch down conditional paths based on runtime data.
A step is the fundamental building block of any Mastra workflow. Every step is an isolated unit of execution created using the createStep function from @mastra/core/workflows.
To build a valid step, you must supply four properties:
id: A unique string identifier.inputSchema: A Zod schema validating incoming data.outputSchema: A Zod schema validating outgoing data.execute: An asynchronous function that receives an object containing inputData and returns the output matching outputSchema.In the next section you will write three steps for the support ticket pipeline: one that cleans up the message, one that classifies it, and one that formats the final ticket. Each step's outputSchema must match the next step's inputSchema.
Common Mistake: Forgetting to match the output schema of one step with the input schema of the next step. Mastra validates data schemas between transitions. If step A returns an object that step B cannot parse, the workflow halts with a validation error.
You chain steps together by calling createWorkflow. You define the overall workflow input and output schemas, attach steps using the .then method, and finish the definition by calling .commit.
Create the file src/mastra/workflows/ticket-workflow.ts and add the following complete implementation:
tsCopy
Pro Tip: Always call .commit() at the very end of your workflow builder chain. Omitting .commit() leaves the workflow in a mutable drafting state, which prevents Mastra from compiling its execution graph.
Real-world support pipelines frequently need to perform multiple checks at the same time or make conditional routing choices.
Use .parallel to run two or more steps concurrently. When steps run in parallel, the step that immediately follows receives an object containing the outputs of all parallel steps keyed by their individual step IDs.
tsCopy
When you need conditional logic, use .branch. The .branch method accepts an array of tuples. Each tuple contains a condition predicate function and the destination step.
tsCopy
After .branch(), the next step receives an object keyed by the id of the step that ran, for example { "manual-review": { "action": "..." } }. Only the branch that ran appears in that object. The .map() call turns it back into a flat { action } object so it matches the workflow outputSchema.
Once registered on the main Mastra instance, you run a workflow programmatically by creating a run instance and calling start.
Register the workflow in src/mastra/index.ts, next to the support agent you already registered:
tsCopy
Create a script named run-workflow.ts at the root of your project to test execution:
tsCopy
Run this file with tsx:
bashCopy
Your terminal outputs the formatted ticket summary and the team route produced by the sequence of steps. You can also view this execution visually by opening Mastra Studio at http://localhost:4111. Studio tracks step execution times, input payloads, and outputs.
Quick Challenge: Open Mastra Studio at http://localhost:4111 while running your dev server. Locate ticket-workflow under the Workflows tab, enter a test JSON payload containing { "message": "My item arrived damaged" }, and inspect each step in the visual run graph.
Try This: Add a fourth step to ticketWorkflow named log-audit. Have it accept the output from formatTicket, record a timestamp using new Date().toISOString(), and return { ticketSummary: string, routeTo: string, loggedAt: string }. Update the workflow output schema accordingly.
In the next lesson, Using Agents and Tools Inside Mastra Workflows, you will integrate the support agent and order status tool directly into workflow steps using mastra.getAgent, createStep(agent), and .map.
Was this lesson helpful?