---
title: createWebhook
description: Create webhooks to suspend and resume workflows via HTTP requests.
type: reference
summary: Use createWebhook to suspend a workflow until an HTTP request is received at a generated URL.
prerequisites:
  - /docs/foundations/hooks
related:
  - /docs/api-reference/workflow/create-hook
---

# createWebhook



Creates a webhook that can be used to suspend and resume a workflow run upon receiving an HTTP request.

Webhooks provide a way for external systems to send HTTP requests directly to your workflow. Unlike hooks which accept arbitrary payloads, webhooks work with standard HTTP `Request` objects and can return HTTP `Response` objects.

<Callout type="warn">
  `createWebhook()` creates a public endpoint at `/.well-known/workflow/v1/webhook/:token`, and the token in that URL is the only authorization performed for incoming requests resuming that webhook. This is convenient for prototypes and simple resume links because it avoids creating another route, but if you need stronger security, prefer [`createHook()`](/docs/api-reference/workflow/create-hook) behind your own route and authorize the request before calling [`resumeHook()`](/docs/api-reference/workflow-api/resume-hook) to avoid unauthenticated workflow resumptions.
</Callout>

```ts lineNumbers
import { createWebhook } from "workflow"

export async function webhookWorkflow() {
  "use workflow";
  // `using` automatically disposes the webhook when it goes out of scope
  using webhook = createWebhook();  // [!code highlight]
  console.log("Webhook URL:", webhook.url);

  const request = await webhook; // Suspends until HTTP request received
  console.log("Received request:", request.method, request.url);
}
```

## API Signature

### Parameters

<TSDoc
  definition={`
import { createWebhook } from "workflow";
export default createWebhook;`}
  showSections={['parameters']}
/>

### Returns

<TSDoc
  definition={`
import { createWebhook } from "workflow";
export default createWebhook;`}
  showSections={['returns']}
/>

The returned `Webhook` object has:

* `url`: The HTTP endpoint URL that external systems can call
* `token`: The unique token identifying this webhook
* Implements `AsyncIterable<RequestWithResponse>` for handling multiple requests

The `RequestWithResponse` type extends the standard `Request` interface with a `respondWith(response: Response)` method for sending custom responses back to the caller.

## Examples

### Basic Usage

Create a webhook that receives HTTP requests and logs the request details:

```typescript lineNumbers
import { createWebhook } from "workflow"

export async function basicWebhookWorkflow() {
  "use workflow";

  using webhook = createWebhook(); // [!code highlight]
  console.log("Send requests to:", webhook.url);

  const request = await webhook;

  console.log("Method:", request.method);
  console.log("Headers:", Object.fromEntries(request.headers));

  const body = await request.text();
  console.log("Body:", body);
}
```

### Responding to Webhook Requests

Use the `respondWith()` method to send custom HTTP responses. Note that `respondWith()` must be called from within a step function:

```typescript lineNumbers
import { createWebhook, type RequestWithResponse } from "workflow"

async function sendResponse(request: RequestWithResponse) { // [!code highlight]
  "use step"; // [!code highlight]
  await request.respondWith( // [!code highlight]
    new Response(JSON.stringify({ success: true, message: "Received!" }), { // [!code highlight]
      status: 200, // [!code highlight]
      headers: { "Content-Type": "application/json" } // [!code highlight]
    }) // [!code highlight]
  ); // [!code highlight]
} // [!code highlight]

export async function respondingWebhookWorkflow() {
  "use workflow";

  using webhook = createWebhook();
  console.log("Webhook URL:", webhook.url);

  const request = await webhook;

  // Send a custom response back to the caller
  await sendResponse(request);

  // Continue workflow processing
  const data = await request.json();
  await processData(data);
}

async function processData(data: any) {
  "use step";
  // Process the webhook data
  console.log("Processing:", data);
}
```

### Waiting for Multiple Requests

You can also wait for multiple requests by using the `for await...of` syntax.

```typescript lineNumbers
import { createWebhook, type RequestWithResponse } from "workflow"

async function sendAck(request: RequestWithResponse, message: string) {
  "use step";
  await request.respondWith(
    Response.json({ received: true, message })
  );
}

async function processEvent(data: any) {
  "use step";
  console.log("Processing event:", data);
}

export async function eventCollectorWorkflow() {
  "use workflow";

  using webhook = createWebhook({ respondWith: "manual" });
  console.log("Send events to:", webhook.url);

  for await (const request of webhook) { // [!code highlight]
    const data = await request.json();

    if (data.type === "done") {
      await sendAck(request, "Workflow complete");
      break;
    }

    await sendAck(request, "Event received");
    await processEvent(data);
  }
}
```

## Related Functions

* [`createHook()`](/docs/api-reference/workflow/create-hook) - Lower-level hook primitive for arbitrary payloads
* [`defineHook()`](/docs/api-reference/workflow/define-hook) - Type-safe hook helper
* [`resumeWebhook()`](/docs/api-reference/workflow-api/resume-webhook) - Resume a webhook from an API route


## Sitemap
[Overview of all docs pages](/sitemap.md)
