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

# defineHook

> Define a typed hook with input validation and transformation

Defines a typed hook for type-safe hook creation and resumption. This provides compile-time type safety and optional runtime validation using a schema.

## Signature

```typescript theme={null}
function defineHook<TInput, TOutput = TInput>(options?: {
  schema?: StandardSchemaV1<TInput, TOutput>;
}): TypedHook<TInput, TOutput>
```

## Parameters

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

  <Expandable title="properties">
    <ParamField path="schema" type="StandardSchemaV1<TInput, TOutput>" optional>
      Schema used to validate and transform the input payload before resuming the hook.
      Must conform to the [Standard Schema](https://github.com/standard-schema/standard-schema) specification.
    </ParamField>
  </Expandable>
</ParamField>

## Type Parameters

<ParamField path="TInput" type="type">
  The type of the input payload when resuming the hook from external contexts.
</ParamField>

<ParamField path="TOutput" type="type" default="TInput">
  The type of the output payload received in the workflow after validation/transformation.
</ParamField>

## Returns

<ResponseField name="TypedHook" type="TypedHook<TInput, TOutput>">
  An object with `create` and `resume` methods.

  <Expandable title="properties">
    <ResponseField name="create" type="(options?: HookOptions) => Hook<TOutput>">
      Creates a new hook with the defined output type. Only available inside workflow functions.
    </ResponseField>

    <ResponseField name="resume" type="(token: string, payload: TInput) => Promise<HookEntity>">
      Resumes a hook by sending a payload with the defined input type. Only available outside workflow functions (e.g., API routes).
    </ResponseField>
  </Expandable>
</ResponseField>

## Usage

### Basic Typed Hook

Define a hook with a specific payload type:

```typescript theme={null}
import { defineHook } from 'workflow';

// Define the hook type
const approvalHook = defineHook<{
  approved: boolean;
  comment: string;
}>();

// In a workflow
export async function workflowWithApproval() {
  "use workflow";

  const hook = approvalHook.create();
  console.log('Approval token:', hook.token);
  
  const result = await hook;
  // result is fully typed as { approved: boolean; comment: string; }
  
  if (result.approved) {
    console.log('Approved:', result.comment);
  }
}

// In an API route
export async function POST(request: Request) {
  const { token, approved, comment } = await request.json();
  
  // Type-safe resume
  await approvalHook.resume(token, { approved, comment });
  
  return Response.json({ success: true });
}
```

### Hook with Schema Validation

Validate and transform input using Zod:

```typescript theme={null}
import { defineHook } from 'workflow';
import { z } from 'zod';

const userSchema = z.object({
  email: z.string().email(),
  age: z.number().min(18),
  name: z.string().optional(),
});

const userHook = defineHook<
  z.input<typeof userSchema>,
  z.output<typeof userSchema>
>({
  schema: userSchema,
});

// In a workflow
export async function userSignup() {
  "use workflow";

  const hook = userHook.create();
  const user = await hook;
  // user.email, user.age, user.name are properly typed
  
  console.log('User signed up:', user.email);
}

// In an API route
export async function POST(request: Request) {
  const { token, ...data } = await request.json();
  
  try {
    // Schema validation happens automatically
    await userHook.resume(token, data);
    return Response.json({ success: true });
  } catch (error) {
    // Validation errors are thrown
    return Response.json({ error: error.message }, { status: 400 });
  }
}
```

### Hook with Transformation

Transform input data before it reaches the workflow:

```typescript theme={null}
import { defineHook } from 'workflow';
import { z } from 'zod';

const timestampSchema = z.object({
  message: z.string(),
  timestamp: z.string().transform((str) => new Date(str)),
});

const eventHook = defineHook<
  z.input<typeof timestampSchema>,
  z.output<typeof timestampSchema>
>({
  schema: timestampSchema,
});

// In a workflow
export async function eventProcessor() {
  "use workflow";

  const hook = eventHook.create();
  const event = await hook;
  // event.timestamp is a Date object
  
  console.log('Event time:', event.timestamp.toISOString());
}
```

### Separate Input and Output Types

Use different types for input and output:

```typescript theme={null}
import { defineHook } from 'workflow';
import { z } from 'zod';

const paymentSchema = z.object({
  amount: z.string().transform((str) => parseFloat(str)),
  currency: z.string().toUpperCase(),
});

const paymentHook = defineHook<
  { amount: string; currency: string },
  { amount: number; currency: string }
>({
  schema: paymentSchema,
});

// In a workflow
export async function processPayment() {
  "use workflow";

  const hook = paymentHook.create();
  const payment = await hook;
  // payment.amount is a number, payment.currency is uppercase
}

// In an API route
export async function POST(request: Request) {
  const { token, amount, currency } = await request.json();
  
  // Input is string
  await paymentHook.resume(token, { amount: "10.50", currency: "usd" });
  
  return Response.json({ success: true });
}
```

### Extract Input Type

Use the TypedHook.Input helper:

```typescript theme={null}
import { defineHook, type TypedHook } from 'workflow';

const myHook = defineHook<{ message: string }>();

// Extract the input type
type MyHookInput = TypedHook.Input<typeof myHook>;
// MyHookInput is { message: string }

function sendMessage(input: MyHookInput) {
  // ...
}
```

## Notes

* The `create()` method can only be called inside a workflow function
* The `resume()` method can only be called outside a workflow function (e.g., API routes)
* If a schema is provided, validation errors will be thrown when calling `resume()`
* Schemas must conform to the [Standard Schema](https://github.com/standard-schema/standard-schema) specification
* Popular schema libraries like Zod, Yup, and Valibot are compatible

## Related

* [createHook](/api-reference/workflow/create-hook) - Create an untyped hook
* [createWebhook](/api-reference/workflow/create-webhook) - Create a webhook for HTTP requests


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