> ## Documentation Index
> Fetch the complete documentation index at: https://docs.attio.com/llms.txt
> Use this file to discover all available pages before exploring further.

# File structure

> The expected folder layout for a workflow block

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](/sdk/workflows/define-workflow-block)). 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](/sdk/workflows/block-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).

```text theme={"system"}
src/blocks/my-trigger/
├── block.ts
├── activate.ts
├── trigger.ts
├── deactivate.ts
└── configurator.tsx
```

| File               | API                                       | Required                         | Purpose                                                                                         |
| ------------------ | ----------------------------------------- | -------------------------------- | ----------------------------------------------------------------------------------------------- |
| `block.ts`         | `defineWorkflowBlock`                     | <Badge color="green">Yes</Badge> | Block identity, copy, and config schema                                                         |
| `activate.ts`      | `Workflows.defineWorkflowBlockActivate`   | <Badge color="green">Yes</Badge> | Runs once when the workflow is enabled. Register the external subscription here.                |
| `trigger.ts`       | `Workflows.defineWorkflowBlockTrigger`    | <Badge color="green">Yes</Badge> | Runs for each incoming event at `triggerCallbackUrl`. Fires the workflow run.                   |
| `deactivate.ts`    | `Workflows.defineWorkflowBlockDeactivate` | <Badge color="green">Yes</Badge> | Runs once when the workflow is disabled. Remove the external subscription here.                 |
| `configurator.tsx` | N/A                                       | <Badge color="gray">No</Badge>   | 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.

```text theme={"system"}
src/blocks/my-step/
├── block.ts
├── execute.ts
├── finish.ts      # optional
└── configurator.tsx
```

| File               | API                                    | Required                                                                                                                                                                           | Purpose                                                                                         |
| ------------------ | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| `block.ts`         | `defineWorkflowBlock`                  | <Badge color="green">Yes</Badge>                                                                                                                                                   | Block identity, copy, and config schema                                                         |
| `execute.ts`       | `Workflows.defineWorkflowBlockExecute` | <Badge color="green">Yes</Badge>                                                                                                                                                   | Runs each time the workflow run reaches this step                                               |
| `finish.ts`        | `Workflows.defineWorkflowBlockFinish`  | <Badge color="gray">No</Badge> 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                                    | <Badge color="gray">No</Badge>                                                                                                                                                     | Configuration UI rendered inside the workflow editor. Omit if the block needs no configuration. |

<Note>
  Handler files are server-only and must use the `.ts` extension. The CLI rejects `.tsx` variants
  like `execute.tsx` or `activate.tsx`.
</Note>
