# Schedule Triggers

Execute workflows automatically on recurring schedules using cron expressions or fixed intervals. Perfect for periodic automation, batch processing, and time-based workflows that need to run without manual intervention.

## Overview

Schedule triggers enable workflows to execute automatically based on time-based schedules. Unlike webhook triggers that respond to external events, schedule triggers run on a predictable, recurring basis at times you define.

**Key Features**:

* Cron expression support for flexible scheduling
* Fixed interval scheduling (hourly, daily, weekly, monthly)
* Optional start and end dates for time-bound schedules
* Configurable input parameters for each schedule
* Execution history and monitoring
* Workspace limit: 10 active schedules maximum

## How Schedule Triggers Work

### Execution Flow

```
Schedule Definition → Cron/Interval Check → Time Matches →
→ Workflow Run Created → Execute with Parameters → Log Execution
```

1. **Scheduler checks** all active schedules continuously
2. **Time matches** the cron expression or interval
3. **Workflow run created** with configured input parameters
4. **Workflow executes** asynchronously
5. **Execution logged** with success/failure status
6. **Next execution** calculated and scheduled

### Schedule Types

AgenticFlow supports two scheduling approaches:

#### 1. Cron Expression Scheduling

Use standard cron syntax for precise control over when workflows execute.

**Cron format**: `minute hour day-of-month month day-of-week`

**Common patterns**:

```
0 * * * *      → Every hour at minute 0
0 0 * * *      → Daily at midnight (00:00)
0 9 * * 1-5    → Weekdays at 9:00 AM
0 0 1 * *      → First day of every month at midnight
*/15 * * * *   → Every 15 minutes
0 */6 * * *    → Every 6 hours
0 0 * * 0      → Every Sunday at midnight
```

#### 2. Interval Scheduling

Specify a fixed interval with a time unit for simpler recurring schedules.

**Available time units**:

* Minutes
* Hours
* Days (default)
* Weeks
* Months
* Years

**Examples**:

* `1 Hour` → Every hour
* `3 Hours` → Every 3 hours
* `1 Day` → Daily
* `3 Days` → Every 3 days
* `1 Week` → Weekly
* `1 Month` → Monthly

## Creating a Schedule Trigger

### Step 1: Open Workflow Trigger Tab

1. Open your workflow in the workflow builder
2. Click the **Trigger** tab
3. Select **Scheduler** tab
4. Click **New Schedule**

### Step 2: Configure Basic Settings

**Schedule name** (required):

```
Example: Daily Sales Report
```

**Schedule description** (optional):

```
Example: Generates and emails sales reports every day at 8 AM
```

### Step 3: Select Schedule Type

Click the **Select schedule type** dropdown and choose between:

#### Option A: Cron Expression

For precise scheduling at specific times.

**Cron Expression**: Enter standard cron syntax

```
0 8 * * *
```

This runs daily at 8:00 AM.

**Common Frequencies**:

* **Hourly**: `0 * * * *`
* **Daily**: `0 0 * * *`
* **Weekly**: `0 0 * * 0`
* **Monthly**: `0 0 1 * *`

#### Option B: Interval (Recurring)

For simpler recurring schedules.

**Custom Interval**: Enter a number and select time unit

```
3 Days
```

**Time unit dropdown**:

* Minutes
* Hours
* Days
* Weeks
* Months
* Years

**Show Presets**: Quick access to common intervals

* Every hour
* Every day
* Every week
* Every month

### Step 4: Configure Parameters (Optional)

Click **Add Parameter** to define input data for your workflow.

**Parameters**: Key-value pairs passed to your workflow on each execution

**Important**: Input parameters are stored as-is and passed to your workflow without modification. Use your workflow's logic to handle dynamic values like current date/time.

**Example for workflow expecting order data**:

```json
{
  "report_type": "daily_sales",
  "format": "pdf",
  "recipients": ["sales@company.com", "manager@company.com"]
}
```

**For workflows that need current date/time**:

Since parameters are static, use workflow nodes to get current date/time:

