ScheduledTrigger NodeTypeCode: schedule-trigger
Fire a workflow automatically at a defined time or recurring interval using a standard cron expression. Provides trigger time and trigger type metadata to downstream nodes.
When to Use
- Daily report generation at 9 AM weekdays: A payroll summary report is generated every morning before the team starts work. The workflow queries the HRMS, computes attendance and exceptions, formats an Excel report, and emails it to department heads — all without human initiation.
- Hourly data sync from an external API: A product catalog sync workflow runs every hour, pulls changed records from a supplier's REST API, normalizes the data, and upserts into the internal database to keep inventory data fresh throughout the business day.
- Monthly billing calculation on the 1st: On the first day of every month at midnight, the billing workflow aggregates usage metrics for all active subscription accounts, calculates charges, generates invoices, and queues them for the accounts receivable system.
- Weekly cleanup of expired records: Every Sunday at 2 AM, a maintenance workflow deletes workflow execution logs older than 90 days, purges expired session tokens, and vacuums database tables — keeping storage costs and query performance optimal.
- Every 15 minutes monitoring check: A health-check workflow polls external API endpoints and internal services, compares response times and status codes against SLA thresholds, and fires a PagerDuty alert if any service is degraded.
Configuration
| Setting | Required | Description |
|---|---|---|
Schedule |
Required | A cron expression with 5 or 6 fields. Controls when the workflow fires. Must match the pattern minute hour day-of-month month day-of-week [second]. The 6th field (second) is optional and enables sub-minute scheduling. Validation is performed on save — an invalid pattern prevents the workflow from being published. |
Schedule field requires a valid cron pattern with exactly 5 or 6 whitespace-separated fields. Fewer or more fields cause a validation error on workflow save. The platform does not silently ignore invalid patterns.
Cron Expression Reference
Cron fields (left to right): minute hour day-of-month month day-of-week [second]
| Pattern | Meaning | Example Use Case |
|---|---|---|
0 9 * * 1-5 | 9:00 AM every weekday (Mon–Fri) | Daily morning report email to management |
*/15 * * * * | Every 15 minutes | Service health monitoring check |
0 0 1 * * | Midnight on the 1st of every month | Monthly invoice generation run |
0 2 * * 0 | 2:00 AM every Sunday | Weekly database cleanup and maintenance |
0 */1 * * * | Every hour on the hour | Hourly data sync from external supplier API |
30 17 * * 1-5 | 5:30 PM weekdays | End-of-day financial reconciliation |
0 6 1 1 * | 6:00 AM on January 1st | Annual compliance report generation |
0 8,12,17 * * 1-5 | 8 AM, 12 PM, and 5 PM weekdays | Three-times-daily stock price feed update |
*/5 9-17 * * 1-5 | Every 5 minutes during business hours | Real-time order status polling during trading hours |
0 0 L * * | Last day of every month at midnight | Month-end closing entries in accounting |
Output Ports
| Port | When It Fires |
|---|---|
main |
The cron schedule fires and the trigger activates successfully. All downstream nodes receive the trigger metadata fields. |
error |
The scheduler encounters an error initiating the workflow execution (e.g., the workflow is in a suspended or locked state, or the scheduler service itself has an internal fault). This port rarely fires under normal operating conditions. |
Output Fields
| Field | Type | Description |
|---|---|---|
trigger_time | DateTime | UTC timestamp of when the schedule fired. This is the scheduled time, not the actual execution start time (which may be slightly later due to platform load). Use this for business-logic decisions like "which day's records to process." |
trigger_type | string | Always "scheduled". Useful when a workflow has multiple trigger paths and needs to differentiate the source at runtime. |
Sample Configuration
{
"nodeType": "schedule-trigger",
"settings": {
"Schedule": "0 9 * * 1-5"
}
}
This fires at 9:00 AM Monday through Friday. The downstream nodes receive trigger_time (the 9:00 AM UTC timestamp) and trigger_type = "scheduled".
Sample Output
Success Port
{
"triggeredAt": "2025-03-15T08:00:00.000Z",
"scheduledAt": "2025-03-15T08:00:00.000Z",
"cronExpression": "0 8 * * 1-5",
"timezone": "America/New_York",
"executionId": "exec_20250315_080000",
"workflowId": "wf_daily_report",
"iterationCount": 45,
"driftMs": 12
}
Expression Reference
| Expression | Value |
|---|---|
{{ $output.scheduledTrigger.trigger_time }} | ISO datetime string of when the schedule fired, e.g. 2026-05-26T09:00:00Z. Use this to determine which data period to process (e.g., yesterday's transactions). |
{{ $output.scheduledTrigger.trigger_type }} | Always the string "scheduled". |
{{ $var.reportDate }} | After assigning the trigger date to a variable via VariableAssignment, access it anywhere downstream. |
trigger_time using a CodeExecute node immediately after the trigger. For example: var d = new Date(triggerTime); d.setDate(d.getDate() - 1); result = d.toISOString().substring(0, 10); gives yesterday's date in YYYY-MM-DD format.
Node Policies & GuardRails
| Policy | Rationale |
|---|---|
| Validate cron expressions before publishing | FlowStudio validates the cron pattern on save. Always use a cron expression validator tool during development to confirm the schedule fires at the expected times, especially for complex patterns with ranges and step values. |
Use trigger_time, not NOW(), for date-relative logic | Using trigger_time ensures deterministic, reproducible behaviour. If the workflow runs slightly late due to platform load, NOW() would produce a different date than expected. trigger_time always reflects the intended scheduled moment. |
| Keep schedule intervals appropriate to workload | A workflow that takes 5 minutes to complete should not be scheduled to run every 2 minutes. If the previous execution is still running when the next fires, the system will start a second concurrent execution. Use a minimum interval of 2x the average execution time. |
Always handle the error port | Connect the error port to a notification node (Slack, Email) to be alerted if the scheduler fails to start a run. Missed scheduled runs can have serious consequences for billing, compliance, and reporting workflows. |
| Use 5-field cron for daily/weekly/monthly schedules | The optional 6th field (seconds) is only needed for high-frequency sub-minute schedules. Do not use it for standard business schedules — it adds complexity without benefit and can cause confusion during maintenance. |
Pattern Examples
Pattern 1 — Daily 9 AM Payroll Exception Report
Fires every weekday at 9 AM. Queries for employees with missing clock-in records from the previous day and emails a formatted exception report to payroll administrators.
// ScheduledTrigger settings
{
"Schedule": "0 9 * * 1-5"
}
// Downstream CodeExecute — compute yesterday's date from trigger_time
var t = new Date(trigger_time);
t.setDate(t.getDate() - 1);
result = { processingDate: t.toISOString().substring(0, 10) };
// Downstream VariableAssignment — store for use in query nodes
{
"VariableName": "reportDate",
"ValueExpression": "{{ $output.dateCalc.result.processingDate }}"
}
// Downstream DB query uses: WHERE work_date = '{{ $var.reportDate }}'
Pattern 2 — Monthly Invoice Generation on the 1st
Fires at midnight on the first day of each month. Queries all active subscriptions, calculates charges, generates invoice PDFs, and queues for dispatch.
// ScheduledTrigger settings
{
"Schedule": "0 0 1 * *"
}
// Downstream CodeExecute — compute billing period (previous month)
var t = new Date(trigger_time);
var year = t.getFullYear();
var month = t.getMonth(); // 0-indexed, so this IS the previous month
if (month === 0) { month = 12; year = year - 1; }
var monthStr = month.toString().padStart(2, "0");
result = {
billingYear: year,
billingMonth: monthStr,
billingPeriod: year + "-" + monthStr
};
Pattern 3 — Every 15 Minutes Service Health Check
Polls a list of internal service endpoints every 15 minutes, checks response times and HTTP status codes, and fires a PagerDuty alert if any service fails its SLA threshold.
// ScheduledTrigger settings
{
"Schedule": "*/15 * * * *"
}
// Downstream CodeExecute — define services to check
result = {
services: [
{ name: "Auth API", url: "https://auth.internal/health", slaMs: 200 },
{ name: "Order API", url: "https://orders.internal/health", slaMs: 300 },
{ name: "Payment API", url: "https://payments.internal/health", slaMs: 500 }
],
checkTime: trigger_time
};
// Downstream Loop + HttpRequest: check each service
// Downstream CollectionOperation filter: item.responseMs > item.slaMs
// Downstream IfCondition: if any failures, fire PagerDuty alert node