Documentation Index
Fetch the complete documentation index at: https://mintlify.com/MotiaDev/motia/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Steps are the building blocks of Motia applications. They define handlers that respond to various triggers like HTTP requests, queue messages, cron schedules, state changes, and stream events.
Functions
step
Defines a step with its configuration and handler.
function step<TConfig extends StepConfig>(
config: TConfig,
handler: Handlers<TConfig>
): StepDefinition<TConfig>
function step<TConfig extends StepConfig>(
config: TConfig
): StepBuilder<TConfig>
config
TConfig extends StepConfig
required
The step configuration object.The unique name of the step.
Optional description of the step’s purpose.
triggers
readonly TriggerConfig[]
required
Array of triggers that activate this step.
Topics this step can enqueue messages to.
Virtual queue topics for type safety without actual queue creation.
Virtual subscriptions for type safety.
Flow identifiers this step belongs to.
Additional files to include with the step.
The handler function for processing step execution. Optional when using builder pattern.
return
StepDefinition<TConfig> | StepBuilder<TConfig>
Returns a step definition if handler is provided, otherwise returns a builder object.
Usage Examples
Direct Handler
import { step, http } from 'motia'
import { z } from 'zod'
export default step(
{
name: 'greet-user',
triggers: [http('POST', '/greet', {
bodySchema: z.object({ name: z.string() })
})]
},
async (input, ctx) => {
const { name } = ctx.getData()
return {
status: 200,
body: { message: `Hello, ${name}!` }
}
}
)
Builder Pattern
import { step, queue } from 'motia'
import { z } from 'zod'
export default step({
name: 'process-order',
triggers: [queue('orders', {
input: z.object({ orderId: z.string() })
})]
}).handle(async (input, ctx) => {
const order = ctx.getData()
await processOrder(order.orderId)
})
Types
StepConfig
type StepConfig = {
name: string
description?: string
triggers: readonly TriggerConfig[]
enqueues?: readonly Enqueue[]
virtualEnqueues?: readonly Enqueue[]
virtualSubscribes?: readonly string[]
flows?: readonly string[]
includeFiles?: readonly string[]
}
StepDefinition
type StepDefinition<TConfig extends StepConfig> = {
config: TConfig
handler: Handlers<TConfig>
}
StepBuilder
type StepBuilder<TConfig extends StepConfig> = {
config: TConfig
handle: (handler: Handlers<TConfig>) => StepDefinition<TConfig>
}
Handlers
type Handlers<TConfig extends StepConfig> = (
input: InferHandlerInput<TConfig>,
ctx: FlowContext<InferEnqueues<TConfig>, InferHandlerInput<TConfig>>
) => Promise<ApiResponse | void>
The handler function receives:
input: The input data based on the trigger type
ctx: The flow context with utilities for state, logging, enqueuing, etc.
StepHandler
type StepHandler<TInput = any, TEnqueueData = never> = (
input: TriggerInput<TInput>,
ctx: FlowContext<TEnqueueData, TriggerInput<TInput>>
) => Promise<ApiResponse | void>
Enqueue
type Enqueue = string | {
topic: string
label?: string
conditional?: boolean
}