1. Add a **JavaScript node** at the start of your workflow
2. Generate current date/time in the node
3. Use the output in subsequent nodes

**Example JavaScript node**:

```javascript
const now = new Date();
return {
  current_date: now.toISOString().split('T')[0],  // YYYY-MM-DD
  current_time: now.toTimeString().split(' ')[0],  // HH:MM:SS
  current_timestamp: Math.floor(now.getTime() / 1000),  // Unix timestamp
  report_type: "{{report_type}}",  // From schedule input
  format: "{{format}}"  // From schedule input
};
```

### Step 5: Create Schedule

Click **Create Scheduler** button to save and activate the schedule.

The schedule will execute immediately according to the configured interval or cron expression.

## Schedule Management

### Viewing Schedules

To view all schedules for a workflow:

1. Open your workflow in the builder
2. Click the **Trigger** tab
3. Select **Scheduler** tab
4. See all configured schedules

**Each schedule shows**:

* Schedule name and description
* Schedule type (Cron Expression or Interval)
* Configuration details
* Delete option (trash icon)

### Editing Schedules

Currently, schedules cannot be edited after creation. To modify a schedule:

1. Delete the existing schedule
2. Create a new schedule with updated settings

### Deleting Schedules

To remove a schedule:

1. Click the trash icon next to the schedule
2. Confirm deletion

**Note**: Deletion is permanent and cannot be undone.

## Monitoring Schedule Executions

To view execution history for scheduled workflows:

1. Navigate to the **History** tab in your workflow
2. Scheduled executions appear alongside manual runs
3. Each execution shows:
   * Execution timestamp
   * Run status (success/failed)
   * Run duration
   * Input parameters used

## Schedule Trigger Examples

### Example 1: Daily Report Generation

**Use Case**: Generate sales report every morning

**Configuration**:

```json
{
  "name": "Daily Sales Report",
  "description": "Generates sales report at 8 AM daily",
  "target": "workflow:550e8400-e29b-41d4-a716-446655440000",
  "schedule_type": "cron",
  "cron_expression": "0 8 * * *",
  "target_parameters": {
    "input": {
      "report_type": "daily_sales",
      "format": "pdf",
      "send_email": true,
      "recipients": ["team@company.com"]
    }
  },
  "enabled": true
}
```

**Workflow structure**:

1. **JavaScript node** - Get current date
2. **API Call node** - Fetch sales data for current date
3. **Generate PDF node** - Create report
4. **Send Email node** - Email to recipients from input

### Example 2: Hourly Data Sync

**Use Case**: Sync customer data from CRM every hour

**Configuration**:

```json
{
  "name": "Hourly CRM Sync",
  "description": "Syncs customer data every hour",
  "target": "workflow:6ba7b810-9dad-11d1-80b4-00c04fd430c8",
  "schedule_type": "cron",
  "cron_expression": "0 * * * *",
  "target_parameters": {
    "input": {
      "sync_type": "incremental",
      "source": "salesforce",
      "destination": "database"
    }
  },
  "enabled": true
}
```

**Execution pattern**: Every hour at minute 0 (1:00, 2:00, 3:00, etc.)

### Example 3: Weekly Backup

**Use Case**: Create database backup every Sunday at midnight

**Configuration**:

```json
{
  "name": "Weekly Database Backup",
  "description": "Backs up production database every Sunday",
  "target": "workflow:7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "schedule_type": "cron",
  "cron_expression": "0 0 * * 0",
  "target_parameters": {
    "input": {
      "backup_type": "full",
      "database": "production",
      "retention_days": 30,
      "notify_on_completion": true
    }
  },
  "enabled": true
}
```

**Execution pattern**: Every Sunday at 00:00

### Example 4: Monthly Billing Process

**Use Case**: Process monthly invoices on the first day of each month

**Configuration**:

```json
{
  "name": "Monthly Billing",
  "description": "Generates and sends invoices on first of month",
  "target": "workflow:8d0e7890-8536-51ef-855c-f18gc2g01bf8",
  "schedule_type": "cron",
  "cron_expression": "0 0 1 * *",
  "target_parameters": {
    "input": {
      "billing_period": "previous_month",
      "auto_send": true,
      "payment_due_days": 30
    }
  },
  "enabled": true
}
```

