Scheduled Workflow Node

Scheduled Workflows let you trigger HTTP calls on a cron schedule. Instead of waiting for an external event, the system initiates outbound requests at defined intervals — perfect for polling APIs, running periodic health checks, or triggering time-based workflows.

Overview

A Scheduled Workflow node fires HTTP requests on a cron-based schedule. Each execution creates an event that flows through the pipeline exactly like an inbound webhook — meaning it can trigger Routers, Transforms, and Chains. The scheduler runs in a dedicated BullMQ queue (scheduled-workflows) and supports timezone-aware cron expressions.

On the canvas, Scheduled Workflow nodes appear as amber rectangles. Edges from a Scheduled Workflow to a Webhook use swEdge: true in edge data for visual differentiation.


Configuration

FieldTypeDefaultDescription
namestringFriendly label for the scheduled webhook
cronExpressionstringCron expression (5 or 6 fields) defining the schedule
urlstringThe URL to call on each scheduled execution
methodstringPOSTHTTP method: GET, POST, PUT, PATCH, DELETE
headersobject{}Custom headers to include in each request
bodyobject | stringnullRequest body sent with POST/PUT/PATCH requests
isActivebooleantrueWhether the schedule is enabled
timezonestringUTCIANA timezone for cron interpretation (e.g. America/New_York)
Cron expressions follow the standard 5-field format: minute hour day-of-month month day-of-week. A 6th field for seconds is also supported. Examples: */5 * * * * (every 5 minutes), 0 9 * * 1-5 (9 AM weekdays).

Create a Scheduled Workflow

bashCreate Scheduled Workflow
curl -X POST /api/scheduled-workflows \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Daily Health Check",
    "cronExpression": "0 9 * * *",
    "url": "https://api.myapp.com/health",
    "method": "GET",
    "headers": {
      "X-Monitor-Source": "hostwebhook"
    },
    "isActive": true,
    "timezone": "America/New_York"
  }'

Response

json201 Created
{
  "_id": "6654b2c3d4e5f6a7b8c9d0e1",
  "name": "Daily Health Check",
  "cronExpression": "0 9 * * *",
  "url": "https://api.myapp.com/health",
  "method": "GET",
  "headers": {
    "X-Monitor-Source": "hostwebhook"
  },
  "body": null,
  "isActive": true,
  "timezone": "America/New_York",
  "nextRunAt": "2025-05-02T13:00:00.000Z",
  "lastRunAt": null,
  "ownerId": "org_abc123",
  "createdAt": "2025-05-01T12:00:00.000Z",
  "updatedAt": "2025-05-01T12:00:00.000Z"
}

Update a Scheduled Workflow

bashUpdate Scheduled Workflow
curl -X PATCH /api/scheduled-workflows/6654b2c3d4e5f6a7b8c9d0e1 \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "cronExpression": "*/30 * * * *",
    "body": {
      "check": "deep",
      "includeMetrics": true
    },
    "method": "POST"
  }'
Changing the cronExpression recalculates nextRunAt immediately. Any pending scheduled job for the old expression is cancelled.

Canvas Integration

On the visual canvas, the Scheduled Workflow node uses the node type scheduled-workflow and is rendered with an amber color scheme. It connects to Webhook nodes via edges marked with swEdge: true.

When a Scheduled Workflow is connected to a Webhook on the canvas, each scheduled execution creates an event on that webhook. The SW processor creates events directly through the EventPipelineService rather than making HTTP POST requests, avoiding unnecessary network overhead.

jsonCanvas node data
{
  "id": "swf-6654b2c3d4e5f6a7b8c9d0e1",
  "type": "scheduled-workflow",
  "position": { "x": 50, "y": 100 },
  "data": {
    "label": "Daily Health Check",
    "swId": "6654b2c3d4e5f6a7b8c9d0e1",
    "cronExpression": "0 9 * * *",
    "isActive": true
  }
}
jsonCanvas edge (SW to Webhook)
{
  "id": "swf-6654b2c3-to-wh-6654a1b2",
  "source": "swf-6654b2c3d4e5f6a7b8c9d0e1",
  "target": "webhook-6654a1b2c3d4e5f6a7b8c9d0",
  "data": { "swEdge": true }
}

Payload Examples

Scheduled execution payload

The body you configure is sent as the request payload. If no body is set, the request is sent with an empty body (or no body for GET requests).

jsonPOST body example
{
  "check": "deep",
  "includeMetrics": true,
  "triggeredAt": "2025-05-02T13:00:00.000Z",
  "source": "hostwebhook-scheduler"
}

Event created by SW execution

When connected to a webhook, the SW creates an event with metadata:

jsonEvent record
{
  "_id": "evt_7765c3d4e5f6a7b8c9d0e1f2",
  "webhookId": "6654a1b2c3d4e5f6a7b8c9d0",
  "payload": {
    "check": "deep",
    "includeMetrics": true
  },
  "source": "scheduled-workflow",
  "scheduledWorkflowId": "6654b2c3d4e5f6a7b8c9d0e1",
  "status": "pending",
  "createdAt": "2025-05-02T13:00:00.000Z"
}

Use Cases

  • Health monitoring — Ping your API every 5 minutes and use Alert nodes to notify you of failures.
  • Data synchronization — Poll a third-party API hourly and forward results through your pipeline.
  • Report generation — Trigger a nightly report at 2 AM in your local timezone.
  • Cache warming — Pre-fetch data every 15 minutes to keep caches fresh.
  • Scheduled notifications — Send daily digest emails by triggering your notification service on a cron schedule.

API Reference

MethodWebhookDescription
GET/api/scheduled-workflowsList all scheduled webhooks
POST/api/scheduled-workflowsCreate a new scheduled webhook
GET/api/scheduled-workflows/:idGet a specific scheduled webhook
PATCH/api/scheduled-workflows/:idUpdate a scheduled webhook
DELETE/api/scheduled-workflows/:idDelete a scheduled webhook
Use the nextRunAt field in the response to verify your cron expression is being interpreted correctly for your timezone.
Scheduled Workflow limits are plan-gated. Free plans allow up to 2 scheduled webhooks, Pro allows 20, and Enterprise is unlimited.