How to Connect a Monday.com Webhook to your n8n Workflow

Recently for a client, I was working to switch over from Make.com to their own n8n install in order to manage some automations. I was struggling to deal with Monday.com’s challenge response to the webhook using n8n. After some finagling with Claude and trial/error with curl, I was able to build a workflow that got me through.

Here is the n8n workflow json that you can copy and paste:

{
  "name": "Monday.com Webhook - Exact Documentation",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "monday-webhook",
        "responseMode": "responseNode",
        "options": {}
      },
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [0, 0],
      "webhookId": "2e18be0d-ef25-4009-8724-8906e1700cb0",
      "id": "4f6c0d7e-cf39-4b04-af53-303ed741d388"
    },
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{ $json.body.challenge }}",
              "operation": "isNotEmpty"
            }
          ]
        }
      },
      "name": "If Challenge Exists",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [200, 0],
      "id": "d39443cf-ebc2-4426-a612-852a482eb18b"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ $node[\"Webhook\"].json[\"body\"] }}",
        "options": {
          "responseCode": 200
        }
      },
      "name": "Return Challenge JSON",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [400, -100],
      "id": "7faa215a-d4d2-466a-98f1-2f83331177e8"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "{\"success\": true}",
        "options": {
          "responseCode": 200
        }
      },
      "name": "Return Success",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [400, 100],
      "id": "8faa215a-d4d2-466a-98f1-2f83331177e9"
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "If Challenge Exists",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Challenge Exists": {
      "main": [
        [
          {
            "node": "Return Challenge JSON",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Return Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "meta": {
    "instanceId": "f4e93957bea2bfbb949bc11ce90a97c3c32f37ea7ba5e965c8ac9cd10fea6dc3"
  }
}

From Claude, here is a full breakdown of the nodes:

Workflow Overview

This workflow handles Monday.com webhook verification and events with 4 nodes connected in a branching pattern.

Node 1: Webhook (Entry Point)

"name": "Webhook"
"type": "n8n-nodes-base.webhook"
  • Purpose: Receives incoming HTTP POST requests from Monday.com
  • Path: /webhook/monday-webhook – This creates the endpoint URL
  • Response Mode: responseNode – Means it waits for another node to send the response (not immediate)
  • Position: [0, 0] – Located at the start of the workflow visually
  • Webhook ID: A unique identifier for this webhook instance

Node 2: If Challenge Exists (Decision Node)

"name": "If Challenge Exists"
"type": "n8n-nodes-base.if"
  • Purpose: Checks if the incoming request contains a challenge field
  • Condition: {{ $json.body.challenge }} with operation isNotEmpty
    • This checks if there’s a challenge field in the request body
    • $json.body refers to the parsed JSON body from the webhook
  • Branching: Creates two paths:
    • True branch (index 0): Goes to “Return Challenge JSON”
    • False branch (index 1): Goes to “Return Success”

Node 3: Return Challenge JSON (True Branch)

"name": "Return Challenge JSON"
"type": "n8n-nodes-base.respondToWebhook"
  • Purpose: Responds to Monday.com’s verification challenge
  • Response Type: json
  • Response Body: ={{ $node["Webhook"].json["body"] }}
    • This returns the ENTIRE body that was received
    • Matches Monday’s requirement: return exactly what they sent
  • Status Code: 200
  • Position: [400, -100] – Positioned above (negative Y) the other response node

Node 4: Return Success (False Branch)

"name": "Return Success"
"type": "n8n-nodes-base.respondToWebhook"
  • Purpose: Responds to regular webhook events (not challenges)
  • Response Type: json
  • Response Body: {"success": true} – A simple success acknowledgment
  • Status Code: 200
  • Position: [400, 100] – Positioned below (positive Y) the challenge response

Connections (Workflow Logic)

"connections": {
  "Webhook": → "If Challenge Exists"
  "If Challenge Exists": 
    - [True] → "Return Challenge JSON"
    - [False] → "Return Success"
}

Flow Scenarios

Scenario 1: Monday.com sends verification challenge

  1. Monday sends: {“challenge”: “abc123xyz”}
  2. Webhook receives it
  3. IF node checks: Is challenge present? YES
  4. Return Challenge JSON sends back: {“challenge”: “abc123xyz”}
  5. Monday.com verifies and activates webhook

Scenario 2: Monday.com sends actual webhook event

  • Monday sends: {“event”: {“type”: “item_created”, …}}
  • Webhook receives it
  • IF node checks: Is challenge present? NO
  • Return Success sends back: {“success”: true}
  • Monday.com knows event was received

Key Design Elements

  • Response Mode: Uses responseNode pattern where the webhook waits for explicit response nodes
  • Expression Syntax: Uses n8n’s ={{}} expression format for dynamic values
  • Node References: $node["Webhook"].json["body"] allows accessing data from previous nodes
  • Conditional Branching: The IF node splits the flow based on whether it’s a verification or regular event

This workflow elegantly handles both Monday.com’s webhook verification process and ongoing event processing in a single, simple flow.

Testing the Monday.com Webhook with cURL

Based on the workflow structure, here are the test commands:

Test 1: Challenge Verification (What Monday.com sends during setup)

bash

curl -X POST https://your-n8n-instance-url.com/webhook/monday-webhook \
  -H "Content-Type: application/json" \
  -d '{"challenge": "3eZbrw1aBm2rZgRNFdxV2595E9CY3gmdALWMmHkvFXO7tYXAYM8P"}' \
  -v

Expected Response:

json

{"challenge": "3eZbrw1aBm2rZgRNFdxV2595E9CY3gmdALWMmHkvFXO7tYXAYM8P"}
  • Status: 200 OK
  • The workflow should echo back the exact JSON it received