Skip to Content
BuildAction StepsRespond to Webhook
Reference

Respond to Webhook

Respond to Webhook (respondToWebhook) sends a custom HTTP response to the caller of a Webhook Trigger. Set the trigger’s When to respond mode to Using a Respond to Webhook step.

At a glance

Last verified: Nov 4, 2026
Use it to
Return a custom HTTP status code, headers, JSON/text body, or redirect to a waiting Webhook caller
Cost
1 Step credit per execution
Limits
1 MiB max response body · Caller waits up to 60 seconds
Find it
Tools → Data → Dev tools → Respond to Webhook
Output
{{ N.statusCode }}, {{ N.headers }}, {{ N.body }}
Instead
Webhook Trigger in When the last step finishes mode (when the final Step's output is the reply)
Applies to
All workspaces (Free & Paid)
Owner
Glow Docs & Engineering

In held-request mode (when the Webhook Trigger has When to respond set to Using a Respond to Webhook step), Glow holds the caller’s HTTP connection open for up to 60 seconds. When the first passing Respond to Webhook Step finishes, Glow sends its status code, headers, and body immediately. Downstream Steps continue running in the background. When When to respond is Immediately instead, a Live automation replies 200 OK with {"success": true}. A Draft automation returns 202 Accepted with {"received": true} without starting a run.

Webhook (Using a Respond to Webhook step)Lookup or transform dataRespond to WebhookBackground follow-up Steps

Setting it up

Set the Webhook Trigger to wait for this Step

Select your Webhook Trigger at Step 1 and set When to respond (responseMode) to Using a Respond to Webhook step.

Add Respond to Webhook

Open Tools → Data → Dev tools in the dock and select Respond to Webhook. Connect it on the branch that should reply to the caller.

Configure the response

Choose how to reply under Respond with (respondWith):

OptionValueFields & behavior
JSON (default)"json"Sends Body (body) as application/json (leave objects, lists, numbers, and booleans unquoted like "profile": {{ 2 }} to preserve native JSON types). Set Status code from 200 to 599 (default 200).
Text"text"Sends Body as text/plain; charset=utf-8 (unless you set a custom Content-Type header).
Redirect"redirect"Sends a Location header to Redirect URL (redirectUrl, must start with https://, up to 2,048 characters) with status 301, 302, 303, 307, or 308 (defaults to 302).
No body"noData"Sends status and headers with an empty body (Status code 204, 205, or 304 also send no body automatically).

Under Optional Props, add up to 50 Headers ({ name, value } pairs). Allowed headers include content-type, cache-control, content-language, etag, last-modified, expires, vary, retry-after, and custom x-* headers. Hop-by-hop, cookie, CORS, and security headers are refused.

Do not return credentials in a webhook response. Workspace secrets and API keys ({{ $secret.* }}, {{ $key.* }}, or sealed variables) are refused with SECRET_IN_UNSAFE_SINK.

What it passes on

The Step records the response it sent so downstream Steps (or your test trace) can inspect it:

ReferenceTypeWhat it holds
{{ N.statusCode }}NumberThe HTTP status code sent to the caller (for example 200 or 302).
{{ N.headers }}RecordNormalized lowercase map of the headers sent with the reply.
{{ N.body }}Text or nullThe exact response text sent, or null for No body and Redirect.

If multiple Respond to Webhook Steps run, the first passing Step sends the HTTP reply. Later executions record their output without overwriting the sent response.

Limits and held-request statuses

Callers can pass an optional x-glow-correlation-id request header when calling a held webhook (Using a Respond to Webhook step or When the last step finishes) to prevent duplicate executions on client retries. Every held-webhook error response returns a JSON object with {"error", "message", "executionId"}:

Limit or situationBehavior
Maximum held request wait60 seconds. If the Step has not run within 60 seconds, the caller receives 504 (error: "timeout") with executionId, and the run continues in the background.
Maximum response body size1 MiB (1,048,576 bytes). Larger or invalid bodies return 500 (error: "response_not_sendable") with executionId.
Run finishes without reaching Respond to WebhookThe caller receives 500 (error: "no_response") with executionId.
Run fails before reaching Respond to WebhookThe caller receives 500 (error: "workflow_failed") with executionId.
Request received but no run started (not_started)The caller receives 500 (error: "not_started") with executionId when the webhook was changed, turned off, or the run was refused.
Duplicate x-glow-correlation-id on a held webhook modeReturns 409 (error: "duplicate") with the existing run’s executionId immediately without starting a second run.

Examples to copy

Look up a customer record in a Data Store and return it synchronously as JSON, then log the access in the background:

  1. Set the Webhook Trigger at Step 1 to When to respond: Using a Respond to Webhook step.
  2. Add Data Store → Get a record (or create it) at Step 2 using {{ 1.body.customerId }} (with Include record details off so Step 2 outputs {"tier": "enterprise", "seats": 25}).
  3. Add Respond to Webhook at Step 3 with Respond with: JSON, Status code: 200, and Body:
{ "customerId": "{{ 1.body.customerId }}", "profile": {{ 2 }} }

Caller request (curl):

curl -X POST "https://api.getglow.ai/webhooks/wh_01J9..." \ -H "Content-Type: application/json" \ -H "x-glow-correlation-id: req-1042" \ -d '{"customerId": "cust_42"}'

HTTP response received by the caller (200 OK):

{ "customerId": "cust_42", "profile": { "tier": "enterprise", "seats": 25 } }

Verify it works

Run
Set the Webhook Trigger to Using a Respond to Webhook step, configure Status code 200 and a JSON body, and run a test
You should see
The Step outputs {{ N.statusCode }}, {{ N.headers }}, and {{ N.body }}, and the test trace records the webhook response.

What’s Next?


Search documentation

Start with a guide, or search by Step, task or error.