**Workflow includes JavaScript node to calculate**:

* Previous month's start/end dates
* Invoice generation date
* Payment due date

**Execution pattern**: First day of every month at midnight

### Example 5: Interval-Based Monitoring

**Use Case**: Check website health every 2 hours

**Configuration**:

```json
{
  "name": "Website Health Check",
  "description": "Monitors website availability every 2 hours",
  "target": "workflow:9e1f8901-9647-62fg-966d-g29hd3h12cg9",
  "schedule_type": "interval",
  "interval": "120",
  "target_parameters": {
    "input": {
      "urls": [
        "https://www.company.com",
        "https://api.company.com",
        "https://app.company.com"
      ],
      "timeout_seconds": 10,
      "alert_on_failure": true
    }
  },
  "enabled": true
}
```

**Execution pattern**: Every 2 hours

### Example 6: Time-Bound Campaign

**Use Case**: Send promotional emails during a campaign period

**Configuration**:

```json
{
  "name": "Holiday Campaign Emails",
  "description": "Sends promotional emails daily during holiday campaign",
  "target": "workflow:0f2g9012-0758-73gh-077e-h30ie4i23dh0",
  "schedule_type": "cron",
  "cron_expression": "0 10 * * *",
  "target_parameters": {
    "input": {
      "campaign_id": "holiday_2024",
      "segment": "active_customers"
    }
  },
  "schedule_start_date": "2024-12-01T00:00:00Z",
  "schedule_end_date": "2024-12-25T23:59:59Z",
  "enabled": true
}
```

**Execution pattern**: Daily at 10:00 AM, only from Dec 1-25, 2024

## Cron Expression Reference

### Cron Syntax

```
┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of month (1 - 31)
│ │ │ ┌───────────── month (1 - 12)
│ │ │ │ ┌───────────── day of week (0 - 6) (Sunday to Saturday)
│ │ │ │ │
* * * * *
```

### Special Characters

* `*` - Any value (every)
* `,` - List of values (e.g., `1,15` = 1st and 15th)
* `-` - Range of values (e.g., `1-5` = 1 through 5)
* `/` - Step values (e.g., `*/5` = every 5)

### Common Patterns

**Note**: The minimum supported frequency is hourly. For sub-hourly execution, contact support about your use case.

#### Hourly Variations

```
0 * * * *      → Every hour
0 */2 * * *    → Every 2 hours
0 */6 * * *    → Every 6 hours
0 9-17 * * *   → Every hour from 9 AM to 5 PM
```

#### Daily Variations

```
0 0 * * *      → Every day at midnight
0 9 * * *      → Every day at 9 AM
30 14 * * *    → Every day at 2:30 PM
0 0,12 * * *   → Every day at midnight and noon
```

#### Weekly Variations

```
0 0 * * 0      → Every Sunday at midnight
0 9 * * 1      → Every Monday at 9 AM
0 9 * * 1-5    → Weekdays at 9 AM
0 0 * * 6      → Every Saturday at midnight
```

#### Monthly Variations

```
0 0 1 * *      → First day of every month
0 0 15 * *     → 15th of every month
0 0 1,15 * *   → 1st and 15th of every month
```

#### Specific Months

```
0 0 1 1 *      → January 1st every year
0 0 1 */3 *    → First day of every quarter
0 0 1 6,12 *   → June 1st and December 1st
```

### Cron Expression Validators

Before using a cron expression, validate it:

* **crontab.guru** - Interactive cron expression editor
* **cron-expression-descriptor** - Human-readable descriptions
* Test your expression before deploying

## Handling Dynamic Data in Scheduled Workflows

Since schedule input parameters are static, use workflow nodes to handle dynamic data:

### Getting Current Date/Time

**JavaScript Node Example**:

