Every workflow block lives in its own folder under src/blocks/{block-id}/, where block-id is the id you pass to defineWorkflowBlock (see block definition). The filenames are fixed. The SDK and CLI resolve handlers by name, so the files must match exactly. Which files are required depends on the block’s type, which you set in block.ts.
Trigger block
A trigger block subscribes to external events and fires a workflow run for each one. It has a three-file lifecycle: activate runs when the workflow is enabled (set up the subscription), trigger runs for each incoming event, and deactivate runs when the workflow is disabled (tear down the subscription).
src/blocks/my-trigger/
├── block.ts
├── activate.ts
├── trigger.ts
├── deactivate.ts
└── configurator.tsx
| File | API | Required | Purpose |
|---|
block.ts | defineWorkflowBlock | Yes | Block identity, copy, and config schema |
activate.ts | Workflows.defineWorkflowBlockActivate | Yes | Runs once when the workflow is enabled. Register the external subscription here. |
trigger.ts | Workflows.defineWorkflowBlockTrigger | Yes | Runs for each incoming event at triggerCallbackUrl. Fires the workflow run. |
deactivate.ts | Workflows.defineWorkflowBlockDeactivate | Yes | Runs once when the workflow is disabled. Remove the external subscription here. |
configurator.tsx | N/A | No | Configuration UI rendered inside the workflow editor. Omit if the block needs no configuration. |
Step block
A step block runs inline each time a workflow reaches it. The only required handler is execute. Add finish.ts only when execute returns {type: "defer"} and the step needs to wait for an external signal before continuing.
src/blocks/my-step/
├── block.ts
├── execute.ts
├── finish.ts # optional
└── configurator.tsx
| File | API | Required | Purpose |
|---|
block.ts | defineWorkflowBlock | Yes | Block identity, copy, and config schema |
execute.ts | Workflows.defineWorkflowBlockExecute | Yes | Runs each time the workflow run reaches this step |
finish.ts | Workflows.defineWorkflowBlockFinish | No Only add this file when execute returns {type: "defer"} and the step must wait for an external callback (e.g. a webhook or approval) to resume. | Runs when a request hits finishCallbackUrl to finish a deferred step |
configurator.tsx | N/A | No | Configuration UI rendered inside the workflow editor. Omit if the block needs no configuration. |
Handler files are server-only and must use the .ts extension. The CLI rejects .tsx variants
like execute.tsx or activate.tsx.