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

# createHook

> Create a hook to receive external data in a workflow

Creates a hook that can be used to suspend and resume a workflow run with a payload from an external system.

Hooks allow external systems to send arbitrary serializable data into a workflow. Each hook has a unique token that external systems use to send data.

## Signature

```typescript theme={null}
function createHook<T = any>(options?: HookOptions): Hook<T>
```

## Parameters

<ParamField path="options" type="HookOptions" optional>
  Configuration options for the hook.

  <Expandable title="properties">
    <ParamField path="token" type="string" optional>
      Unique token to associate with the hook. If not provided, a randomly generated token will be assigned.

      When specifying an explicit token, construct it with information that the dispatching side can reliably reconstruct.
    </ParamField>

    <ParamField path="metadata" type="Serializable" optional>
      Additional user-defined data to include with the hook payload.
    </ParamField>
  </Expandable>
</ParamField>

## Returns

<ResponseField name="Hook<T>" type="Hook<T>">
  A hook object that can be awaited or iterated over to receive payloads.

  <Expandable title="properties">
    <ResponseField name="token" type="string">
      The unique token identifying this hook.
    </ResponseField>

    <ResponseField name="dispose" type="() => void">
      Releases the hook token for reuse. After calling, the hook will no longer receive events.
    </ResponseField>

    <ResponseField name="[Symbol.dispose]" type="() => void">
      Implements TC39 Explicit Resource Management. Called automatically when using the `using` keyword.
    </ResponseField>
  </Expandable>
</ResponseField>

## Usage

### Basic Hook

Create a hook and await a single payload:

```typescript theme={null}
export async function workflowWithHook() {
  "use workflow";

  const hook = createHook<{ message: string }>();
  console.log('Hook token:', hook.token);

  const payload = await hook;
  console.log('Received:', payload.message);
}
```

### Hook with Custom Token

Use a predictable token that external systems can reconstruct:

```typescript theme={null}
export async function slackBot(channelId: string) {
  "use workflow";

  // One workflow run per channel
  const hook = createHook<SlackMessage>({
    token: `slack_webhook:${channelId}`,
  });

  for await (const message of hook) {
    console.log('Received message:', message);
  }
}
```

### Hook with Metadata

Attach additional context to the hook:

```typescript theme={null}
export async function workflowWithMetadata() {
  "use workflow";

  const hook = createHook<{ name: string }>({
    metadata: {
      type: "cat",
      color: "orange",
    },
  });

  const payload = await hook;
}
```

### Iterate Over Multiple Payloads

Receive multiple payloads using async iteration:

```typescript theme={null}
export async function workflowWithMultiplePayloads() {
  "use workflow";

  const hook = createHook<{ message: string }>();

  for await (const payload of hook) {
    console.log('Received:', payload.message);
    if (payload.message === 'done') {
      break;
    }
  }
}
```

### Explicit Resource Management

Use the `using` keyword for automatic disposal:

```typescript theme={null}
export async function workflowWithUsing() {
  "use workflow";

  {
    using hook = createHook<{ message: string }>();
    const payload = await hook;
    // hook is automatically disposed when the block exits
  }
}
```

### Manual Disposal

Release the token early:

```typescript theme={null}
export async function workflowWithDisposal() {
  "use workflow";

  const hook = createHook<{ message: string }>({
    token: 'my-token'
  });

  for await (const payload of hook) {
    if (payload.message === 'done') {
      hook.dispose(); // Release the token early
      break;
    }
  }
}
```

## Notes

* Can only be called inside a workflow function (with `"use workflow"`)
* Hooks implement AsyncIterable and can be used with `for await...of`
* Hooks implement the TC39 Explicit Resource Management proposal
* The token must be unique across all active hooks in your workflow runs
* Disposing a hook allows another workflow to register a hook with the same token

## Related

* [createWebhook](/api-reference/workflow/create-webhook) - Create a webhook for HTTP requests
* [defineHook](/api-reference/workflow/define-hook) - Define a typed hook with validation


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.