> ## 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.

# Block definition

> Declare a workflow block's identity, copy, and config schema

Call `Workflows.defineWorkflowBlock` in `block.ts` to declare a block's stable identity, human-readable copy, and the configuration schema exposed to workspace members in the workflow editor. The export from `block.ts` is shared between client and server; it must not import client- or server-only code.

## Parameters

<ParamField path="type" type="&#x22;trigger&#x22; | &#x22;step&#x22;" required>
  Whether this block starts a workflow run (`"trigger"`) or runs inline as part of one (`"step"`).
</ParamField>

<ParamField path="id" type="string" required>
  Stable identifier for this block within your app. Used as the folder name under `src/blocks/`,
  to wire up handlers, and to reference the block from workflow definitions. Must be unique across
  all blocks in the app.
</ParamField>

<ParamField path="title" type="string" required>
  Human-readable label shown in the workflow editor's block picker.
</ParamField>

<ParamField path="description" type="string" required>
  Short description shown alongside the title in the block picker.
</ParamField>

<ParamField path="configSchema" type="WorkflowBlockConfigFriendlyStruct" required>
  The configurable fields that `configurator.tsx` must render inputs for. Build this with
  `Workflows.ConfigSchema`, for example `Workflows.ConfigSchema.struct({...})`. The configSchema is
  also the source of truth for the typed `config` argument your handlers receive. See
  [Config schema](./config-schema) for all available node types.
</ParamField>

<ParamField path="requireUserConnection" type="boolean" default="false">
  Whether this block expects a workspace user to have a connection configured. Set to `true` for
  blocks that call third-party APIs on behalf of the user.
</ParamField>

<ParamField path="deprecated" type="true | {replacedBy: string}">
  Mark the block as deprecated. Pass `{replacedBy: "other-block-id"}` to point users at a
  successor block.
</ParamField>

## Example

```ts block.ts theme={"system"}
import {Workflows} from "attio"

export default Workflows.defineWorkflowBlock({
  type: "step",
  id: "send-welcome-email",
  title: "Send welcome email",
  description: "Send a welcome email to a newly-created contact.",
  configSchema: Workflows.ConfigSchema.struct({
    recipient_email: Workflows.ConfigSchema.string(),
    subject: Workflows.ConfigSchema.string(),
  }),
})
```

## See also

* [File structure](./file-structure): complete folder layout for trigger and step blocks
* [Config schema](./config-schema): all available schema field types
* [Executing a step](./define-workflow-block-execute): step execute handler
* [Registering a trigger](./define-workflow-block-activate): trigger activate handler
