Guide to Monday Webhooks: Features and Best Practices
Monday.com has become one of the most popular work operating systems, used by teams of all sizes to manage projects, workflows, and operations. Beyond its visual boards and automations, Monday's webhook integration enables developers to build real-time integrations that respond instantly when work items change without constantly polling the API.
This guide covers everything you need to know about Monday webhooks: their features, how to configure them, best practices for production deployments, and the common pain points developers face along with solutions to address them.
What are Monday webhooks?
Monday webhooks are HTTP callbacks that deliver real-time event notifications to external endpoints whenever specific actions occur on a Monday board. When an item is created, a status changes, an update is posted, or any other supported event fires, Monday sends a JSON payload containing event details to a URL you configure. Rather than repeatedly polling the Monday API to detect changes, you subscribe to webhook events and receive instant HTTP POST notifications at your endpoint. This makes webhooks far more efficient for building integrations, syncing data with external systems, and triggering downstream automations.
Webhooks in Monday exist in two primary contexts:
- Board-level webhooks — The primary webhook integration, configured per board via the Integrations Center or the GraphQL API
- App lifecycle webhooks — Webhooks triggered by app installation, uninstallation, and subscription events for marketplace apps
This guide focuses primarily on board-level webhooks, as they're the most commonly used webhook integration.
Monday webhook features
| Feature | Details |
|---|---|
| Webhook configuration | Monday UI (Integrations Center), GraphQL API |
| Scope | Board-level (one webhook per board per event) |
| Authentication | URL challenge verification; JWT via app integration tokens |
| Hashing algorithm | None (no HMAC signing for standard webhooks) |
| Retry policy | Retries once per minute for 30 minutes |
| Timeout | Not publicly documented |
| Manual retry | Not available |
| Browsable log | Not available |
| Event types | 18+ event types covering items, columns, subitems, updates, and groups |
| Payload customization | Not supported |
Supported event types
Monday webhooks can notify you of the following board events:
| Event | Description |
|---|---|
create_item | A new item is created on the board |
change_column_value | Any column value changes on an item |
change_status_column_value | A status column value changes (supports filtering by specific value) |
change_specific_column_value | A specific column's value changes (requires columnId in config) |
change_name | An item's name is changed |
item_archived | An item is archived |
item_deleted | An item is deleted |
item_moved_to_any_group | An item is moved to any group |
item_moved_to_specific_group | An item is moved to a specific group (requires groupId in config) |
item_restored | An archived item is restored |
create_subitem | A subitem is created |
change_subitem_column_value | A subitem's column value changes |
change_subitem_name | A subitem's name is changed |
move_subitem | A subitem is moved |
subitem_archived | A subitem is archived |
subitem_deleted | A subitem is deleted |
create_update | An update (comment) is posted on an item |
edit_update | An update is edited |
delete_update | An update is deleted |
create_subitem_update | An update is posted on a subitem |
create_column | A new column is added to the board |
Some events accept a config argument for more granular filtering:
| Event | Config JSON | Notes |
|---|---|---|
change_specific_column_value | {"columnId": "column_id"} | Does not support subitem columns |
change_status_column_value | {"columnValue": {"index": N}, "columnId": "column_id"} | Index structure varies by column type |
item_moved_to_specific_group | {"groupId": "group_id"} | Requires the target group ID |
Webhook payload structure
When Monday sends a webhook notification, it delivers a JSON payload with an event object containing the event data. Here's an example payload for a create_item event:
{
"event": {
"userId": 9603417,
"originalTriggerUuid": null,
"boardId": 1771812698,
"pulseId": 1772099344,
"pulseName": "New task item",
"groupId": "topics",
"groupName": "Group Title",
"groupColor": "#579bfc",
"isTopGroup": true,
"columnValues": {},
"app": "monday",
"type": "create_pulse",
"triggerTime": "2025-01-15T09:07:28.210Z",
"subscriptionId": 73759690,
"triggerUuid": "b5ed2e17c530f43668de130142445cba"
}
}
And here's a change_column_value event:
{
"event": {
"userId": 9603417,
"originalTriggerUuid": null,
"boardId": 1771812698,
"groupId": "topics",
"pulseId": 1771812728,
"pulseName": "My item",
"columnId": "status",
"columnType": "color",
"columnTitle": "Status",
"value": {
"label": {
"index": 3,
"text": "Done",
"style": {
"color": "#0086c0",
"border": "#3DB0DF",
"var_name": "blue-links"
}
},
"post_id": null
},
"previousValue": null,
"changedAt": 1633944017.473193,
"isTopGroup": true,
"app": "monday",
"type": "update_column_value",
"triggerTime": "2025-01-15T09:20:18.022Z",
"subscriptionId": 73761176,
"triggerUuid": "504b2eb76c80f672a18f892c0f700e41"
}
}
Key payload fields
| Field | Description |
|---|---|
event.userId | The ID of the user who triggered the event |
event.boardId | The unique identifier of the board |
event.pulseId | The unique identifier of the item (also referred to as itemId) |
event.pulseName | The name of the item |
event.groupId | The group the item belongs to |
event.columnId | The column that changed (for column change events) |
event.columnType | The type of the changed column |
event.value | The new column value |
event.previousValue | The previous column value (often null) |
event.type | The internal event type (e.g., create_pulse, update_column_value) |
event.triggerTime | ISO 8601 timestamp of when the event occurred |
event.subscriptionId | The webhook subscription ID |
event.triggerUuid | A unique identifier for this specific trigger |
event.parentItemId | The parent item ID (subitem events only) |
event.parentItemBoardId | The parent item's board ID (subitem events only) |
URL verification (challenge flow)
Before a webhook becomes active, Monday verifies that you control the endpoint by sending a JSON POST body containing a randomly generated token in a challenge field. Your endpoint must echo this token back in the response body:
{
"challenge": "3eZbrw1aBm2rZgRNFdxV2595E9CY3gmdALWMmHkvFXO7tYXAYM8P"
}
Your endpoint should return this same JSON structure as the response.
Authentication options
Monday webhooks offer limited authentication options:
| Method | How it works |
|---|---|
| Challenge handshake | Verifies you control the URL at setup time only |
| JWT via integration app | Webhooks created with an integration app token include a JWT in the Authorization header, verifiable against the app's Signing Secret |
JWT-based authentication is only available for webhooks created through a monday app with an integration feature. Webhooks created with personal API tokens or via the UI do not include authentication headers.
Setting up Monday webhooks
Via the Monday UI
- Navigate to your board and open the Integrations Center (top-right corner)
- Click on Integrations at the bottom of the left-pane menu
- Search for "webhooks" and find the webhooks app
- Select the webhook recipe matching your desired event (e.g., "When any column changes, send a webhook")
- Provide the URL that will receive the event payload
- Monday will send a challenge to verify your endpoint
- Once verified, the webhook is active
Via the GraphQL API
Use the create_webhook mutation:
mutation {
create_webhook(
board_id: 1234567890,
url: "https://your-endpoint.com/webhooks/monday",
event: change_column_value
) {
id
board_id
}
}
Best practices when working with Monday webhooks
Respond to webhooks quickly and process asynchronously
Monday's retry policy will resend webhooks if your endpoint doesn't respond promptly. Always acknowledge the webhook immediately with a 200 status code and process the event data asynchronously.
Use triggerUuid for idempotency
Each webhook event includes a triggerUuid field that uniquely identifies the specific trigger. Use this to implement idempotent processing and avoid handling duplicate deliveries:
async function processEvent(event) {
const idempotencyKey = event.triggerUuid;
const exists = await redis.get(`processed:${idempotencyKey}`);
if (exists) {
console.log(`Event ${idempotencyKey} already processed, skipping`);
return;
}
// Process the event
await handleEvent(event);
// Mark as processed with 24-hour TTL
await redis.setex(`processed:${idempotencyKey}`, 86400, '1');
}
Verify JWT signatures for app-based webhooks
If you've created webhooks through a monday app with an integration feature, verify the JWT in the Authorization header:
const jwt = require('jsonwebtoken');
function verifyMondayWebhook(req, signingSecret) {
const authHeader = req.headers['authorization'];
if (!authHeader) return false;
try {
const decoded = jwt.verify(authHeader, signingSecret);
return decoded;
} catch (err) {
console.error('JWT verification failed:', err.message);
return false;
}
}
app.post('/webhooks/monday', (req, res) => {
if (req.body.challenge) {
return res.status(200).json({ challenge: req.body.challenge });
}
const verified = verifyMondayWebhook(req, process.env.MONDAY_SIGNING_SECRET);
if (!verified) {
return res.status(401).send('Unauthorized');
}
// Process verified webhook
res.status(200).send('OK');
});
Enrich payloads with follow-up API calls
Since Monday webhook payloads are minimal (especially for create_item events where columnValues is empty), you'll often need to fetch additional data.
Monday webhook limitations and pain points
No HMAC signature verification for standard webhooks
The Problem: Monday does not support HMAC signature verification for webhooks created via the UI or with personal API tokens. There is no cryptographic way to verify that an incoming request genuinely originated from Monday. Anyone who discovers your webhook URL could submit fake payloads to your endpoint.
Why It Happens: The only verification mechanism is the challenge handshake at setup time, which confirms you control the URL but does not authenticate subsequent requests. JWT-based authentication is only available when webhooks are created through a monday app with an integration feature—a more complex setup that requires building and registering an app.
Workarounds:
- Create webhooks through a Monday app with an integration feature to get JWT authentication
- Use obscure, unguessable webhook URLs with secret tokens in the path
- Implement IP allowlisting if Monday publishes egress IP ranges
- Add a secret query parameter to your webhook URL and validate it on each request
How Hookdeck Can Help: Hookdeck provides built-in source verification and can act as a secure intermediary, validating incoming requests and adding authentication headers before forwarding to your endpoint without needing to build a Monday app.
Board-scoped webhooks with no account-wide subscriptions
The Problem: Every webhook in Monday is scoped to a single board. There is no way to create an account-wide or workspace-wide webhook that captures events across all boards. If your organization has dozens or hundreds of boards, you must create and manage individual webhook subscriptions for each one.
Why It Happens: Monday's webhook architecture is tightly coupled to the board as the primary organizational unit. The create_webhook mutation requires a board_id parameter, and there is no wildcard or account-level scope option.
Workarounds:
- Build automation to enumerate all boards and create webhooks programmatically
- Listen for
create_boardevents (if available through app lifecycle events) to dynamically create webhooks on new boards - Use Monday's GraphQL API to periodically discover new boards and subscribe to them
How Hookdeck Can Help: Hookdeck can serve as a single destination URL for all your board-level webhooks, providing unified routing, filtering, and monitoring across all boards through a single dashboard—simplifying management even when individual subscriptions are required.
Minimal webhook payloads requiring follow-up API calls
The Problem: Monday webhook payloads are intentionally minimal. Item creation events deliver an empty columnValues: {} object, and column change events only include data for the specific column that changed. Developers almost always need to make a follow-up GraphQL API call to fetch the full item data they need to process the event.
Why It Happens: Monday's webhook system sends only the data directly related to the triggering event. There is no payload customization feature to request additional fields or include all column values.
Workarounds:
- Implement a follow-up API call using the
pulseId(item ID) andboardIdfrom the payload to fetch complete item data - Cache board column schemas to avoid repeated lookups when translating column IDs to human-readable names
- Batch follow-up API calls when processing multiple webhook events to stay within rate limits
How Hookdeck Can Help: Hookdeck's transformation capabilities allow you to enrich webhook payloads in-flight by making follow-up API calls and attaching the additional data before forwarding to your endpoint, reducing the complexity of your webhook handler.
Aggressive retry policy with no configurable backoff
The Problem: Monday retries failed webhook deliveries once per minute for 30 minutes. This retry schedule is fixed and cannot be configured. If your endpoint has a brief outage, you'll receive a burst of retries that may compound the problem, especially when combined with new events still firing during the outage.
Why It Happens: The retry policy is hardcoded at the platform level. There is no per-webhook configuration for retry frequency, maximum retries, or backoff strategy. Community reports also suggest discrepancies between the documented retry behavior and observed behavior—some developers have reported retries every 30 seconds rather than every minute.
Workarounds:
- Ensure your endpoint returns appropriate HTTP status codes quickly, even during partial outages
- Implement idempotent processing using
triggerUuidto safely handle duplicate deliveries - Design your endpoint to degrade gracefully under retry load
How Hookdeck Can Help: Hookdeck provides configurable retry policies with exponential backoff, rate limiting, and manual replay. Failed deliveries are preserved and can be retried on demand, preventing retry storms while ensuring reliable delivery.
No delivery logs or monitoring dashboard
The Problem: Monday provides no visibility into webhook delivery status, success rates, or failure details. There is no delivery log, no way to see response codes from your endpoint, and no dashboard showing webhook health. If webhooks silently fail, you may not discover the problem until data is missing.
Why It Happens: The webhook infrastructure is designed as a fire-and-forget system from the user's perspective. The platform handles retries internally but does not expose delivery telemetry to developers.
Workarounds:
- Implement your own logging at the webhook receiver to track all incoming deliveries
- Build health-check alerting that detects gaps in expected webhook events
- Create a reconciliation process that periodically compares webhook-received data against Monday's API
How Hookdeck Can Help: Hookdeck's dashboard provides complete visibility into webhook delivery status, latency, response codes, and error rates. You can inspect individual deliveries, search through logs, and configure alerts for delivery issues.
No dead letter queue
The Problem: When webhooks fail after exhausting all retry attempts (30 minutes of retries), the events are permanently lost. Monday does not maintain a dead letter queue or any record of failed deliveries that could be inspected or replayed later.
Why It Happens: Monday does not offer a webhook event persistence or replay mechanism. Once retries are exhausted, there is no fallback.
Workarounds:
- Ensure high availability for your webhook endpoint to minimize missed events
- Implement your own dead letter queue by logging all received events and running periodic reconciliation against the Monday API
- Use a queuing service (Hookdeck, SQS, RabbitMQ) between Monday and your final processing endpoint
How Hookdeck Can Help: Hookdeck automatically preserves all webhook events, including failed deliveries, in a persistent store. Failed webhooks can be inspected, debugged, and replayed—individually or in bulk—once issues are resolved.
Webhook loops in bidirectional sync scenarios
The Problem: When building bidirectional sync between Monday and an external system, a webhook-triggered API mutation back to Monday can trigger another webhook, creating an infinite loop. There is no way to temporarily pause a webhook or mark API calls as "don't trigger webhooks."
Why It Happens: Monday does not provide a mechanism to suppress webhook firing for specific API calls. Every change to a board, regardless of source, triggers subscribed webhooks.
Workarounds:
- Maintain a set of "in-flight" updates and filter out self-triggered webhook events using the
userIdor item ID - Use the
originalTriggerUuidfield (when non-null) to detect chain reactions - Implement a cooldown period after making API mutations before processing new webhooks for the same item
- Delete and recreate webhooks around sync operations (not recommended due to challenge verification overhead)
How Hookdeck Can Help: Hookdeck's filtering and transformation capabilities can detect and suppress loop-causing events based on payload content, preventing infinite cycles without requiring changes to your webhook handler logic.
Integration action limits tied to pricing tiers
The Problem: Webhook-triggered integrations count against your plan's monthly action limits, which vary dramatically by tier: 250 actions/month on Standard, 25,000 on Pro, and 250,000 on Enterprise. Exceeding limits can result in integrations being disabled for the remainder of the month—or even consuming the following month's allocation.
Why It Happens: Monday bills automation and integration activity by action count. Webhooks that trigger high volumes of events (e.g., boards with frequent column changes) can rapidly burn through monthly allocations, especially on lower-tier plans.
Workarounds:
- Monitor your integration action usage regularly through the Integrations Center's Account Usage tab
- Use specific event types (like
change_specific_column_value) rather than broad ones (likechange_column_value) to reduce unnecessary triggers - Upgrade to a higher plan if integration volumes consistently exceed limits
- Consider using the API directly for polling if webhook-driven action counts are problematic
How Hookdeck Can Help: Hookdeck's filtering capabilities can suppress unwanted webhook events before they reach your processing endpoint, helping you reduce unnecessary action consumption and stay within plan limits.
Phantom webhooks in UI after API deletion
The Problem: When a webhook is deleted via the delete_webhook API mutation, the webhook is functionally removed but continues to appear in the Monday Integrations Center UI. This creates confusion, and further user interactions with these phantom entries can cause additional unintended webhook creation.
Why It Happens: There is a known synchronization issue between the API layer and the UI layer. The API correctly deletes the webhook subscription, but the UI cache is not always updated.
Workarounds:
- Refresh the board or Integrations Center page after deleting webhooks via API
- Use the
webhooksquery to verify actual webhook subscriptions rather than relying on the UI - Educate team members to check the API for the source of truth on active webhooks
How Hookdeck Can Help: By routing all webhooks through Hookdeck, you can manage webhook lifecycle entirely through Hookdeck's dashboard and API, which provides an accurate, real-time view of active connections independent of Monday's UI.
Testing Monday webhooks
Handle the challenge flow first
Before building any event processing logic, ensure your endpoint correctly responds to the challenge verification. Use a request inspector like Hookdeck's Console to verify the exact challenge payload format.
Use a request inspector
Before building your handler, inspect real Monday payloads:
- Create a temporary webhook URL using a service like Hookdeck's Console.
- Configure it as your webhook endpoint on a test board
- Complete the challenge verification
- Trigger events by creating items, changing column values, and posting updates
- Inspect the payload structure, fields, and data types
Test with realistic board configurations
Test your webhook integration with scenarios that match your production boards:
- Boards with many columns (to verify your enrichment API calls work correctly)
- Rapid item creation and status changes (to test idempotency handling)
- Subitem events (to verify parent item data is included in payloads)
- Concurrent changes by multiple users (to test event ordering assumptions)
- Webhook creation and deletion via API (to verify lifecycle management)
Conclusion
Monday webhooks provide a practical foundation for building real-time integrations with the platform. The GraphQL-based API for creating and managing webhooks is straightforward, the challenge verification ensures endpoint ownership, and the range of supported event types covers most common board activities.
However, meaningful limitations around security (no HMAC signing), observability (no delivery logs), payload completeness (minimal data requiring follow-up API calls), and scope (board-level only) mean production deployments need careful architecture. Implementing idempotent processing, asynchronous handling, payload enrichment, and loop prevention will address most common issues.
For straightforward integrations with moderate event volumes and reliable endpoints, Monday's built-in webhook infrastructure combined with proper error handling works well. For high-volume deployments, multi-board environments, or mission-critical workflows where delivery guarantees and observability matter, webhook infrastructure like Hookdeck can address Monday's limitations by providing configurable retries, payload transformation, automatic deduplication, delivery monitoring, and dead letter queues without modifying your Monday configuration.