> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stateset.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Schedules & Automation

> Build powerful time-based automation workflows for your StateSet agents

## Introduction

StateSet Schedules transform your agents from reactive responders to proactive assistants. By automating time-based actions, your agents can anticipate needs, follow up on conversations, perform routine maintenance, and ensure nothing falls through the cracks. This guide shows you how to build sophisticated scheduling systems that work 24/7.

## What are Agent Schedules?

Agent Schedules are intelligent automation rules that trigger actions based on time. Unlike simple cron jobs, StateSet Schedules are context-aware, can adapt to business logic, and integrate seamlessly with your agent's capabilities.

### Key Features

<CardGroup cols={3}>
  <Card title="Flexible Timing" icon="calendar-days">
    Cron expressions, intervals, or business calendar rules
  </Card>

  <Card title="Smart Execution" icon="brain">
    Conditional logic, timezone awareness, and holiday handling
  </Card>

  <Card title="Reliable Delivery" icon="shield-check">
    Guaranteed execution with retry logic and monitoring
  </Card>
</CardGroup>

## Use Cases

<Tabs>
  <Tab title="Customer Success">
    * Follow up 24 hours after purchase
    * Check in weekly with VIP customers
    * Send satisfaction surveys after support tickets close
    * Remind about expiring subscriptions
  </Tab>

  <Tab title="Operations">
    * Daily inventory checks
    * Hourly order status updates
    * Weekly performance reports
    * Monthly billing reconciliation
  </Tab>

  <Tab title="Proactive Support">
    * Monitor for abandoned carts
    * Check unresolved tickets
    * Escalate aging issues
    * Perform health checks
  </Tab>
</Tabs>

## Getting Started

### Prerequisites

1. StateSet account with scheduling enabled
2. At least one configured agent
3. Understanding of cron expressions (optional)

<Note>
  Code examples focus on core API calls. For production-ready patterns (structured logging, retries, and error handling), see [Error Handling Best Practices](/guides/error-handling-best-practices).
</Note>

### Installation

<CodeGroup>
  ```bash npm theme={null}
  npm install StateSet-node @StateSet/scheduler
  ```

  ```bash yarn theme={null}
  yarn add StateSet-node @StateSet/scheduler
  ```

  ```bash pip theme={null}
  pip install StateSet StateSet-scheduler
  ```
</CodeGroup>

## Creating Schedules

### Basic Schedule Example

```javascript theme={null}
import { StateSetClient } from 'StateSet-node';

const client = new StateSetClient({
  apiKey: process.env.STATESET_API_KEY
});

async function createDailyCheckIn() {
  const schedule = await client.schedules.create({
    agent_id: 'agent_123',
    name: 'daily_customer_check_in',
    description: 'Check in with customers who have open issues',
    schedule: {
      type: 'cron',
      expression: '0 9 * * 1-5', // 9 AM weekdays
      timezone: 'America/New_York'
    },
    action: {
      type: 'function',
      function: 'check_open_issues',
      parameters: {
        priority: 'high',
        age_days: 2
      }
    },
    enabled: true,
    metadata: {
      category: 'customer_success',
      owner: 'support_team'
    }
  });
  
  logger.info('Schedule created:', schedule.id);
  return schedule;
}
```

### Advanced Schedule with Conditions

```javascript theme={null}
async function createSmartFollowUp() {
  const schedule = await client.schedules.create({
    agent_id: 'agent_123',
    name: 'smart_purchase_follow_up',
    description: 'Intelligent post-purchase follow-up based on order value and customer type',
    
    // Complex scheduling rules
    schedule: {
      type: 'event_based',
      trigger: 'order.completed',
      delay: {
        unit: 'hours',
        value: 24,
        business_hours_only: true
      },
      conditions: [
        {
          field: 'order.total',
          operator: 'greater_than',
          value: 100
        },
        {
          field: 'customer.lifetime_value',
          operator: 'greater_than',
          value: 500
        }
      ]
    },
    
    // Dynamic action based on context
    action: {
      type: 'workflow',
      steps: [
        {
          type: 'evaluate',
          condition: 'order.total > 1000',
          true_action: {
            type: 'send_message',
            template: 'vip_thank_you',
            channel: 'email'
          },
          false_action: {
            type: 'send_message',
            template: 'standard_thank_you',
            channel: 'email'
          }
        },
        {
          type: 'wait',
          duration: '7d'
        },
        {
          type: 'send_message',
          template: 'product_review_request',
          channel: 'sms'
        }
      ]
    },
    
    // Error handling
    error_handling: {
      retry_attempts: 3,
      retry_delay: '5m',
      on_failure: 'create_ticket'
    }
  });
  
  return schedule;
}
```

