At a Glance — Monday.com Webhooks in n8n
- Why webhooks fail: Monday.com sends a
{"challenge": "token"}on registration and expects your endpoint to echo it back immediately — if it doesn't, the webhook is marked failed and no events are sent - Fix: Set Webhook trigger Respond = "Using Respond to Webhook Node" + add an If branch that checks for the challenge field and echoes it before any other processing
- Two-branch structure: challenge branch (echo + stop) → event branch (process board data); both connect to the same Webhook trigger node
- Column value formats: status =
{"label":{"text":"Done"}}, date ={"date":"2026-08-28"}, person ={"personsAndTeams":[{"id":123,"kind":"person"}]} - Register via GraphQL: Use
create_webhookmutation with aconfigcolumn filter to fire only on specific column changes, not all board events - Production note: Activate your n8n workflow before registering the webhook in Monday.com — the challenge fires at registration time and won't wait for you to activate
The challenge verification problem
When you create a webhook in Monday.com (via their API or Integrations Center), Monday.com immediately sends a POST request to your endpoint with a body like this:
{"challenge": "abcdef123456"}
Monday.com expects your endpoint to respond synchronously with exactly that challenge value as JSON:
{"challenge": "abcdef123456"}
If your endpoint takes too long, returns a different response, or returns a 200 with no body, Monday.com marks the webhook as unverified and stops sending events. This is the source of the "webhook not firing" problem that fills the n8n community forum.
The fix is simple once you know what to look for: your n8n workflow needs to handle the challenge before doing anything else, and it must use the Respond to Webhook node to send the response while the workflow continues processing.
Workflow structure: two branches from the webhook
The correct n8n workflow structure for Monday.com webhooks has two parallel branches immediately after the Webhook trigger:
- Challenge branch — checks if the request body contains a
challengefield. If yes, responds immediately with{"challenge": "the-value"}and ends. - Event branch — handles the actual board event data (item created, status changed, etc.)
Add an If node after the Webhook trigger with the condition: {{ $json.body.challenge }} exists (or is not empty). The "true" branch handles the challenge; the "false" branch handles real events.
Key setting: On your Webhook trigger node, set Respond to Using Respond to Webhook Node. This is required for the Respond to Webhook node to work — if the Webhook is set to respond automatically, the Respond to Webhook node has no effect. Check this setting first if the challenge response isn't being sent.
Step 1 — Configure the n8n Webhook trigger
Add a Webhook trigger node to your workflow. Set:
- HTTP Method: POST
- Respond: Using Respond to Webhook Node
- Binary Property: leave unchecked (you want JSON, not binary)
Copy the webhook URL — you'll need it in Step 3. Activate the workflow (in test mode, use the "test URL"; for production, use the production URL and activate the workflow).
Step 2 — Add the challenge handler branch
Connect an If node to the Webhook. Set the condition to check for the challenge field:
- Value 1:
{{ $json.body.challenge }} - Operation: Is Not Empty
On the true output, add a Respond to Webhook node. Set the response body to:
{"challenge": "{{ $('Webhook').item.json.body.challenge }}"}
Set Content-Type to application/json and status code to 200. This branch terminates here — no further nodes needed on the challenge path.
On the false output, connect your actual workflow logic for processing board events.
Step 3 — Register the webhook in Monday.com
Monday.com webhooks can be registered two ways: through the Integrations Center UI, or via the GraphQL API.
Via Integrations Center (simpler)
In your Monday.com board, go to Integrate → Webhooks. Select the event type (item created, column changed, etc.), paste your n8n webhook URL, and click Add. Monday.com immediately sends the challenge request — your workflow must be active and the challenge branch must be in place before you click Add.
Via GraphQL API (more control)
Use the Monday.com GraphQL API to register webhooks programmatically:
mutation { create_webhook(board_id: YOUR_BOARD_ID, url: "YOUR_N8N_URL", event: change_column_value, config: "{\"columnId\":\"status\"}") { id board_id } }
The config parameter lets you filter to a specific column — useful when you want the webhook to fire only on status changes, not all column changes. Available events include: create_item, change_column_value, change_status_column_value, create_subitem, delete_item, and more.
Test mode vs. production: Monday.com will challenge your webhook URL when you register it. If your workflow is in test/listen mode in n8n, the test webhook URL is only active while n8n is waiting for a test execution. For the challenge to succeed automatically, either activate the workflow with the production URL, or be ready to click "Listen for Test Event" in n8n immediately before registering the webhook in Monday.com.
Step 4 — Parse Monday.com column values
Once the webhook is working and real events are flowing, the next hurdle is parsing Monday.com's typed column value format. The webhook payload for a change_column_value event includes a value object that varies by column type:
Status column: {"label": {"text": "Done"}, "index": 1, "post_id": null}
Date column: {"date": "2026-08-13", "time": null}
Person column: {"personsAndTeams": [{"id": 12345678, "kind": "person"}]}
Text column: {"value": "Some text content"}
Use a Code node in n8n to parse these into a clean object. The column ID is in $json.body.event.columnId and the raw value JSON is in $json.body.event.value. Parse the value string with JSON.parse() and extract what you need.
To find column IDs for your board, use the Monday.com GraphQL playground (developer.monday.com):
{ boards(ids: [YOUR_BOARD_ID]) { columns { id title type } } }
This returns the column IDs that will appear in webhook payloads — save them, because Monday.com uses internal IDs like date4 or status_1, not the display names you see in the board UI.
Step 5 — Build your event processing logic
With the webhook verified and column values parsing correctly, connect your actual automation logic on the false branch of the If node. Common patterns:
Status-to-action routing
Add an If or Switch node that checks the status label value. Route "Done" to one path (create a Jira issue, notify Slack), "In Review" to another (assign a reviewer via the Monday.com GraphQL API), and "Blocked" to an escalation path (ping a manager, create a Zendesk ticket).
Writing back to Monday.com
To update a Monday.com item from within the same workflow, use an HTTP Request node with a GraphQL mutation. The n8n Monday.com node handles simple column updates, but for complex column types (people, timeline, mirror columns), direct GraphQL mutations give you more control:
mutation { change_column_value(board_id: BOARD_ID, item_id: ITEM_ID, column_id: "status", value: "{\"label\":\"Done\"}") { id } }
Authentication: pass your Monday.com API token as an Authorization header (Bearer YOUR_TOKEN). The Monday.com API v2 endpoint is https://api.monday.com/v2.
Respond to the event webhook
After your processing logic, add a final Respond to Webhook node on the false branch to acknowledge the event to Monday.com with a 200 status. Monday.com will retry unacknowledged webhooks — acknowledging after processing closes the loop cleanly.
Troubleshooting common issues
- Webhook shows as "failed" in Monday.com — the challenge wasn't handled. Check that your Webhook node is set to "Respond using Respond to Webhook Node" and that the challenge branch is connected and returning the correct JSON.
- Events fire during testing but not in production — you registered the webhook against the test URL instead of the production URL. Re-register using the production URL from your activated workflow.
- Column value is null or unparseable — the
valuefield in the payload is a JSON string, not an object. You mustJSON.parse()it before accessing nested properties. - Webhook fires but item data is incomplete — the basic webhook payload contains the event metadata but not full item details. If you need all column values, use the Monday.com node to fetch the full item by ID after receiving the event.
If you want this built, tested, and maintained rather than debugged step by step, Entech Solutions delivers production-grade n8n Monday.com integrations — including webhook setup, column value parsing, and cross-system sync with Jira, Salesforce, and Slack. Most Monday.com automation projects go live in 1–3 weeks.