Hand out one URL and let the outside world start your workflow
Every trigger so far has been n8n making the move: you press a button, a clock strikes, or n8n goes out and asks a service whether anything is new. This part turns the arrow around. A form is submitted, a LINE bot receives a message, a door sensor trips, someone pushes to GitHub — all of it reaches n8n through the Webhook node. It is also the last part of the series, so stay to the end.
One mode has been missing all along
Lay the triggers from the earlier parts side by side and something stands out.
- Manual Trigger (Part 7) — the workflow only moves when you press the button.
- Schedule Trigger — the time comes and the workflow moves by itself.
- Gmail / Slack / Sheets Trigger (Part 8) — the SaaS side has a new event, and n8n polls for it on a timer to bring it back.
- The
HTTP Requestnode (Part 9) — n8n goes out and calls someone else's API.
What they share is that n8n is always the one making the move. One mode is missing: an outside system wants to wake your workflow up. That is exactly what the Webhook node does.
A Schedule Trigger is an alarm clock — it goes off when the time comes, whether or not anything happened. The HTTP Request node is you picking up the phone to ask somebody a question. The Webhook node is a doorbell. You are not watching the door and you are not phoning anyone. Somebody arrives, presses it, and you know about it.
flowchart LR
subgraph IN["This part: something outside makes the move"]
direction LR
D["A form, a LINE message,
a door sensor, a git push,
a payment"] --> E["Webhook node,
one URL, always answering"]
E --> F["The rest of your workflow"]
end
subgraph OUT["Parts 7 to 9: n8n makes the move"]
direction LR
A["A clock, or you
pressing the button"] --> B["Your n8n workflow"]
B --> C["Somebody else's API,
called by HTTP Request"]
end
Webhooks come up in far more situations than you would expect:
AI Agent (Part 16) produces the reply and it goes back to LINE.Put simply: if the other system has a “webhook” or “callback URL” field you can fill in, it can call into n8n. When you add a Webhook node to a workflow, n8n hands you a URL that looks like this:
https://n8n.woowtech.io/webhook/form-abc123Anyone who calls that URL — a person, a server, LINE, Home Assistant, a curl command — triggers your workflow. Everything that comes in becomes the $json of the first item, so the nodes after it can pull values out with an ordinary expression such as {{ $json.name }}. Three places hold the incoming pieces, and knowing which is which saves you the most common mapping mistake:
| Where it lands | What is in it | A field would be read as |
|---|---|---|
$json.body | The body of the request — JSON or form data sent with POST, PUT or PATCH | {{ $json.body.name }} |
$json.query | The query string, the ?key=value part after the URL | {{ $json.query.token }} |
$json.headers | The request headers, including any signature header the caller adds | {{ $json.headers['content-type'] }} |
In other words, the Webhook node turns your workflow into a simple HTTP API. Any service that knows the URL can trigger it. That is also why Zapier and Make each ship a webhooks trigger of their own — it is the bridge every automation platform shares.
Webhook node and the HTTP Request node are a symmetric pair. HTTP Request is n8n calling out; Webhook is somebody calling in. Opposite directions, the same HTTP idea underneath. If Part 9 made sense, this one will too.Webhook node that receives real data, a clear head about the difference between the Test URL and the Production URL, auth set up so strangers cannot hammer it, a custom response through the Respond to Webhook node, and one run where data genuinely arrives from outside.Two URLs, and the one that quietly stops listening
Open the Webhook node's settings panel and you see two URLs. This is the first real trap, and it catches almost everybody once.
| Type | When it is live | What it is for | How long it stays live |
|---|---|---|---|
| Test URL | Only after you press the Listen for test event button inside the node | Testing while you build — press the button, call it once, see what the incoming data looks like | It starts listening when you press the button and closes itself after one event. With no event, the docs state no timeout, but in practice it stops after about two minutes; pressing again reopens it |
| Production URL | Live permanently once the workflow is Active — the toggle at the top right is on | Going live — the URL you hand to an outside service for the long term | Live for as long as the workflow stays Active. Turn Active off and it is a 404 |
Three differences between them are small on the screen and large in practice:
- The paths differ. The Test URL is usually
/webhook-test/xxxand the Production URL is/webhook/xxx. Look carefully at which one you are copying out of the node panel. - The Test URL takes one event and then closes itself. That suits tweaking fields and reading the shape of the incoming data, one call at a time.
- The Production URL does not show up as a live preview on the canvas. To see the runs that really happened, open the Executions tab.
The Test URL is you standing by the intercom while an engineer downstairs checks it works. The moment you walk away, ringing it does nothing at all. The Production URL is the buzzer wired into the wall. Handing a customer the first one is why nothing ever comes through: by the time they got round to using it, you had long since walked away from the intercom.
stateDiagram-v2
direction LR
[*] --> Saved
Saved --> Listening: press Listen for test event
Listening --> Saved: one event arrives, or nothing arrives for about two minutes
Saved --> Active: Save, then switch Active on
Active --> Saved: switch Active off
note right of Listening
The Test URL answers here, and nowhere else
end note
note right of Active
The Production URL answers for as long as this lasts
end note
/webhook/, not /webhook-test/.Note the honest wrinkle in that table. The documentation says the listen session has no timeout; what people actually see is that it stops after roughly two minutes when nothing arrives. Both statements are in the source material and they do not agree, so do not build anything around the exact number — if the node has gone quiet, press the button again and move on.
Catch a form submission and put it in a Google Sheet
The most classic starter example, and the most immediately useful: expose one URL, let a web form POST what the user typed, and have n8n write it into Google Sheets automatically. Once this works you can wire it straight to the contact form on your own site or landing page. The whole thing is two nodes: an outside POST hits the Webhook node, and the data flows on to the next node to do the work.
-
Step 1
Create a workflow and make Webhook the first node
Top right,
+ Add workflow, and you land on an empty canvas. Click the+in the middle, search the nodes panel forWebhook— it sits under the Triggers category — and add it. -
Step 2
Set the HTTP Method and the Path
With the
Webhooknode open, set HTTP Method toPOST, because a form sending data in uses POST by default. Then give Path any memorable English name —form-contact, say. It is appended to the end of the URL. As soon as that is set, the bottom of the node panel shows both URLs:Test URL: https://n8n.woowtech.io/webhook-test/form-contactProduction URL: https://n8n.woowtech.io/webhook/form-contact -
Step 3
Press Listen for test event and call it once with curl
Press Listen for test event at the top right of the node. It goes into waiting mode — it ends by itself after the first event, and in practice it also stops after about two minutes if nothing arrives. Open a terminal and send fake data to the Test URL:
curl -X POST https://n8n.woowtech.io/webhook-test/form-contact \
-H "Content-Type: application/json" \
-d '{"name":"Wang Xiaoming","email":"[email protected]","message":"I would like a quote"}'Back on the canvas, the
Webhooknode turns green and the output panel on the right shows the JSON you just sent. The moment you can see the data arrive, this step is finished. -
Step 4
Wire up a Google Sheets node set to Append Row
Add a
Google Sheetsnode after theWebhooknode and set Operation toAppend Row in Sheet. Pick your credential, creating one the first time round — Part 10 covers that. Choose a spreadsheet and a sheet that already has the columnsname,email,messageandreceived_at. -
Step 5
Map the fields, in Expression mode
Switch every field in the Columns block to Expression mode and map them like this:
name → {{ $json.body.name }}email → {{ $json.body.email }}message → {{ $json.body.message }}received_at → {{ $now.toISO() }}The
bodyin the middle of each one is the part people forget. TheWebhooknode does not flatten the request for you — it keeps the body under$json.body, the query string under$json.query, and the headers under$json.headers. Writing{{ $json.name }}here would quietly give you nothing. -
Step 6
Execute step, and check the Sheet really has a new row
Press Execute step on the
Google Sheetsnode. It sends the item theWebhooknode just received. Open Google Sheets and look for a row with that data in it. If it is there, the whole chain is connected. -
Step 7
Save, then switch Active on
Press Save at the top right, then flip the Active toggle at the top right to on. This step is the one people skip, and skipping it is why the Production URL answers 404.
-
Step 8
Verify by calling the Production URL once
Back in the terminal, call the Production URL this time — the same command with
/webhook-test/replaced by/webhook/:curl -X POST https://n8n.woowtech.io/webhook/form-contact \
-H "Content-Type: application/json" \
-d '{"name":"Li Xiaohua","email":"[email protected]","message":"Live submission"}'Another row appears in the Sheet. That URL is now ready to hand to an outside frontend engineer or a customer. For the history of what has come in, open the Executions tab in the sidebar.
The two dropdowns that decide almost everything
Once the URL exists, two settings do most of the work: which HTTP method the node answers on, and what n8n sends back to whoever called. Get either wrong and the symptoms look nothing like the cause.
HTTP Method: which one to use when
The HTTP Method dropdown offers GET, POST, PUT, PATCH, DELETE and HEAD. In practice you use the first two often; the rest come up when you are building a REST-style API for somebody else.
| Method | What the caller does with it | Where the data is | Classic use |
|---|---|---|---|
GET | The outside system wants to look something up, or to trigger without carrying much data | The query string, the ?key=value after the URL; n8n keeps it in $json.query | A simple ping, a health check, testing by pasting the URL into a browser |
POST | The outside system sends new data in | The body, JSON or a form; n8n keeps it in $json.body | Form submissions, LINE webhooks, GitHub webhooks, payment callbacks — the one you use most |
PUT | The outside system replaces a whole record of some resource | The body | Only when you hand n8n to someone else as a REST API |
PATCH | The outside system partially updates some resource | The body | As above, for the case where only a few fields change |
DELETE | The outside system deletes some resource | The URL path or the query | As above; only a REST-style API needs it |
404 in one place and a 405 Method Not Allowed in another, so expect either depending on your build. What matters is the cause, which is the same in both cases: when incoming data is stuck, the first thing to confirm is that both sides use the same Method.POST in almost every situation. Use GET only when all you want is a “paste the URL in a browser and it fires” trigger, or when the other system's docs say plainly that they use GET, PUT or DELETE — in which case follow what they ask for.Respond: what n8n sends back, and who waits
The Respond option decides what HTTP response n8n returns when an outside call comes in. This matters more than it looks. Services like LINE, Slack and Stripe read what you return to judge whether the webhook succeeded. Answer wrong and they may retry, which gives you duplicate runs, or disable your webhook outright.
| Response mode | Behavior | When to use it |
|---|---|---|
Immediately |
n8n answers 200 OK with an empty body the moment the request arrives, and the workflow keeps running in the background |
The caller only cares that it arrived and does not read the content; or the workflow takes a long time — an AI Agent generating for 30 seconds — and you do not want to keep the caller waiting; or the caller is Stripe or GitHub and wants an answer within seconds |
When Last Node Finishes |
The whole workflow runs to the end, and the last node's output goes back as the response | The caller wants the result the workflow produced — a LINE bot receives a message and n8n sends the finished reply straight back. The workflow has to finish within a few seconds |
Using 'Respond to Webhook' Node |
You name the node in the middle of the workflow that does the answering — drop a Respond to Webhook node at the point you want to reply from |
When you need a custom response: the status code, the headers, the body and the content type are all yours to decide. The right choice when you are building an API for someone else |
Streaming Response |
It streams the answer back piece by piece, usually paired with a node like AI Agent that produces chunked content |
When you want a ChatGPT-style frontend that types out live, or a downstream that supports SSE or streaming |
A courier is at the door with a parcel. Immediately is signing for it and letting them drive off while you open the box in your own time. When Last Node Finishes is making them stand on the step while you unpack it and check the contents — fine if that takes ten seconds, pointless if it takes five minutes, because they will give up and mark it undelivered. Their patience, not yours, is what sets the limit.
sequenceDiagram participant S as The calling service participant W as Webhook node participant N as The nodes after it participant R as Respond to Webhook Note over S,R: Respond set to Immediately S->>W: POST, their timer starts W-->>S: 200 OK, empty body, at once W->>N: the rest runs in the background Note over S,R: Respond set to When Last Node Finishes S->>W: POST, timer still running W->>N: every node runs, caller waits N-->>S: the last node's output is the reply Note over S,R: Respond set to Using Respond to Webhook Node S->>W: POST W->>R: the run reaches the node you chose R-->>S: your status code, headers, body R->>N: anything wired after it runs on
The Respond to Webhook node is the key to that third mode. Put it after whichever node you want to answer from — it does not have to be the last one — and you get three settings:
| Setting | What you choose | Notes |
|---|---|---|
| Respond With | The shape of the answer: JSON, Text, Binary File, Redirect, JWT Token, No Data, All Incoming Items, First Incoming Item | Most APIs you build for other people answer JSON |
| Response Code | You type the number yourself | Common ones: 200 success, 201 created, 400 client error, 500 server error |
| Response Headers | Any headers you want on the reply | For example Content-Type: application/json, or CORS-related headers |
Respond to Webhook that are easy to trip over. It only handles the first incoming item — even if the node before it emits many, only the first is used for the reply. A second Respond to Webhook node in the same workflow is ignored. If the workflow runs to the end without passing through one at all, n8n answers a standard 200 by itself. And if it errors on the way and never reaches the node, it answers 500.Immediately. A LINE bot or a form that wants to see the reply means When Last Node Finishes. Building your own REST API means Using 'Respond to Webhook' Node.The services that will call you, and how to keep everyone else out
Almost every modern SaaS has a webhook feature. When they have an event to tell you about, they POST to a URL you name. Put your Webhook node's Production URL in that field and the two are wired together. These are the ones you meet most often.
| Source | How to set it up | Watch out for |
|---|---|---|
| Google Forms | Google Forms has no native webhook — you need Apps Script, or Zapier / Make as a bridge. Or switch to a form service with a native webhook, such as Tally or Typeform | If Google Forms is a must, you can also go through the Google Sheets Trigger, since form answers get written into a Sheet |
| LINE Official Account | LINE Developers Console → Messaging API channel → paste the n8n Production URL into Webhook URL. Turn on Use webhook | LINE wants a 200 within 3 seconds, so set Respond to Immediately; signature verification uses the X-Line-Signature header |
| Home Assistant | HA Automation → set Trigger to Webhook and give it a webhook_id. When HA fires — a door sensor, say — it calls the URL you named. It also works the other way round, with HA receiving a webhook on its own webhook trigger |
When HA calls out you pick the method and the body yourself, and they have to line up with the Webhook node's settings |
| Typeform / Tally | Paste the URL on the Integrations or Webhooks tab in the form settings. Every submission then calls your n8n | Their body follows their own schema, so use the Test URL to read the field paths clearly before you map them |
| GitHub / GitLab | Repo Settings → Webhooks → Add webhook → paste the n8n URL into Payload URL. Pick the events: push, PR, issue | GitHub sends a great many kinds of event, so use an IF node (Part 11) to filter down to the ones you care about |
| Slack slash command or event | Slack App settings → Slash Commands or Event Subscriptions → paste the n8n URL into Request URL | Slack also wants a 200 within 3 seconds; Event Subscriptions sends a verification challenge the first time, and you have to return the challenge field |
| Stripe / ECPay / TapPay | The webhook or notification URL setting in the payment provider's dashboard | Signature verification, idempotency and retries on failure all apply — always pick Immediately so a 200 goes back fast, and leave the real processing to the nodes behind it |
{{ $json.body.foo }} blind usually gives you undefined.Once the URL is out there, anyone can call it
That is not a figure of speech. Somebody malicious can stuff junk into your Sheet, fire an expensive AI Agent over and over, or send spam LINE messages on your account. There are several ways to protect it, from the simplest to the most advanced.
| Method | Where to set it | Security | When to use it |
|---|---|---|---|
| No auth, relying on a URL that is hard to guess | Webhook node, Authentication = None. Use a UUID or a long random string as the Path |
Low — the URL is the password | Only for internal services you trust, such as HA or an internal tool. Never put it in client-side JavaScript or in public documentation |
| Basic Auth | Set Authentication to Basic Auth and set a username and password |
Medium — the caller has to carry Authorization: Basic base64(user:pass) in the header |
Simple server-to-server cases, when the other side supports Basic Auth |
| Header Auth | Set Authentication to Header Auth and name the header and its value, for example X-Api-Key: your-secret-value |
Medium — with no header, or the wrong value, n8n answers 401 outright |
The convention for most modern APIs, and the general-purpose option we recommend most |
| JWT | Set Authentication to JWT Auth and set the secret and algorithm. n8n verifies the signature |
High — it comes with an expiry time and signature verification | The caller is a real system that can issue JWTs: enterprise SSO, a mobile app |
| HMAC signature verification | Set Authentication to None and use a Code node (Part 15) to compute the HMAC and compare it with the header |
High — every request carries a signature of its own | LINE, Stripe and GitHub all use this; implement it the way their docs describe |
An unguessable URL is a key under the mat. It genuinely stops the casual passer-by, and it is worth doing. It is not a lock. Header Auth is the lock. Keeping the URL quiet as well as setting a header is the whole point — you would not publish your address next to a photo of where the key lives and then feel safe because there is also a deadbolt.
Webhook node with no auth that is open to the world is easy prey for bots that scan for URLs. The usual symptoms are a sudden flood of Executions, runs you cannot explain, and the cost of AI or messaging nodes shooting up. The first thing to do when you see that: turn Active off, change the Path to a new long random string, add Header Auth, and switch it back on.A customer messages on LINE, and an AI Agent answers
This is where the whole series comes together in one build: Webhook to receive, AI Agent (Part 16) to think, HTTP Request (Part 9) to answer, an expression to grab the payload, and Credentials to hold the token. Every piece was learned in its own part; here they are simply joined into one line.
flowchart TD U["A customer types a message
in the LINE chat"] --> L["The LINE platform POSTs
to your Webhook URL"] L --> W["Webhook node
POST, path line-bot,
Respond set to Immediately"] W -.->|"200 back within 3 seconds"| L W --> A["AI Agent
with a Chat Model attached"] A --> H["HTTP Request
POST to the LINE Reply API"] H --> B["The reply appears
in the customer's chat"]
-
Step 1
Create a Messaging API channel in the LINE Developers Console
Go to
developers.line.bizand sign in, create a Provider, then add a Messaging API channel. Fill in the basics and submit. -
Step 2
Get the Channel Secret and the Access Token
Once the channel exists, go to the Basic settings tab and copy down the Channel Secret. At the bottom of the Messaging API tab, press Issue under Channel Access Token to generate one, and copy that too. Both of these go into n8n Credentials in a moment — not into a node parameter, and not into a note you paste into a group chat.
-
Step 3
New n8n workflow, with a Webhook node on POST
Create a new workflow and add a
Webhooknode: Method =POST, Path =line-bot, Respond =Immediately, because LINE wants a200within 3 seconds. Copy the Production URL for later — you cannot use it yet, since the workflow is not Active. For now press Listen for test event and build against the Test URL. -
Step 4
On the LINE side, paste the n8n URL into Webhook URL
Back in the LINE Console on the Messaging API tab → Webhook settings → paste the n8n Test URL → turn on Use webhook. Press Verify and it should say Success, because LINE really does call it once.
-
Step 5
Add the bot as a friend and send it a message
Scan the QR code shown in the LINE Console with your phone to add the Official Account as a friend, and send it a “hello”. Back on the n8n canvas, the
Webhooknode turns green and the output shows LINE's payload. Find the path to the message text. It is usually one of these:{{ $json.body.events[0].message.text }}{{ $json.body.events[0].replyToken }}{{ $json.body.events[0].source.userId }}The first is the text the user typed, the second is the token you reply with, and the third is the user's ID.
-
Step 6
Add an AI Agent node to produce the reply
Add an
AI Agentnode. Use an expression in its Text field to bring in the user's message:{{ $json.body.events[0].message.text }}. Attach a Chat Model — OpenAI GPT-4o mini, or another. Add Memory if you want it to remember the conversation. -
Step 7
Add an HTTP Request node to call the LINE Reply API
Add an
HTTP Requestnode: Method =POST, URL =https://api.line.me/v2/bot/message/reply, Authentication set to Header Auth, carryingAuthorization: Bearer <your-channel-access-token>. The body is JSON, with three values in it:Field Value Where it comes from replyToken"{{ $('Webhook').item.json.body.events[0].replyToken }}"$('Webhook')reaches back past theAI Agentnode to theWebhooknode's own itemmessages[0].type"text"A fixed value — this reply is a plain text message messages[0].text"{{ $json.output }}"$json.outputis the reply theAI Agentnode has just producedIn the JSON itself,
messagesis an array holding one object, so those last two rows sit together inside a single{ "type": ..., "text": ... }entry. -
Step 8
Save, switch Active on, then move LINE to the Production URL
Save, then switch Active on. Back in the LINE Console, change the Webhook URL from the Test URL to the Production URL — the one ending
/webhook/line-bot. Send another message from your phone, and the answer comes back in a second.
Read the status code first, then work backward
Almost every webhook fault announces itself in what the caller gets back. Start there and you can usually name the cause before you open a single node.
flowchart TD A["An outside call is not
reaching your workflow"] --> B{"What does the
caller get back?"} B -->|"nothing, on test"| B1["Listen mode is off.
Press it again"] B -->|"404"| C{"Is it Active?"} C -->|"no"| C1["Save, then
Active on"] C -->|"yes"| C2["Check the Path.
Case sensitive"] B -->|"405"| D["Methods differ.
Match both sides"] B -->|"401"| E["Auth header wrong.
Test it with curl"] B -->|"200, empty"| F["No Content-Type.
Ask for JSON"]
Each box names the cause and the first move. The table below is the long version of the same five answers: what to compare on the node, what to ask the caller to send, and the limits that start to bite once the traffic is real.
| Symptom | Cause | How to fix it |
|---|---|---|
| You called the Test URL and nothing happened; n8n received nothing | Either you did not press Listen for test event — the Test URL only lives in listen mode — or the listen session already ended, since it closes after one event and also stops when nothing arrives for a while | Press the button again. Also check you picked the right URL: when you copy, make sure it is the /webhook-test/ one |
Calling the Production URL returns 404 Not Found |
Almost always the workflow is not Active. While the toggle at the top right is off, the Production URL is a 404 | Save, then switch Active on. If it still 404s with Active on, check the Path matches what you are calling — it is case sensitive, and a stray space breaks it |
| The webhook arrives but the body is empty | Their request set no Content-Type, or set it to text/plain instead of application/json, so n8n will not parse it for you |
Ask them to add the Content-Type: application/json header, or turn on Options → Raw Body on the Webhook node and parse it yourself in a Code node. Note too that the node caps a single payload at 16MB — anything larger is rejected outright, so large files have to go through an upload URL or be sent in pieces |
You get 405 Method Not Allowed |
The method the caller uses does not match the node's setting: they POST while your node is set to GET, or the other way round | Open the node panel and set both sides to the same Method. Some outside services default to GET while you assumed POST, so test it by hand once with curl or Postman |
| The caller keeps retrying, and the same record is processed many times | The caller retries when it does not get a 200 in time. Usually you picked When Last Node Finishes and the workflow runs past their timeout — LINE 3 seconds, Stripe 3 seconds, GitHub 10 seconds |
Switch Respond to Immediately, so n8n answers 200 instantly and the processing carries on in the background |
| Calls come in too fast, n8n rejects them, and Executions queue up | An n8n instance has a concurrency limit. Too many calls in a short window and requests jam up or get rejected outright | Three options: turn on Queue Mode and add workers; pair it with Split In Batches or a Wait node to stagger the work; or split “receive and store” from “process afterwards” into two workflows, where the first only writes and answers fast and the second reads on a schedule |
Auth is on but the caller keeps getting 401 |
They typed the header name or the value wrong. It is case sensitive, and a stray space or a quote around the value makes it fail | Send the same header by hand with curl and test it once. The header name in their docs has to line up with the field name in the node. It can also simply be the wrong Authentication type — Basic where you set Header, say |
| Executions shows no record of the webhook firing | The Executions tab shows only recent successful runs by default | The filter at the top has Include failed; turn it on to see the failures. Beyond that, turn on Save Execution Progress in the workflow Settings to see the detail of each node. While you are building, set all three of Save Manual, Save Failed and Save Successful to Save |
Can crawlers find my Webhook URL, or can outsiders guess it and hammer it?
/webhook/form-abc123, say — is a guessable string like form-abc123, a scanning bot really can stumble onto it. Use a UUID as the path instead, something along the lines of /webhook/8f3b2c9a-..., and the odds get very low. Add Header Auth on top of that and it is safer still. If you are genuinely worried, treat the URL as only one lock and rely on auth or an IP allowlist as the second.How many Webhook nodes can one workflow have?
/webhook/order-create and /webhook/order-cancel, say — that go down different branches.What if the Webhook node's URL changes? Do the outside services have to be set up again?
Can an n8n Webhook trigger another n8n workflow?
HTTP Request node to call workflow B's Webhook URL, exactly as an outside service would — cleanly isolated, but with one round trip over HTTP. Or workflow A can use the Execute Workflow node, a Core node, to call workflow B directly, passing the data straight across without HTTP, which is faster. For internal calls pick Execute Workflow, which Part 14 covers; reach for an HTTP Request onto a webhook only when you cross instances or accounts.Does the Webhook node have a timeout? Will my workflow be cut off if it runs for 5 minutes?
Webhook node itself is not cut off — but the caller almost always has a timeout of its own: LINE 3 seconds, GitHub 10 seconds, Stripe a few seconds, a browser usually 30 to 60 seconds. Go past their timeout and they treat it as a failure, and may retry. The answer for long jobs is to set Respond to Immediately so a 200 goes back instantly and the real processing runs in the background, then notify separately or write the result back once it finishes.Do the Test URL and the Production URL use the same data format? Is it safe to go straight to Production once Test works?
How do I debug a webhook? What do I do when a call comes in and I see no log?
Set / Edit Fields (Set) node in as the first node that only passes data through, so at least the raw incoming data shows up in Executions.Can a webhook store the data and process it slowly, instead of chaining the processing nodes onto it?
Webhook node receives, it does exactly one thing — write into Google Sheets, Postgres, Redis or even an n8n Data Table — and answers 200 straight away with Immediately. Then build a separate Schedule Trigger workflow that reads the new data every minute and processes it. The caller always gets an instant answer, slow processing behind it changes nothing on their side, and a node dying does not lose data. This is the right architecture for high traffic or an unreliable third-party API.My node panel says something different from this page. Which do I trust?
What you can actually build now
That is the whole guide. From Part 1, what n8n is, to this one, the series took you from “I have heard of Zapier” to “I can wire up a LINE bot myself and give a workflow a brain that thinks.” Concretely, here is what you can do:
Build from nothing
Create a workflow, drop nodes in, and chain Trigger, Action and Core nodes into something that runs on a schedule or on a button press. Parts 5 to 7.
Connect what your company uses
Slack, Gmail, Google Sheets, Drive, and any service with an API at all through the HTTP Request node — with the credentials kept where they belong. Parts 8 to 10.
Control the flow
Write expressions to grab upstream data, branch with IF and Switch, and handle many items at once with Merge and split. Parts 10 and 11.
Make it survive contact
Handle errors, reshape data with Edit Fields (Set), pull reusable logic into a sub-workflow, and drop into a few lines of Code when the canvas runs out. Parts 12 to 15.
Give it judgment, and a door
Let an AI Agent decide what to do with a message, and let outside systems start the whole thing through a Webhook. Parts 16 and 17.
Know where to look
Read an execution, tell a caller-side fault from a callee-side one, and find the setting that explains what you are seeing rather than guessing at it.
The rest is doing it. The honest advice to finish on: find one thing your company has done over and over in the past three months — tidying a report by hand every morning, sending the same reminder email every week, replying to every LINE customer with the same canned message — and open a workflow that kills it off. The moment your first workflow goes live, you tend to realize it really did not need a person at all. And then you will not be able to stop.
And when you get stuck along the way:
- You forgot how to configure a node — go back to the part that covers it; the guide's contents list them all.
- A node has a red border and will not run — open its error message first, then the error-handling material in Part 12.
- You cannot find a setting — check the settings reference in the full guide rather than clicking through the panel at random.
- You want to go deeper on self-hosting — the guide's architecture appendix covers how it works underneath.
- Nobody has written about your exact problem — ask the official n8n community at
community.n8n.io. Plenty of people are walking the same road.
May your workflows all run smoothly, may they go live without incident, and may the automation land well enough that somebody notices.
Where to go from here
Your workflows can now be started by anything, including things that are not you.
The full guide keeps every part in one place, along with the settings reference, the error troubleshooting list and the architecture notes each part was built from.
Open the full guidePart 17 of the Woow n8n Onboarding Guide series on the Apporo blog.
Adapted from the Woow n8n Onboarding Guide, produced by WoowTech and released under CC BY 4.0. This adaptation is published by Apporo under the same licence.
Light · Air · Water · Control · apporo