## Schedule Types

### 1. Cron-Based Schedules

```javascript theme={null}
// Common cron patterns
const cronPatterns = {
  // Every hour
  hourly: '0 * * * *',
  
  // Every day at 9 AM
  daily_morning: '0 9 * * *',
  
  // Every Monday at 10 AM
  weekly_monday: '0 10 * * 1',
  
  // First day of month at midnight
  monthly_start: '0 0 1 * *',
  
  // Every 15 minutes during business hours
  business_quarter_hour: '*/15 9-17 * * 1-5',
  
  // Last Friday of month at 5 PM
  monthly_last_friday: '0 17 * * 5L'
};

// Create schedule with cron
const cronSchedule = await client.schedules.create({
  agent_id: 'agent_123',
  name: 'hourly_metrics_check',
  schedule: {
    type: 'cron',
    expression: cronPatterns.hourly,
    timezone: 'UTC'
  },
  action: {
    type: 'function',
    function: 'collect_hourly_metrics'
  }
});
```

### 2. Interval-Based Schedules

```javascript theme={null}
const intervalSchedule = await client.schedules.create({
  agent_id: 'agent_123',
  name: 'continuous_monitoring',
  schedule: {
    type: 'interval',
    every: {
      unit: 'minutes',
      value: 30
    },
    start_time: '2024-01-01T00:00:00Z',
    end_time: '2024-12-31T23:59:59Z'
  },
  action: {
    type: 'function',
    function: 'monitor_system_health'
  }
});
```

### 3. Event-Triggered Schedules

```javascript theme={null}
const eventSchedule = await client.schedules.create({
  agent_id: 'agent_123',
  name: 'abandoned_cart_recovery',
  schedule: {
    type: 'event_based',
    trigger: 'cart.abandoned',
    delay: {
      unit: 'hours',
      value: 2
    },
    conditions: [
      {
        field: 'cart.value',
        operator: 'greater_than',
        value: 50
      }
    ]
  },
  action: {
    type: 'workflow',
    workflow_id: 'abandoned_cart_recovery_flow'
  }
});
```

### 4. Business Calendar Schedules

```javascript theme={null}
const businessSchedule = await client.schedules.create({
  agent_id: 'agent_123',
  name: 'quarterly_business_review',
  schedule: {
    type: 'business_calendar',
    calendar: 'fiscal_2024',
    events: [
      'quarter_end',
      'quarter_start'
    ],
    offset: {
      days: -5,
      business_days_only: true
    }
  },
  action: {
    type: 'function',
    function: 'prepare_quarterly_report'
  },
  notifications: {
    on_start: ['email:manager@company.com'],
    on_complete: ['slack:#reports']
  }
});
```

## Complex Workflows

### Multi-Step Customer Journey

```javascript theme={null}
async function createCustomerJourneySchedule() {
  const journey = await client.schedules.create({
    agent_id: 'agent_123',
    name: 'new_customer_onboarding',
    description: 'Automated 30-day onboarding journey',
    
    schedule: {
      type: 'journey',
      trigger: 'customer.created',
      steps: [
        {
          delay: '1h',
          action: 'send_welcome_email'
        },
        {
          delay: '1d',
          action: 'check_first_login',
          condition: 'customer.logins == 0',
          true_action: 'send_login_reminder'
        },
        {
          delay: '3d',
          action: 'send_getting_started_guide'
        },
        {
          delay: '7d',
          action: 'schedule_onboarding_call',
          condition: 'customer.plan == "enterprise"'
        },
        {
          delay: '14d',
          action: 'send_feature_highlights'
        },
        {
          delay: '30d',
          action: 'send_feedback_survey'
        }
      ]
    },
    
    tracking: {
      metrics: ['completion_rate', 'engagement_score'],
      report_to: 'customer_success_dashboard'
    }
  });
  
  return journey;
}
```

