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_webhook mutation with a config column 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:

  1. Challenge branch — checks if the request body contains a challenge field. If yes, responds immediately with {"challenge": "the-value"} and ends.
  2. 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:

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:

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


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.