By default an n8n webhook answers "Workflow got started" as soon as it receives a request. That is fine for fire-and-forget events, but not when a form, an app or another system waits for a result. The Webhook node and the Respond to Webhook node let you return exactly what the caller needs: JSON, a status code, headers, a file or a redirect.
In short. In the Webhook node, set Respond to "Using 'Respond to Webhook' Node", then place a Respond to Webhook node where the answer is ready. It answers once, with the first item it receives: aggregate items first if you need to return a list. On n8n Cloud, answer within 100 seconds or the caller gets a 524 error.
The four response modes of the Webhook node
| Respond setting | What the caller receives | Use it for |
|---|---|---|
| Immediately | The response code and "Workflow got started" | Events where the sender only needs an acknowledgement |
| When Last Node Finishes | The output of the last node that ran | Simple linear workflows |
| Using 'Respond to Webhook' Node | Whatever the Respond to Webhook node sends | Branches, custom codes, files, redirects |
| Streaming response | Data streamed as the workflow runs | AI agent chats, with nodes that support streaming |
"When Last Node Finishes" has a Response Data option: All Entries, First Entry JSON, First Entry Binary or No Response Body.
Set up the Respond to Webhook node
- 1 In the Webhook node, set Respond to "Using 'Respond to Webhook' Node".
- 2 Add a Respond to Webhook node after the nodes that produce the answer.
- 3 Choose "Respond With": All Incoming Items, Binary File, First Incoming Item, JSON, JWT Token, No Data, Redirect or Text.
- 4 Add options if needed: Response Code, Response Headers, Put Response in Field.
Example JSON body with an expression:
Return a proper status code
APIs communicate through status codes. Use the Response Code option:
- 200 or 201 when the request succeeded or created something;
- 400 when the input is invalid (missing email, wrong format);
- 401 or 403 when authentication fails;
- 409 when the record already exists.
A typical pattern is an IF node right after the Webhook: one branch validates and processes, the other goes to a Respond to Webhook node with code 400 and a clear message such as {"error":"email is required"}.
The multi-item trap
The Respond to Webhook node runs once, using the first item it receives. If the previous node outputs 50 items, the caller gets one. Two documented solutions:
- Choose "All Incoming Items" in Respond With, which returns every item.
- Or put an Aggregate node before it ("All Item Data (Into a Single List)") to build one item that contains the list.
What happens in edge cases
The documentation lists the behaviour precisely:
- The workflow finishes without reaching a Respond to Webhook node: the caller receives a standard message with status 200.
- The workflow errors before the first Respond to Webhook node: the caller receives an error with status 500.
- A second Respond to Webhook node runs after the first: it is ignored.
So put the Respond to Webhook node on every branch that should answer, including your error path.
Return a file
Set Respond With to "Binary File" and select the binary property, for example a PDF generated earlier. Add a Content-Disposition response header if the browser should download it rather than display it:
Redirect the user
For form submissions from a website, "Redirect" sends the visitor to a thank-you page. Set Redirect URL to an absolute address.
HTML responses are sandboxed
Since n8n 1.103.0, HTML returned to a webhook is wrapped in a sandboxed iframe. JavaScript cannot access the top window or local storage, basic auth headers are not available inside, and relative URLs do not work. Use absolute URLs, or return JSON and render it on your own site.
Long-running workflows
On n8n Cloud, requests go through Cloudflare. If the webhook does not respond within 100 seconds, the caller receives a 524 error. For long jobs, the documentation recommends two webhooks: one that starts the job and answers immediately with a job ID, and a second one the caller polls for the result.
Worked example: a quote calculator API for your website
Your website has a small form: square metres and service type. You want an instant price shown on the page, computed by n8n.
- 1 Webhook: POST
/webhook/quote, Respond: "Using 'Respond to Webhook' Node", Allowed Origins (CORS):https://www.yoursite.com. - 2 IF:
{{ Number($json.body.sqm) > 0 && ['standard','premium'].includes($json.body.service) }}. - 3 Code (true branch): compute the price.
- 1 Respond to Webhook (true branch): JSON
{ "price": {{ $json.price }}, "currency": "USD" }, code 200. - 2 Respond to Webhook (false branch): JSON
{ "error": "sqm and service are required" }, code 400.
On the website, a few lines of JavaScript call the webhook and display the price:
The rates in this example are placeholders: use your own.
Respond Immediately, then keep working
For webhooks from payment providers or CRMs, the sender only needs a fast acknowledgement. Set Respond to "Immediately": n8n answers at once and the rest of the workflow keeps running. This avoids sender timeouts and retries, which can otherwise trigger the same workflow several times.
If you need to acknowledge first and still return a custom code, place a Respond to Webhook node right after the Webhook, then continue the work after it. Only the first Respond to Webhook node that runs is used.
Status codes worth using
| Code | Meaning for the caller | Example |
|---|---|---|
| 200 | OK, here is the result | Quote returned |
| 201 | Created | Lead created |
| 202 | Accepted, processing later | Long job started |
| 400 | Your input is wrong | Missing email |
| 401 / 403 | Not allowed | Bad or missing key |
| 409 | Conflict | Lead already exists |
| 429 | Slow down | Your own rate limit |
| 500 | Our side failed | Unexpected error |
Troubleshooting table
| Symptom | Likely cause | Fix |
|---|---|---|
| Caller always gets "Workflow got started" | Respond set to Immediately | Use Respond to Webhook node mode |
| Caller gets only the first record | Respond to Webhook uses the first item | Choose All Incoming Items, or Aggregate first |
| Caller gets 500 | Error before the Respond node | Add validation; check the failed execution |
| Browser blocks the call (CORS) | Origin not allowed | Set Allowed Origins (CORS) |
| HTML response looks broken | Sandboxed iframe since 1.103.0 | Absolute URLs, or return JSON |
| 524 on n8n Cloud | More than 100 seconds | Respond early, process after |
Production checklist
- A Respond to Webhook node on every branch, including validation failures.
- Status codes that match the outcome (200, 201, 400, 409).
- Lists aggregated or returned with "All Incoming Items".
- A response in under 100 seconds on n8n Cloud, or an asynchronous pattern.
Frequently asked questions
Why does my n8n webhook only return one item?
The Respond to Webhook node uses the first incoming item. Choose "All Incoming Items" or aggregate the items into one before responding.
How do I return a custom status code from an n8n webhook?
Use the Response Code option in the Respond to Webhook node, or in the Webhook node when you do not use Respond to Webhook.
What does n8n return if the workflow fails before responding?
An error with status 500, when the failure happens before the first Respond to Webhook node.
How long can an n8n webhook take to respond?
On n8n Cloud, less than 100 seconds, or the request fails with 524. Self-hosted limits depend on your proxy and server timeouts.
How do I return HTML from an n8n webhook?
Use Respond With "Text", which sends text/html by default. Since n8n 1.103.0 the HTML renders in a sandboxed iframe, so use absolute URLs and avoid scripts that access the parent window.
Can I set cookies or custom headers in the webhook response?
Yes, with the Response Headers option of the Respond to Webhook node.
What happens if two Respond to Webhook nodes run?
Only the first one is used; the second is ignored.
Tags
Steve founded PURIST, a workflow automation studio working with n8n, Make and Claude AI, and is the point of contact on every project. Prices and features in our articles come from vendor documentation and public pricing pages. How we research and score tools.