### Intelligent Escalation System

```javascript theme={null}
async function createEscalationSchedule() {
  const escalation = await client.schedules.create({
    agent_id: 'agent_123',
    name: 'ticket_escalation_system',
    
    schedule: {
      type: 'continuous',
      check_interval: '15m'
    },
    
    rules: [
      {
        name: 'urgent_escalation',
        condition: {
          all: [
            { field: 'ticket.priority', operator: 'equals', value: 'urgent' },
            { field: 'ticket.age_minutes', operator: 'greater_than', value: 30 },
            { field: 'ticket.status', operator: 'not_equals', value: 'resolved' }
          ]
        },
        action: {
          type: 'escalate',
          to: 'senior_support',
          notification: 'immediate'
        }
      },
      {
        name: 'standard_escalation',
        condition: {
          all: [
            { field: 'ticket.priority', operator: 'equals', value: 'normal' },
            { field: 'ticket.age_hours', operator: 'greater_than', value: 4 }
          ]
        },
        action: {
          type: 'escalate',
          to: 'support_lead',
          notification: 'email'
        }
      },
      {
        name: 'vip_escalation',
        condition: {
          all: [
            { field: 'customer.tier', operator: 'equals', value: 'vip' },
            { field: 'ticket.age_minutes', operator: 'greater_than', value: 15 }
          ]
        },
        action: {
          type: 'escalate',
          to: 'vip_support',
          notification: 'phone'
        }
      }
    ]
  });
  
  return escalation;
}
```

## Schedule Management

### Monitoring and Analytics

```javascript theme={null}
class ScheduleMonitor {
  async getScheduleMetrics(scheduleId, timeframe = '7d') {
    const metrics = await client.schedules.getMetrics({
      schedule_id: scheduleId,
      timeframe: timeframe,
      metrics: [
        'execution_count',
        'success_rate',
        'average_duration',
        'failure_reasons'
      ]
    });
    
    return {
      health: this.calculateHealth(metrics),
      performance: {
        executions: metrics.execution_count,
        success_rate: `${metrics.success_rate}%`,
        avg_duration: `${metrics.average_duration}ms`,
        reliability: this.calculateReliability(metrics)
      },
      issues: this.identifyIssues(metrics),
      recommendations: this.generateRecommendations(metrics)
    };
  }
  
  calculateHealth(metrics) {
    if (metrics.success_rate >= 99) return 'excellent';
    if (metrics.success_rate >= 95) return 'good';
    if (metrics.success_rate >= 90) return 'fair';
    return 'poor';
  }
  
  identifyIssues(metrics) {
    const issues = [];
    
    if (metrics.success_rate < 95) {
      issues.push({
        type: 'reliability',
        severity: 'high',
        message: `Success rate ${metrics.success_rate}% is below threshold`
      });
    }
    
    if (metrics.average_duration > 5000) {
      issues.push({
        type: 'performance',
        severity: 'medium',
        message: 'Schedule execution taking longer than expected'
      });
    }
    
    return issues;
  }
}
```

### Bulk Schedule Operations

```javascript theme={null}
// Pause all schedules for maintenance
async function pauseAllSchedules(reason) {
  const schedules = await client.schedules.list({
    filter: { enabled: true }
  });
  
  const results = await Promise.all(
    schedules.map(schedule => 
      client.schedules.update({
        id: schedule.id,
        enabled: false,
        pause_reason: reason,
        paused_at: new Date().toISOString()
      })
    )
  );
  
  logger.info(`Paused ${results.length} schedules`);
  return results;
}

// Migrate schedules to new timezone
async function migrateScheduleTimezones(fromTz, toTz) {
  const schedules = await client.schedules.list({
    filter: { 
      'schedule.timezone': fromTz,
      'schedule.type': 'cron'
    }
  });
  
  for (const schedule of schedules) {
    const updatedCron = convertCronTimezone(
      schedule.schedule.expression,
      fromTz,
      toTz
    );
    
    await client.schedules.update({
      id: schedule.id,
      schedule: {
        ...schedule.schedule,
        expression: updatedCron,
        timezone: toTz
      }
    });
  }
}
```