```javascript
const now = new Date();

// Get various date formats
const currentDate = now.toISOString().split('T')[0];  // 2024-01-15
const currentTime = now.toTimeString().split(' ')[0];  // 14:30:45
const timestamp = Math.floor(now.getTime() / 1000);    // 1705329045

// Get yesterday's date
const yesterday = new Date(now);
yesterday.setDate(yesterday.getDate() - 1);
const yesterdayDate = yesterday.toISOString().split('T')[0];

// Get month start/end
const monthStart = new Date(now.getFullYear(), now.getMonth(), 1);
const monthEnd = new Date(now.getFullYear(), now.getMonth() + 1, 0);

return {
  current_date: currentDate,
  current_time: currentTime,
  timestamp: timestamp,
  yesterday: yesterdayDate,
  month_start: monthStart.toISOString().split('T')[0],
  month_end: monthEnd.toISOString().split('T')[0]
};
```

Use these values in subsequent nodes:

```
{{current_date}}
{{yesterday}}
{{month_start}}
```

### Calculating Relative Dates

**For monthly reports** (previous month):

```javascript
const now = new Date();
const firstOfThisMonth = new Date(now.getFullYear(), now.getMonth(), 1);
const firstOfLastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);
const lastOfLastMonth = new Date(firstOfThisMonth - 1);

return {
  period_start: firstOfLastMonth.toISOString().split('T')[0],
  period_end: lastOfLastMonth.toISOString().split('T')[0],
  report_month: firstOfLastMonth.toLocaleString('en-US', { month: 'long', year: 'numeric' })
};
```

### Combining Static and Dynamic Values

**Schedule provides static config**:

```json
{
  "input": {
    "report_type": "sales",
    "recipients": ["team@company.com"],
    "timezone": "America/New_York"
  }
}
```

**Workflow JavaScript node adds dynamic data**:

```javascript
const staticConfig = {
  report_type: "{{report_type}}",
  recipients: "{{recipients}}",
  timezone: "{{timezone}}"
};

const now = new Date();
const dynamicData = {
  generated_at: now.toISOString(),
  report_date: now.toISOString().split('T')[0]
};

return {
  ...staticConfig,
  ...dynamicData
};
```

## Best Practices

### 1. Choose Appropriate Schedule Granularity

**Match frequency to business need**:

* ✅ Choose the right time unit (minutes, hours, days, weeks, months)
* ❌ Don't over-schedule - wastes credits

**Recommended frequencies**:

* Email campaigns: Daily or weekly
* Data sync: Hourly to daily
* Monitoring: Every few hours
* Reports: Daily, weekly, or monthly
* Backups: Daily or weekly
* Billing: Monthly

### 2. Plan for Time-Bound Campaigns

For temporary automations (seasonal campaigns, limited-time offers):

**Recommended approach**:

* Create schedule when campaign starts
* Delete schedule when campaign ends
* Or use cron expression with specific date ranges

### 3. Design Workflows for Scheduled Execution

**Best practice workflow structure**:

1. **JavaScript node** - Generate dynamic values (dates, timestamps)
2. **Validation node** - Verify prerequisites
3. **Core logic** - Main workflow operations
4. **Error handling** - Catch and log failures
5. **Notification** - Alert on completion/failure

**Example**:

```
Start → Get Current Date → Validate Config → Fetch Data →
→ Process → Generate Report → Send Email → Log Success
```

### 4. Test Before Scheduling

**Testing checklist**:

1. ✅ Run workflow manually with test data
2. ✅ Verify all nodes execute successfully
3. ✅ Check output matches expectations
4. ✅ Test error scenarios
5. ✅ Create schedule with exact same input parameters
6. ✅ Monitor first few scheduled executions

### 5. Monitor Execution History

**Regular checks**:

* Review failed executions weekly
* Investigate patterns of failures
* Update schedules if business needs change

**Set up notifications**: Configure your workflow to notify you on failures:

* Send error emails
* Post to Slack/Teams
* Create support tickets

### 6. Respect Workspace Limits

**Maximum 10 active schedules per workspace**:

