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
Flexible Timing
Cron expressions, intervals, or business calendar rules
Smart Execution
Conditional logic, timezone awareness, and holiday handling
Reliable Delivery
Guaranteed execution with retry logic and monitoring
Use Cases
- Customer Success
- Operations
- Proactive Support
- Follow up 24 hours after purchase
- Check in weekly with VIP customers
- Send satisfaction surveys after support tickets close
- Remind about expiring subscriptions
Getting Started
Prerequisites
- StateSet account with scheduling enabled
- At least one configured agent
- Understanding of cron expressions (optional)
Installation
Copy
Ask AI
npm install stateset-node @stateset/scheduler
Creating Schedules
Basic Schedule Example
Copy
Ask AI
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'
}
});
console.log('Schedule created:', schedule.id);
return schedule;
}
Advanced Schedule with Conditions
Copy
Ask AI
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
Copy
Ask AI
// 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
Copy
Ask AI
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
Copy
Ask AI
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
Copy
Ask AI
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
Copy
Ask AI
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
Copy
Ask AI
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
Copy
Ask AI
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
Copy
Ask AI
// 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()
})
)
);
console.log(`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
Copy
Ask AI
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);
console.log(`Schedule would run ${results.expected_runs} times in 30 days`);
Error Handling & Recovery
Robust Error Handling
Copy
Ask AI
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
Copy
Ask AI
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
Copy
Ask AI
// 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
Copy
Ask AI
// 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
Copy
Ask AI
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
-
Schedule Not Executing
- Verify timezone settings
- Check schedule is enabled
- Validate cron expression
- Review execution logs
-
Missed Executions
- Check system time sync
- Review resource limits
- Verify agent availability
- Check for conflicting schedules
-
Performance Issues
- Batch similar operations
- Optimize action execution
- Use appropriate intervals
- Monitor resource usage
Debug Tools
Copy
Ask AI
// Schedule debugger
async function debugSchedule(scheduleId) {
const debug = await client.schedules.debug({
schedule_id: scheduleId,
include: ['execution_history', 'next_runs', 'conflicts']
});
console.log('Schedule Debug Info:');
console.log('- Status:', debug.status);
console.log('- Last run:', debug.last_execution);
console.log('- Next 5 runs:', debug.next_runs.slice(0, 5));
console.log('- Conflicts:', debug.conflicts);
console.log('- Error rate:', debug.error_rate);
return debug;
}
Next Steps
Advanced Workflows
Build complex multi-step automated processes
Event-Driven Architecture
Create reactive systems with event-based scheduling
Pro Tip: Start with simple schedules and gradually add complexity. Always test schedules in a staging environment before deploying to production.