## Testing Schedules

### Test Framework

```javascript theme={null}
class ScheduleTester {
  async testSchedule(scheduleId, options = {}) {
    const testRun = await client.schedules.test({
      schedule_id: scheduleId,
      mode: options.mode || 'dry_run',
      test_data: options.testData || {},
      simulate_time: options.simulateTime || new Date()
    });
    
    return {
      would_execute: testRun.would_execute,
      execution_time: testRun.execution_time,
      action_preview: testRun.action_preview,
      validation_errors: testRun.validation_errors,
      estimated_duration: testRun.estimated_duration
    };
  }
  
  async simulateScheduleRun(scheduleId, days = 7) {
    const simulations = [];
    const schedule = await client.schedules.get(scheduleId);
    
    for (let i = 0; i < days * 24; i++) {
      const simulatedTime = new Date();
      simulatedTime.setHours(simulatedTime.getHours() + i);
      
      const wouldRun = this.evaluateCron(
        schedule.schedule.expression,
        simulatedTime,
        schedule.schedule.timezone
      );
      
      if (wouldRun) {
        simulations.push({
          time: simulatedTime,
          action: schedule.action
        });
      }
    }
    
    return {
      schedule_id: scheduleId,
      simulation_period: `${days} days`,
      expected_runs: simulations.length,
      run_times: simulations
    };
  }
}

// Usage
const tester = new ScheduleTester();
const results = await tester.simulateScheduleRun('schedule_123', 30);
logger.info(`Schedule would run ${results.expected_runs} times in 30 days`);
```

## Error Handling & Recovery

### Robust Error Handling

```javascript theme={null}
const resilientSchedule = await client.schedules.create({
  agent_id: 'agent_123',
  name: 'critical_daily_task',
  
  schedule: {
    type: 'cron',
    expression: '0 2 * * *' // 2 AM daily
  },
  
  action: {
    type: 'function',
    function: 'process_daily_reports'
  },
  
  error_handling: {
    retry_strategy: {
      max_attempts: 5,
      delays: [30, 60, 300, 900, 1800], // seconds
      backoff_type: 'exponential'
    },
    
    failure_actions: [
      {
        after_attempts: 3,
        action: {
          type: 'notify',
          channel: 'email',
          recipients: ['oncall@company.com'],
          template: 'schedule_failure_warning'
        }
      },
      {
        after_attempts: 5,
        action: {
          type: 'escalate',
          create_incident: true,
          severity: 'high',
          assign_to: 'oncall_engineer'
        }
      }
    ],
    
    recovery: {
      type: 'compensating_action',
      action: 'run_backup_process',
      notify_on_recovery: true
    }
  },
  
  monitoring: {
    alert_on_miss: true,
    alert_on_delay: {
      threshold_minutes: 15
    },
    health_check_endpoint: 'https://status.company.com/schedules/daily_task'
  }
});
```

### Schedule Dependencies

```javascript theme={null}
async function createDependentSchedules() {
  // Parent schedule
  const parentSchedule = await client.schedules.create({
    agent_id: 'agent_123',
    name: 'data_collection',
    schedule: { type: 'cron', expression: '0 1 * * *' },
    action: { type: 'function', function: 'collect_daily_data' }
  });
  
  // Child schedule that depends on parent
  const childSchedule = await client.schedules.create({
    agent_id: 'agent_123',
    name: 'data_processing',
    schedule: {
      type: 'dependent',
      depends_on: parentSchedule.id,
      trigger: 'on_success',
      delay: '30m'
    },
    action: { type: 'function', function: 'process_collected_data' }
  });
  
  // Grandchild schedule
  const reportSchedule = await client.schedules.create({
    agent_id: 'agent_123',
    name: 'report_generation',
    schedule: {
      type: 'dependent',
      depends_on: childSchedule.id,
      trigger: 'on_complete',
      conditions: [
        { field: 'output.record_count', operator: 'greater_than', value: 0 }
      ]
    },
    action: { type: 'function', function: 'generate_report' }
  });
  
  return { parentSchedule, childSchedule, reportSchedule };
}
```

