docs/src/content/en/reference/ai-sdk/handle-workflow-stream.mdx
import PropertiesTable from "@site/src/components/PropertiesTable";
Framework-agnostic handler for streaming workflow execution in AI SDK-compatible format. Use this function directly when you need to handle workflow streaming outside Hono or Mastra's own apiRoutes feature.
handleWorkflowStream() returns a ReadableStream that you can wrap with createUIMessageStreamResponse().
handleWorkflowStream() keeps the existing AI SDK v5/default behavior. If your app is typed against AI SDK v6, pass version: 'v6'.
Use workflowRoute() if you want to create a workflow route inside a Mastra server.
:::tip Agent streaming in workflows
When a workflow step pipes an agent's stream to the workflow writer (e.g., await response.fullStream.pipeTo(writer)), the agent's text chunks and tool calls are forwarded to the UI stream in real time, even when the agent runs inside workflow steps.
See Workflow Streaming for more details.
:::
Next.js App Router example:
import { handleWorkflowStream } from '@mastra/ai-sdk'
import { createUIMessageStreamResponse } from 'ai'
import { mastra } from '@/src/mastra'
export async function POST(req: Request) {
const params = await req.json()
const stream = await handleWorkflowStream({
mastra,
workflowId: 'weatherWorkflow',
params,
})
return createUIMessageStreamResponse({ stream })
}
<PropertiesTable
content={[
{
name: 'version',
type: "'v5' | 'v6'",
description:
"Selects the AI SDK stream contract to emit. Omit it or pass 'v5' for the existing default behavior. Pass 'v6' when your app is typed against AI SDK v6 response helpers.",
isOptional: true,
defaultValue: "'v5'",
},
{
name: 'mastra',
type: 'Mastra',
description: 'The Mastra instance containing registered workflows.',
isOptional: false,
},
{
name: 'workflowId',
type: 'string',
description: 'The ID of the workflow to execute.',
isOptional: false,
},
{
name: 'params',
type: 'WorkflowStreamHandlerParams',
description: 'Parameters for the workflow stream.',
isOptional: false,
},
{
name: 'params.runId',
type: 'string',
description: 'Optional run ID for the workflow execution.',
isOptional: true,
},
{
name: 'params.resourceId',
type: 'string',
description: 'Optional resource ID for the workflow run.',
isOptional: true,
},
{
name: 'params.inputData',
type: 'Record<string, any>',
description: 'Input data for starting a new workflow execution.',
isOptional: true,
},
{
name: 'params.resumeData',
type: 'Record<string, any>',
description: 'Data for resuming a suspended workflow execution.',
isOptional: true,
},
{
name: 'params.requestContext',
type: 'RequestContext',
description: 'Request context to pass to the workflow execution.',
isOptional: true,
},
{
name: 'params.tracingOptions',
type: 'TracingOptions',
description: 'Options for tracing and observability.',
isOptional: true,
},
{
name: 'params.step',
type: 'string',
description: 'Specific step to target in the workflow.',
isOptional: true,
},
{
name: 'includeTextStreamParts',
type: 'boolean',
description: 'Whether to include text stream parts in the output.',
isOptional: true,
defaultValue: 'true',
},
]}
/>