* Prioritize most important automations
* Disable unused schedules rather than deleting
* Combine related tasks into single workflows when possible

**Example consolidation**: Instead of:

* ❌ Schedule 1: Sync contacts (hourly)
* ❌ Schedule 2: Sync companies (hourly)
* ❌ Schedule 3: Sync deals (hourly)

Combine to:

* ✅ Single schedule: Sync all CRM data (hourly with parallel tasks)

### 7. Use Descriptive Names

**Good names**:

* ✅ "Daily Sales Report - 8 AM UTC"
* ✅ "Hourly Customer Data Sync - Salesforce to DB"
* ✅ "Weekly Backup - Sundays Midnight UTC"

**Bad names**:

* ❌ "Schedule 1"
* ❌ "Test"
* ❌ "Workflow Run"

### 8. Consider Time Zones

**Cron expressions use UTC**:

* Convert your local time to UTC
* Document timezone in schedule name/description
* Account for daylight saving time changes

**Example**:

* Want: 9 AM EST (UTC-5)
* Use: `0 14 * * *` (9 AM + 5 hours = 14:00 UTC)
* Name: "Daily Report - 9 AM EST"

### 9. Plan for Failures

**Your workflow should handle**:

* API failures (retries, fallbacks)
* Missing data (validation, defaults)
* Timeout scenarios

**Add error handling**:

* Try/catch patterns in JavaScript nodes
* Conditional branches for error cases
* Logging and notification on failures

## Troubleshooting

### Schedule Not Executing

**Check enabled status**:

* Ensure schedule is enabled (toggle is ON)
* Verify in schedule list that status shows "Active"

**Check schedule dates**:

* Ensure current date is between start and end dates
* If no start date set, schedule should execute immediately
* If end date passed, schedule will not execute

**Check workspace limits**:

* Verify you haven't exceeded 10 active schedules
* Disable unused schedules to free up slots

**Verify cron expression**:

* Use crontab.guru to validate syntax
* Ensure expression matches your intent
* Check for typos (common: wrong day-of-week)

### Wrong Execution Time

**Time zone confusion**:

* Cron expressions use UTC
* Convert local time to UTC for cron expression
* Document timezone in description

**Cron expression error**:

* Validate expression syntax
* Test with crontab.guru
* Check execution history for actual run times

**Example debugging**:

```
Want: 9 AM EST
Wrong: 0 9 * * *  (9 AM UTC = 4 AM EST)
Right: 0 14 * * * (2 PM UTC = 9 AM EST)
```

### Workflow Fails on Schedule But Works Manually

**Check input parameters**:

* Ensure target\_parameters match workflow input schema
* Test workflow manually with exact same parameters from schedule
* Verify workflow doesn't have hardcoded test values

**Check workflow state**:

* Ensure workflow is published (not draft)
* Verify workflow hasn't been modified since schedule created
* Check workflow is active and not disabled

**Review execution logs**:

1. Click workflow\_run\_id in execution history
2. Review each node's execution
3. Check for error messages
4. Compare with successful manual runs

### Executions Missing

**Check execution history**:

* Review last executions in schedule details
* Look for patterns in failures
* Check error messages

**Verify next execution time**:

* Schedule details show "Next Expected Execution"
* Should update after each run
* If stuck, try disabling and re-enabling

**Check credits**:

* Insufficient credits will prevent execution
* Review workspace credit balance
* Add credits if needed

### Performance Issues

**Workflow takes too long**:

* Review workflow execution time in logs
* Optimize slow nodes
* Consider breaking into multiple schedules

**Too many concurrent schedules**:

* Stagger execution times to avoid overlap
* Use different hours for similar schedules

**Example staggering**:

```
Schedule 1: 0 8 * * *   (8:00 AM)
Schedule 2: 0 9 * * *   (9:00 AM)
Schedule 3: 0 10 * * *  (10:00 AM)
```

## Comparing Schedule Triggers with Webhooks

