Start with the request that failed
Find the first point where the request stops matching what you expected. Check the sender, the webhook, the workflow run and the response in that order. Changing all four at once makes the next result harder to explain.
Record the request time, HTTP method, URL type, status and execution ID if one exists. Use a harmless request ID to match the sender's log to n8n. Leave credentials and customer data out of screenshots.
These six examples use invented data in a separate workflow you own. The outputs are expected results for you to test, not results from a running Quintera installation. Documentation was checked on September 26, 2026; older versions may use different labels.
Start with a Webhook node connected directly to a Respond to Webhook node. Select Using 'Respond to Webhook' node in the Webhook node's Respond setting. Confirm this small workflow works before adding the steps that update your business systems.
Use the symptom to choose the first check
| What you see | Check first | Evidence to keep |
|---|---|---|
| Test worked yesterday; no run today | Test listener and copied URL | Listener state and request time |
| Production sends an old value | Published version and destination URL | Publication state and response body |
| Request is rejected before a run | Method, authentication and network path | Sanitized headers and actual status |
| A run exists but the caller sees an error | First failed node and response branch | Execution ID and node error |
| Caller sees success but no record appears | What the success response promises | Response body and destination record ID |
| Two records appear for one event | Repeated delivery and duplicate handling | Sender event ID in both runs |
A status code is a clue, not a full diagnosis. A proxy, the sender or n8n can produce the response. Compare their timestamps before deciding which component failed.
Example 1: The test URL worked once, then stopped
Suppose your HTTP client sent one successful request yesterday. Today the same saved URL returns an error and the editor shows no new input.
Setup: Create a Webhook node with HTTP Method POST and a path such as delivery-intake-example. Copy the node's actual Test URL. Configure the Respond to Webhook node to return JSON with Response Code 200 and this Response Body:
{"received": true, "mode": "test"}Choose Listen for Test Event, then use your HTTP client to send the following request to that copied URL. Include whatever authentication your workflow requires.
Method: POST
Content-Type: application/json
Body: {"request_id":"REQ-104","title":"Beacon review"}Expected result: The editor receives the request and the client receives your JSON response. The test listener is temporary: n8n documents a 120-second listening window. Restart the listener before retrying an expired test URL. A production sender should use the Production URL after publication. See n8n's test and production workflow guidance.
Edge check: Pasting the URL into an address bar sends a different kind of request from your POST test. Use the same method, headers and body as the sender you are investigating. Do not treat an address-bar result as proof that the POST endpoint is broken.
Keep the client's complete response beside the editor result. If the editor receives REQ-104 but your client shows a different response, check which Respond node ran. If neither has evidence of the request, compare the copied URL with the client's destination character by character. A trailing path segment or an old host name can send it somewhere else.
Example 2: Production still returns the old response
Your test response says version two, but the external service still receives version one. First confirm that its saved endpoint is the Production URL from this exact workflow, not another workflow with a similar name.
Setup: In a private diagnostic workflow, set the response body to the first value below and publish it. Then change the response body to the second value without publishing again.
Published response: {"version":"v1"}
Edited response: {"version":"v2"}Expected result: A production request still receives v1. In current n8n, edits autosave, but production uses the published version. Click Publish, complete the publication dialog and wait for completion. Then repeat the same production request and expect v2. If the header says Published, partial, inspect the failed triggers rather than assuming every webhook registered. See current save and publish behavior.
Production requests do not populate the editor canvas like test requests. Look in Executions. The Webhook node documentation explains where each mode appears.
Edge check: Another workflow cannot register the same path and method. Give your diagnostic workflow its own path if there is a conflict. Do not unpublish an unrelated working workflow to make a test pass.
For this test, record the publication state, then send a new request after publication finishes. A run started earlier is poor evidence of the new version. Also check every place that stores the destination URL: a form setting, an integration connection and a testing tool may each hold a different copy.
Example 3: The URL is right, but the request is rejected
A form integration may be calling the correct Production URL with the wrong method or without the required header. Check the actual outgoing request in the sender's logs, not only its setup screen.
Setup: Keep the webhook method as POST. For an owned test endpoint, choose Header Auth and configure a credential with header Name X-Webhook-Key and a private Value. Configure your HTTP client with that same name and value. n8n supports header authentication through its Webhook credentials. See the credential fields.
Input: Reuse the REQ-104 body from example 1. Send it with the configured header. Then deliberately omit that header for a separate test, without changing the workflow's authentication.
Expected result: The correctly authenticated request reaches the workflow. The missing-header request is rejected and must not perform the business action. Capture the actual status and response text; an authentication failure from n8n and one from a proxy can look different.
Edge check: Repeat with GET instead of POST. That method should not trigger this POST-only webhook. n8n matches the configured method; multiple methods require the separate node option. See method and registration checks.
Keep secret values in private credentials and your client's protected configuration. Do not paste them into a public URL, article, screenshot or support ticket.
Change one thing per request. First keep POST and remove only the credential header. Next restore the header and change only the method. Write down which request reached an execution. This separates authentication from routing instead of guessing from a single error screen.
Example 4: The request arrives, but the response is misleading
A successful HTTP response is only useful if the sender knows what it means. For this exercise, make it mean that a request ID passed validation. It does not mean a customer record was saved or a job finished.
Setup: Add an If node after the Webhook node. This example assumes application/json input parsed under body, with raw-body and binary handling off. Confirm that input shape in the Webhook output first. Add a Boolean condition using the following expression and compare it with true. It accepts a nonempty text ID after trimming whitespace:
{{ typeof $json.body?.request_id === 'string' && $json.body.request_id.trim().length > 0 }}Connect each branch to its own Respond to Webhook node. Use JSON responses and configure the true branch as status 200, the false branch as status 400.
True branch body: {"validated":true}
False branch body: {"error":"request_id must be nonempty text"}| Request body | Expected response |
|---|---|
{"request_id":"REQ-104"} | 200, validated true |
{} | 400, validation error |
{"request_id":null} | 400, validation error |
{"request_id":" "} | 400, validation error |
{"request_id":104} | 400, validation error |
Each request should reach one intended response branch. n8n ignores a second response after the first. If the workflow finishes without reaching a response node, it returns a standard 200 message; an error before that node returns 500. A generic 200 therefore does not prove your validation branch ran. See Respond to Webhook behavior.
Test both branches before reconnecting real work. Keep the validation response small so the result is easy to recognize. If you later return validated: true after saving a record, update the contract and test the save-failed branch too. The word you return should describe what actually completed.
Example 5: The request arrives, but the ID is in the wrong place
The sender says it included an ID. Your validation still returns 400. Open the Webhook output and compare its shape with the field your expression reads.
Send this JSON body with POST and Content-Type: application/json to the validation workflow from example 4:
{"data":{"request_id":"REQ-104"}}The ID is nested inside data. The existing check reads $json.body.request_id, so its expected result is false. That is a mapping problem, not an authentication failure.
Fix the sender for this exercise: Put the field where the receiving contract expects it, then resend:
{"request_id":"REQ-104"}The expected response is now 200 with validated: true. If the sender's documented format must stay nested, deliberately change your receiving mapping instead. Agree on one format rather than accepting any field that looks similar.
Also test Request_ID instead of request_id, and an empty array instead of an object. Neither satisfies the existing check. Leave raw-body and binary options off for this JSON exercise. Those options change how incoming content is handled. See the Webhook node's body options.
Example 6: The sender retries and creates the work twice
A timed-out caller cannot always tell whether your workflow started the work. The same event may arrive again. Give each event a stable ID and decide which run is allowed to create the business record.
Input for both deliveries:
{"event_id":"EVT-801","request_id":"REQ-104"}Here is one design for a team that already uses PostgreSQL. Create a separate test table, webhook_receipts, with text columns sender_key, event_id, request_id and status. Require non-null values and a unique constraint on (sender_key, event_id). Set the sender key from trusted workflow configuration, not from a caller's claim.
Validate event_id as nonempty text too. Keep the same event ID for retries. Directly after the valid branch, use a Postgres node with Execute Query. This query records a new receipt and returns one Boolean row:
WITH inserted AS (
INSERT INTO webhook_receipts
(sender_key, event_id, request_id, status)
VALUES ($1, $2, $3, 'received')
ON CONFLICT (sender_key, event_id) DO NOTHING
RETURNING event_id
)
SELECT EXISTS (SELECT 1 FROM inserted) AS is_new;In Query Parameters, pass the trusted sender key, incoming event ID and request ID in that order. For the body shape above, use this expression:
{{ ['delivery-intake', $json.body.event_id, $json.body.request_id] }}Use parameters rather than building SQL from the message text. See n8n's Postgres query settings. The unique constraint and ON CONFLICT decide which insert succeeds. See PostgreSQL's INSERT documentation.
Expected checks: The first delivery returns is_new: true. The identical repeat returns false. Only the true branch may start new work. On false, read the existing receipt and return its known state. If the same event ID contains a different request, stop for review instead of silently treating it as the original.
Repeat the test with two requests sent close together. Then simulate failure after recording the receipt but before completing the work. A receipt is not proof of completion. Keep failed or uncertain work visible for recovery; do not report success or rerun an external action blindly. This database check alone does not guarantee that every downstream action happens exactly once.
If those examples work, check the business steps
Add the remaining steps one at a time and record the first change that breaks the expected response. A timeout can happen after the webhook accepted the request. n8n Cloud documents a 100-second webhook response limit, after which the caller can receive 524. Long jobs need a deliberate acknowledgement and status-check design. See the timeout guidance.
Before enabling retries on a workflow that creates records, decide how repeated delivery of the same request ID will be handled. A caller that timed out may retry work that already started. Return success only for the meaning you documented, and keep business completion separate from receipt.
For self-hosted installations behind a reverse proxy, also check the public URL, HTTPS routing and proxy configuration with the host administrator. Changing a workflow body will not fix an incorrectly advertised external address. Use n8n's reverse-proxy URL guidance.
For help, bring a sanitized request, its timestamp and status, the published version and the relevant execution. That is enough to investigate without sharing a mailbox export or a production credential.
Finish with a repeatable test and a short handover
Keep a small request set that the next maintainer can run without using customer data. Record expected results before testing:
- Valid authenticated POST reaches one intended workflow and response.
- Missing authentication and the wrong method do not perform the business action.
- Missing, blank, numeric and wrongly nested IDs take the rejection path.
- A newly published response appears on a fresh production request.
- A repeated event does not create another business record.
- A downstream failure stays visible and does not claim completion.
For each result, save the time, request ID, response and execution ID. Note the URL owner, the response contract, the person who handles failures and the rule for retrying uncertain work. Keep credentials in the configured secret store. This gives someone else enough information to fix the next failure without rebuilding the whole workflow.
Sources
Primary documentation checked September 26, 2026.
Need help with this in your business?
Tell Felipe which tools you use, what keeps going wrong and what you want to improve. We can use a free 20-minute call to discuss a useful first project.
Prepare a project briefPrefer email? felipe@getquintera.com. No booking, purchase or automatic submission.