## Best Practices

### 1. Design for Reliability

```javascript theme={null}
// Good: Idempotent actions with proper error handling
const reliableSchedule = {
  action: {
    type: 'function',
    function: 'process_orders',
    parameters: {
      mode: 'idempotent',
      check_processed: true,
      batch_size: 100
    }
  },
  error_handling: {
    retry_attempts: 3,
    alert_on_failure: true
  }
};

// Bad: Non-idempotent actions without safeguards
const unreliableSchedule = {
  action: {
    type: 'function',
    function: 'send_emails',
    parameters: {
      send_all: true // Could send duplicates
    }
  }
};
```

### 2. Timezone Awareness

```javascript theme={null}
// Good: Explicit timezone handling
const timezoneAwareSchedule = {
  schedule: {
    type: 'cron',
    expression: '0 9 * * 1-5',
    timezone: 'America/New_York',
    observe_dst: true
  },
  metadata: {
    business_hours: '9 AM - 5 PM EST/EDT',
    skip_holidays: true
  }
};

// Bad: Ambiguous timing
const ambiguousSchedule = {
  schedule: {
    type: 'cron',
    expression: '0 9 * * *' // Which 9 AM?
  }
};
```

### 3. Performance Optimization

```javascript theme={null}
class ScheduleOptimizer {
  // Batch similar schedules
  async optimizeSchedules() {
    const schedules = await client.schedules.list();
    
    // Group schedules by execution time
    const grouped = this.groupByExecutionTime(schedules);
    
    // Create batch processors
    for (const [time, group] of Object.entries(grouped)) {
      if (group.length > 5) {
        await this.createBatchSchedule(time, group);
      }
    }
  }
  
  async createBatchSchedule(time, schedules) {
    return client.schedules.create({
      name: `batch_processor_${time}`,
      schedule: { type: 'cron', expression: time },
      action: {
        type: 'batch',
        actions: schedules.map(s => s.action),
        parallel: true,
        max_concurrent: 10
      }
    });
  }
}
```

## Troubleshooting

### Common Issues

1. **Schedule Not Executing**
   * Verify timezone settings
   * Check schedule is enabled
   * Validate cron expression
   * Review execution logs

2. **Missed Executions**
   * Check system time sync
   * Review resource limits
   * Verify agent availability
   * Check for conflicting schedules

3. **Performance Issues**
   * Batch similar operations
   * Optimize action execution
   * Use appropriate intervals
   * Monitor resource usage

### Debug Tools

```javascript theme={null}
// Schedule debugger
async function debugSchedule(scheduleId) {
  const debug = await client.schedules.debug({
    schedule_id: scheduleId,
    include: ['execution_history', 'next_runs', 'conflicts']
  });
  
  logger.info('Schedule Debug Info:');
  logger.info('- Status:', debug.status);
  logger.info('- Last run:', debug.last_execution);
  logger.info('- Next 5 runs:', debug.next_runs.slice(0, 5););
  logger.info('- Conflicts:', debug.conflicts);
  logger.info('- Error rate:', debug.error_rate);
  
  return debug;
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Advanced Workflows" icon="sitemap" href="/guides/workflow-automation">
    Build complex multi-step automated processes
  </Card>

  <Card title="Event-Driven Architecture" icon="bolt" href="/guides/event-driven">
    Create reactive systems with event-based scheduling
  </Card>
</CardGroup>

***

<Note>
  **Pro Tip**: Start with simple schedules and gradually add complexity. Always test schedules in a staging environment before deploying to production.
</Note>

For schedule templates and examples, visit our [GitHub repository](https://github.com/StateSet/schedule-examples) or contact [support@StateSet.com](mailto:support@StateSet.com).