| Feature               | Schedule Triggers           | Webhook Triggers               |
| --------------------- | --------------------------- | ------------------------------ |
| **Execution Pattern** | Time-driven (cron/interval) | Event-driven (HTTP request)    |
| **Frequency**         | Based on schedule           | Unlimited (on demand)          |
| **Input Data**        | Static parameters           | Dynamic from request body      |
| **Predictability**    | Highly predictable          | Depends on external caller     |
| **Use Case**          | Recurring automation        | Event response                 |
| **Best For**          | Reports, backups, sync      | Integrations, real-time events |
| **Workspace Limit**   | 10 active schedules         | Unlimited triggers             |
| **Configuration**     | Cron or interval            | HTTP method, auth              |

## API Reference

### Create Schedule

```http
POST /v1/scheduler/definitions
Content-Type: application/json
Authorization: Bearer your_api_key
```

**Request**:

```json
{
  "name": "Daily Report",
  "description": "Generate daily sales report",
  "target": "workflow:550e8400-e29b-41d4-a716-446655440000",
  "target_parameters": {
    "input": {
      "report_type": "sales",
      "format": "pdf"
    }
  },
  "schedule_type": "cron",
  "cron_expression": "0 8 * * *",
  "enabled": true,
  "schedule_start_date": "2024-01-01T00:00:00Z",
  "schedule_end_date": null
}
```

**Response**:

```json
{
  "id": "01HXXX123456789ABCDEF",
  "name": "Daily Report",
  "target": "workflow:550e8400-e29b-41d4-a716-446655440000",
  "schedule_type": "cron",
  "cron_expression": "0 8 * * *",
  "enabled": true,
  "system_next_expected_tick": "2024-01-16T08:00:00Z",
  "created_at": "2024-01-15T10:30:00Z"
}
```

### List Schedules

```http
GET /v1/scheduler/definitions
Authorization: Bearer your_api_key
```

**Response**:

```json
{
  "items": [
    {
      "id": "01HXXX123456789ABCDEF",
      "name": "Daily Report",
      "enabled": true,
      "system_next_expected_tick": "2024-01-16T08:00:00Z"
    }
  ],
  "total": 1
}
```

### Get Schedule Details

```http
GET /v1/scheduler/definitions/{schedule_id}
Authorization: Bearer your_api_key
```

### Update Schedule

```http
PUT /v1/scheduler/definitions/{schedule_id}
Content-Type: application/json
Authorization: Bearer your_api_key
```

**Request**:

```json
{
  "name": "Updated Daily Report",
  "cron_expression": "0 9 * * *",
  "enabled": true
}
```

### Delete Schedule

```http
DELETE /v1/scheduler/definitions/{schedule_id}
Authorization: Bearer your_api_key
```

### Get Execution History

```http
GET /v1/scheduler/definitions/{schedule_id}/executions
Authorization: Bearer your_api_key
```

**Response**:

```json
{
  "items": [
    {
      "id": "01HYYY234567890BCDEFG",
      "schedule_id": "01HXXX123456789ABCDEF",
      "workflow_run_id": "01HZZZ345678901CDEFGH",
      "status": "success",
      "started_at": "2024-01-15T08:00:00Z",
      "completed_at": "2024-01-15T08:02:15Z",
      "error": null
    }
  ],
  "total": 45
}
```

***

## Related Documentation

* [Triggers Overview](https://docs.agenticflow.ai/workflows/triggers) - All trigger types
* [Webhook Triggers](https://docs.agenticflow.ai/workflows/triggers/webhook-triggers) - Event-driven triggers
* [Workflow Execution](https://docs.agenticflow.ai/workflows/workflow-single-run) - Running workflows manually
* [Workflow Inputs](https://github.com/PixelML/agenticflow-docs/blob/main/docs/04-workflows/building-blocks/inputs/README.md) - Input configuration guide
* [Agent Triggers](https://docs.agenticflow.ai/ai-agents/trigger) - Triggers for AI agents
* [Platform Limits](https://docs.agenticflow.ai/workflows/triggers/broken-reference) - Workspace limits and quotas

***

**Ready to automate your recurring tasks?** Create your first schedule trigger and let your workflows run on autopilot.
