Delay Node
The Delay node pauses event forwarding for a configurable duration. Events are held in the pipeline and only continue to the next node after the delay period expires — useful for rate pacing, debouncing, and time-sensitive workflows.
Overview
When an event reaches a Delay node, it is placed in a holding state with status DELAYED. After the configured number of seconds, the event is released and continues through the pipeline to the connected downstream nodes. The delay is implemented via BullMQ delayed jobs, ensuring reliability even across service restarts.
On the canvas, Delay nodes appear as slate rectangles. They can be placed between any two nodes in the pipeline to introduce a pause.
Configuration
| Field | Type | Default | Description |
|---|---|---|---|
| name | string | — | Friendly label for the delay node |
| delaySeconds | number | — | Number of seconds to delay event forwarding |
| isActive | boolean | true | Whether the delay is enabled (when disabled, events pass through immediately) |
| inputNodes | { nodeType, nodeId }[] | [] | Upstream nodes that feed this one. nodeType is the node kind (webhook, scheduledWorkflow, filter, …) |
Create a Delay Node
curl -X POST /api/delay-nodes \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "5-Minute Cooldown",
"delaySeconds": 300,
"isActive": true,
"inputNodes": [{ "nodeType": "webhook", "nodeId": "6654a1b2c3d4e5f6a7b8c9d0" }]
}'Response
{
"_id": "6655c9d0e1f2a3b4c5d6e7f8",
"name": "5-Minute Cooldown",
"delaySeconds": 300,
"isActive": true,
"inputNodes": [{ "nodeType": "webhook", "nodeId": "6654a1b2c3d4e5f6a7b8c9d0" }],
"ownerId": "org_abc123",
"createdAt": "2025-05-01T12:00:00.000Z",
"updatedAt": "2025-05-01T12:00:00.000Z"
}Update a Delay Node
curl -X PATCH /api/delay-nodes/6655c9d0e1f2a3b4c5d6e7f8 \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"delaySeconds": 600,
"name": "10-Minute Cooldown"
}'delaySeconds only affects future events. Events already in the DELAYED state will complete their original delay period.Canvas Integration
The Delay node uses canvas type delay-node and renders in slate. It is placed inline between nodes to introduce a pause in the pipeline flow.
{
"id": "delay-6655c9d0e1f2a3b4c5d6e7f8",
"type": "delay-node",
"position": { "x": 350, "y": 200 },
"data": {
"label": "5-Minute Cooldown",
"delayNodeId": "6655c9d0e1f2a3b4c5d6e7f8",
"delaySeconds": 300,
"isActive": true
}
}Payload Examples
Event entering delay
{
"_id": "evt_9987e5f6a7b8c9d0e1f2a3b4",
"webhookId": "6654a1b2c3d4e5f6a7b8c9d0",
"status": "DELAYED",
"payload": {
"type": "order.created",
"data": { "orderId": "ORD-789", "amount": 4500 }
},
"delayNodeId": "6655c9d0e1f2a3b4c5d6e7f8",
"delayUntil": "2025-05-01T12:05:00.000Z",
"createdAt": "2025-05-01T12:00:00.000Z"
}Event after delay expires
Once the delay period expires, the event's status changes and it continues through the pipeline with its original payload intact:
{
"_id": "evt_9987e5f6a7b8c9d0e1f2a3b4",
"webhookId": "6654a1b2c3d4e5f6a7b8c9d0",
"status": "pending",
"payload": {
"type": "order.created",
"data": { "orderId": "ORD-789", "amount": 4500 }
},
"delayNodeId": "6655c9d0e1f2a3b4c5d6e7f8",
"delayedAt": "2025-05-01T12:00:00.000Z",
"releasedAt": "2025-05-01T12:05:00.000Z",
"createdAt": "2025-05-01T12:00:00.000Z"
}Use Cases
- Rate pacing — Add a delay between event processing to avoid overwhelming rate-limited downstream APIs.
- Debouncing — Delay processing to allow time for duplicate or updated events to arrive (combine with a Merge node).
- Scheduled follow-ups — Delay a notification by 30 minutes after an order is placed to send a "still processing" message.
- Retry spacing — Insert delays between chained webhook calls to give downstream services time to recover.
- Business hours processing — Combine a Delay with a Filter to hold events until they can be processed during business hours.
API Reference
| Method | Webhook | Description |
|---|---|---|
| GET | /api/delay-nodes | List all delay nodes |
| POST | /api/delay-nodes | Create a new delay node |
| GET | /api/delay-nodes/:id | Get a specific delay node |
| PATCH | /api/delay-nodes/:id | Update a delay node |
| DELETE | /api/delay-nodes/:id | Delete a delay node |
isActive: false), events pass through immediately without any pause — useful for temporarily bypassing the delay during debugging.