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
namestring—Friendly label for the scheduled webhook
cronExpressionstring—Cron expression (5 or 6 fields) defining the schedule
urlstring—The 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 '{
    "workspaceId": "<your-workspace-id>",
    "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"
}

Templates in the payload

Text values can carry templates, and they are resolved every time the schedule fires — and when you press Run now, so the output you see is the one that will go out:

jsonPayload with templates
{
  "message": "Good morning, it is {{$time}}",
  "day": "{{$date}}",
  "runId": "{{$uuid}}"
}

A schedule has no incoming data, so {{payload.x}} has nothing to read here; the clock variables, {{$uuid}} and functions are what you use.

ℹ{{$time}} and {{$date}} use the schedule's time zone once your workspace has a time zone set; without one they print UTC. Date pipes such as {{$now | formatTime}} always print UTC — use {{$time}} for the local hour.

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.
ℹThere's no cap on how many Scheduled Workflows you create. What the plan sets is how often each one can run: at most every 15 minutes on Free, and every 5 minutes on Starter, Pro and Enterprise.