Skip to main content

Scheduling & Availability

Control when your agent is available to handle calls by configuring business hours and timezone settings. Scheduling ensures your agent only takes calls during appropriate times and manages call routing based on your configured hours.

Overview

Agent scheduling allows you to:
  • Define business hours for each day of the week
  • Set timezone for accurate call routing and scheduling
  • Configure call handling for outside-hours requests
  • Manage multiple time blocks per day for complex schedules
Scheduling is optional. If no schedule is configured, your agent will be available 24/7 when enabled.

When to Use Scheduling

Use scheduling when you need to:
  • Match business hours: Only accept calls during your organization’s operating hours
  • Geographic alignment: Match agent availability to specific timezones
  • Resource planning: Limit call volume during specific time windows
  • Regional operations: Support different hours for different regions with multiple agents
Pro Tip: Even if you operate 24/7, configure scheduling with your primary timezone. This ensures accurate call timestamps and scheduling in your analytics.

Configuring Business Hours

Dashboard Configuration

Configure scheduling in the Schedule tab when creating or editing an agent: Schedule tab showing business hours configuration Configure business hours for each day of the week

Step 1: Set Timezone

Select the timezone for your agent’s schedule:
  1. Click the Timezone dropdown
  2. Search for your timezone (e.g., “America/New_York”, “Europe/London”)
  3. Select the appropriate IANA timezone identifier
Timezone is required when scheduling is enabled. All business hours are interpreted in this timezone.
Common Timezones:
  • US East Coast: America/New_York
  • US West Coast: America/Los_Angeles
  • US Central: America/Chicago
  • UK: Europe/London
  • Central Europe: Europe/Paris
  • India: Asia/Kolkata
  • Japan: Asia/Tokyo
  • Australia (Sydney): Australia/Sydney

Step 2: Configure Daily Hours

Set business hours for each day of the week: For each day (Monday-Sunday):
  1. Toggle the day ON to enable it (enabling a day automatically adds a 00:00-23:59 slot)
  2. Click the time selectors to adjust Start Time and End Time
  3. Click ”+” button to add additional time blocks for split shifts
  4. Click ”×” button to remove a time block (if multiple exist)
  5. Use the Copy icon to duplicate this day’s schedule to other days
Time Format Toggle: The Schedule Editor includes a 12h/24h time format toggle at the top. This controls how times are displayed in the dropdowns but does not affect the underlying data (times are always stored in 24-hour format). Example: Standard Business Hours
Monday:    09:00 - 17:00
Tuesday:   09:00 - 17:00
Wednesday: 09:00 - 17:00
Thursday:  09:00 - 17:00
Friday:    09:00 - 17:00
Saturday:  OFF
Sunday:    OFF
Example: Split Shift (Lunch Break)
Monday:    09:00 - 12:00, 13:00 - 18:00
Tuesday:   09:00 - 12:00, 13:00 - 18:00
Wednesday: 09:00 - 12:00, 13:00 - 18:00
Thursday:  09:00 - 12:00, 13:00 - 18:00
Friday:    09:00 - 12:00, 13:00 - 18:00
Example: 24/7 with Reduced Hours on Weekends
Monday-Friday:   00:00 - 23:59
Saturday:        10:00 - 16:00
Sunday:          10:00 - 16:00
Bulk Operations: Use the copy icon next to any day’s schedule to quickly apply the same hours to other days, then customize individual days as needed.
Empty Schedule Fallback: If you clear all time ranges for every day (leaving the schedule completely empty), the backend will automatically fall back to a 24/7 availability schedule (00:00-23:59 for all seven days). To truly disable a day, keep at least one other day enabled or disable the agent entirely.

API Configuration

Configure scheduling programmatically when creating or updating agents:
const response = await fetch('https://blackbox.dasha.ai/api/v1/agents', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: "Customer Support Agent",
    isEnabled: true,
    config: {
      version: "v1",
      primaryLanguage: "en-US",
      llmConfig: {
        version: "v1",
        vendor: "openai",
        model: "gpt-4.1-mini",
        prompt: "You are a helpful customer support agent."
      },
      ttsConfig: {
        version: "v1",
        vendor: "Dasha",
        voiceId: "default-voice"
      },
      sttConfig: {
        version: "v1",
        vendor: "Auto"
      },
      features: {
        version: "v1"
      }
    },
    schedule: {
      timezone: "America/New_York",
      mon: [
        { start: { hour: 9, minute: 0 }, end: { hour: 17, minute: 0 } }
      ],
      tue: [
        { start: { hour: 9, minute: 0 }, end: { hour: 17, minute: 0 } }
      ],
      wed: [
        { start: { hour: 9, minute: 0 }, end: { hour: 17, minute: 0 } }
      ],
      thu: [
        { start: { hour: 9, minute: 0 }, end: { hour: 17, minute: 0 } }
      ],
      fri: [
        { start: { hour: 9, minute: 0 }, end: { hour: 17, minute: 0 } }
      ],
      sat: [],  // Not available on Saturdays
      sun: []   // Not available on Sundays
    }
  })
});

const agent = await response.json();
console.log('Agent created with schedule:', agent.agentId);

Schedule Data Structure

AgentSchedule Schema

interface AgentSchedule {
  timezone: string;        // IANA timezone (e.g., "America/New_York")
  mon?: TimeSlot[] | null; // Monday time slots
  tue?: TimeSlot[] | null; // Tuesday time slots
  wed?: TimeSlot[] | null; // Wednesday time slots
  thu?: TimeSlot[] | null; // Thursday time slots
  fri?: TimeSlot[] | null; // Friday time slots
  sat?: TimeSlot[] | null; // Saturday time slots
  sun?: TimeSlot[] | null; // Sunday time slots
}

interface TimeSlot {
  start: TimeOfDay;
  end: TimeOfDay;
}

interface TimeOfDay {
  hour: number;   // 0-23
  minute: number; // 0-59
}

Field Details

timezone (required)
  • Type: string
  • Format: IANA timezone identifier
  • Examples: "America/New_York", "Europe/London", "Asia/Tokyo"
  • Required when schedule is configured
mon, tue, wed, thu, fri, sat, sun (optional)
  • Type: TimeSlot[] or null
  • Empty array [] = Agent not available on this day
  • Array of time slots = Agent available during specified times
  • If all days are empty arrays or null, backend applies 24/7 fallback
TimeSlot
  • start: Start time of availability window
  • end: End time of availability window
  • Multiple time slots per day supported (for split shifts)
TimeOfDay
  • hour: 0-23 (24-hour format)
  • minute: 0-59
Validation Rules:
  • start time must be before end time (no overnight ranges)
  • Time slots within a day cannot overlap
  • Hours must be 0-23, minutes must be 0-59
  • Use 23:59 as the end time for “end of day” (not 24:00)

Timezone Handling

Understanding Timezones

BlackBox uses IANA timezone identifiers (e.g., “America/New_York”) for accurate timezone handling: Why IANA Timezones?
  • Handles daylight saving time (DST) automatically
  • More accurate than UTC offsets
  • Accounts for historical timezone changes
  • Consistent with modern web standards
Common Timezone Identifiers:
RegionTimezone IdentifierUTC Offset (Standard)
New York, USAAmerica/New_YorkUTC-5 (EST)
Los Angeles, USAAmerica/Los_AngelesUTC-8 (PST)
Chicago, USAAmerica/ChicagoUTC-6 (CST)
London, UKEurope/LondonUTC+0 (GMT)
Paris, FranceEurope/ParisUTC+1 (CET)
Tokyo, JapanAsia/TokyoUTC+9 (JST)
Sydney, AustraliaAustralia/SydneyUTC+10 (AEST)
Mumbai, IndiaAsia/KolkataUTC+5:30 (IST)
DST Handling: The platform automatically adjusts for daylight saving time. You don’t need to update schedules when DST changes occur.

Scheduling Calls Across Timezones

When scheduling outbound calls to different timezones: Best Practices:
  1. Set agent timezone to your business location
  2. Schedule calls using recipient’s local time
  3. Use deadline parameter in API calls to specify exact call time
  4. Consider caller timezone when choosing call windows
Example: Scheduling to Different Timezones
// Agent in New York (UTC-5), calling customer in Los Angeles (UTC-8)

// Create agent with New York timezone
const agent = await createAgent({
  schedule: {
    timezone: "America/New_York",
    mon: [{ start: { hour: 9, minute: 0 }, end: { hour: 17, minute: 0 } }]
  }
});

// Schedule call for 10 AM Los Angeles time (1 PM New York time)
const call = await fetch('https://blackbox.dasha.ai/api/v1/calls', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    agentId: agent.agentId,
    endpoint: "+13105551234",
    callDeadline: "2025-10-20T10:00:00-07:00" // ISO 8601 with LA timezone
  })
});
Tip: Use ISO 8601 datetime format with timezone offset when scheduling calls to ensure accurate timing across timezones.

Managing Holidays

Since BlackBox does not provide a built-in holiday configuration UI, you can manage holidays using the following approaches:

Option 1: Disable Agent Temporarily

Disable the agent programmatically for holidays:
// Disable agent for holiday
await fetch(`https://blackbox.dasha.ai/api/v1/agents/${agentId}`, {
  method: 'PUT',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: "Customer Support Agent",
    isEnabled: false,
    config: {
      // ... rest of config unchanged
    },
    schedule: {
      // ... schedule unchanged
    }
  })
});

// Re-enable after holiday (schedule this with your automation)
await fetch(`https://blackbox.dasha.ai/api/v1/agents/${agentId}`, {
  method: 'PUT',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: "Customer Support Agent",
    isEnabled: true,
    config: {
      // ... rest of config unchanged
    },
    schedule: {
      // ... schedule unchanged
    }
  })
});

Option 2: Holiday Guard via Start Webhook

Use a start webhook to reject calls on specific dates:
// In your start webhook handler:
app.post('/webhook/start', (req, res) => {
  const today = new Date();
  const holidays = ['2025-12-25', '2025-01-01']; // Christmas, New Year
  const todayStr = today.toISOString().split('T')[0];

  if (holidays.includes(todayStr)) {
    res.json({
      additionalContext: "Today is a company holiday. We will return on the next business day.",
      shouldContinue: false // End call after greeting
    });
  } else {
    res.json({ shouldContinue: true });
  }
});
Best Practice: Maintain holiday lists in your external automation system rather than relying on platform-level configuration. This gives you more control and flexibility for managing downtime.

Call Routing & Behavior

Calls During Business Hours

When a call arrives within business hours:
  1. Agent accepts the call immediately
  2. Call proceeds normally according to agent configuration
  3. Full conversation capabilities available

Calls Outside Business Hours

When a call arrives outside business hours: Inbound Calls:
  • The platform does not automatically reject inbound calls based on schedule
  • Recommendation: Use a start webhook to handle after-hours inbound calls (see “Managing Holidays” section above)
  • Alternative: Disable the agent entirely during after-hours periods
Scheduled Outbound Calls:
  • Calls are enqueued even when outside agent working hours
  • The scheduler calculates nextScheduleTime based on the agent’s schedule using ScheduleUtils.CalculateNextScheduleTimeWithTimezone
  • Calls remain in the queue with status Created until working hours resume
  • When the scheduler runs during working hours and finds calls with nextScheduleTime <= now, it checks if the current time is within working hours using ScheduleUtils.IsTimeWithinAgentWorkHours
  • If within working hours: Call status advances to PendingQueued and is dispatched
  • If outside working hours but deadline not yet passed: nextScheduleTime is recalculated and the call waits
  • If the deadline is exceeded before working hours resume: Call is marked as Canceled
Queue Behavior: Calls scheduled outside business hours are queued and processed when:
  • Business hours resume
  • Agent becomes enabled
  • nextScheduleTime is reached and current time is within working hours
Queue Priority:
  • Calls are processed in DWRR (Dynamic Weighted Round Robin) order
  • Earlier deadline = higher priority
  • Respects call priority settings if configured
Call Deadlines: Always set reasonable callDeadline values when scheduling calls. Calls that exceed their deadline while queued will be marked as Canceled and removed from queue.

Common Scheduling Patterns

Pattern 1: Standard Business Hours (9-5, Mon-Fri)

schedule: {
  timezone: "America/New_York",
  mon: [{ start: { hour: 9, minute: 0 }, end: { hour: 17, minute: 0 } }],
  tue: [{ start: { hour: 9, minute: 0 }, end: { hour: 17, minute: 0 } }],
  wed: [{ start: { hour: 9, minute: 0 }, end: { hour: 17, minute: 0 } }],
  thu: [{ start: { hour: 9, minute: 0 }, end: { hour: 17, minute: 0 } }],
  fri: [{ start: { hour: 9, minute: 0 }, end: { hour: 17, minute: 0 } }],
  sat: [],
  sun: []
}

Pattern 2: Retail Hours (Extended Weekends)

schedule: {
  timezone: "America/Chicago",
  mon: [{ start: { hour: 10, minute: 0 }, end: { hour: 20, minute: 0 } }],
  tue: [{ start: { hour: 10, minute: 0 }, end: { hour: 20, minute: 0 } }],
  wed: [{ start: { hour: 10, minute: 0 }, end: { hour: 20, minute: 0 } }],
  thu: [{ start: { hour: 10, minute: 0 }, end: { hour: 20, minute: 0 } }],
  fri: [{ start: { hour: 10, minute: 0 }, end: { hour: 21, minute: 0 } }],
  sat: [{ start: { hour: 10, minute: 0 }, end: { hour: 21, minute: 0 } }],
  sun: [{ start: { hour: 12, minute: 0 }, end: { hour: 18, minute: 0 } }]
}

Pattern 3: Global Support (Follow-the-Sun)

Create multiple agents in different timezones:
// Asia-Pacific Agent (Sydney timezone)
const apacAgent = await createAgent({
  name: "APAC Support",
  schedule: {
    timezone: "Australia/Sydney",
    mon: [{ start: { hour: 8, minute: 0 }, end: { hour: 17, minute: 0 } }],
    tue: [{ start: { hour: 8, minute: 0 }, end: { hour: 17, minute: 0 } }],
    wed: [{ start: { hour: 8, minute: 0 }, end: { hour: 17, minute: 0 } }],
    thu: [{ start: { hour: 8, minute: 0 }, end: { hour: 17, minute: 0 } }],
    fri: [{ start: { hour: 8, minute: 0 }, end: { hour: 17, minute: 0 } }],
    sat: [],
    sun: []
  }
});

// EMEA Agent (London timezone)
const emeaAgent = await createAgent({
  name: "EMEA Support",
  schedule: {
    timezone: "Europe/London",
    mon: [{ start: { hour: 8, minute: 0 }, end: { hour: 17, minute: 0 } }],
    tue: [{ start: { hour: 8, minute: 0 }, end: { hour: 17, minute: 0 } }],
    wed: [{ start: { hour: 8, minute: 0 }, end: { hour: 17, minute: 0 } }],
    thu: [{ start: { hour: 8, minute: 0 }, end: { hour: 17, minute: 0 } }],
    fri: [{ start: { hour: 8, minute: 0 }, end: { hour: 17, minute: 0 } }],
    sat: [],
    sun: []
  }
});

// Americas Agent (New York timezone)
const americasAgent = await createAgent({
  name: "Americas Support",
  schedule: {
    timezone: "America/New_York",
    mon: [{ start: { hour: 8, minute: 0 }, end: { hour: 17, minute: 0 } }],
    tue: [{ start: { hour: 8, minute: 0 }, end: { hour: 17, minute: 0 } }],
    wed: [{ start: { hour: 8, minute: 0 }, end: { hour: 17, minute: 0 } }],
    thu: [{ start: { hour: 8, minute: 0 }, end: { hour: 17, minute: 0 } }],
    fri: [{ start: { hour: 8, minute: 0 }, end: { hour: 17, minute: 0 } }],
    sat: [],
    sun: []
  }
});
Then route calls to the appropriate agent based on caller location or time.

Pattern 4: Night Shift Coverage (Split Across Days)

Since the validator requires start < end within the same day, overnight coverage must be split into two separate time slots:
schedule: {
  timezone: "UTC",
  // Monday night shift (10 PM Monday to midnight)
  mon: [
    { start: { hour: 22, minute: 0 }, end: { hour: 23, minute: 59 } }
  ],
  // Tuesday continues from midnight to 6 AM, plus evening shift
  tue: [
    { start: { hour: 0, minute: 0 }, end: { hour: 6, minute: 0 } },
    { start: { hour: 22, minute: 0 }, end: { hour: 23, minute: 59 } }
  ],
  // Wednesday continues from midnight to 6 AM, plus evening shift
  wed: [
    { start: { hour: 0, minute: 0 }, end: { hour: 6, minute: 0 } },
    { start: { hour: 22, minute: 0 }, end: { hour: 23, minute: 59 } }
  ],
  // Thursday continues from midnight to 6 AM, plus evening shift
  thu: [
    { start: { hour: 0, minute: 0 }, end: { hour: 6, minute: 0 } },
    { start: { hour: 22, minute: 0 }, end: { hour: 23, minute: 59 } }
  ],
  // Friday continues from midnight to 6 AM, plus evening shift
  fri: [
    { start: { hour: 0, minute: 0 }, end: { hour: 6, minute: 0 } },
    { start: { hour: 22, minute: 0 }, end: { hour: 23, minute: 59 } }
  ],
  // Saturday wraps up the week (midnight to 6 AM only)
  sat: [
    { start: { hour: 0, minute: 0 }, end: { hour: 6, minute: 0 } }
  ],
  sun: []
}
Overnight Coverage: Time slots cannot cross midnight. To cover overnight hours (e.g., 22:00-06:00), split into two slots: one ending at 23:59 on the first day, and another starting at 00:00 on the next day.

Best Practices

Scheduling Strategy

Do:
  • ✅ Set timezone to your business location
  • ✅ Include buffer time before/after shifts for system processing
  • ✅ Use multiple agents for 24/7 coverage instead of one agent
  • ✅ Test schedule changes with a disabled agent first
  • ✅ Document your schedule configuration for team reference
  • ✅ Track holiday downtime in your external automation system
Don’t:
  • ❌ Use UTC unless your business actually operates in UTC
  • ❌ Configure overlapping time slots in the same day
  • ❌ Forget to account for daylight saving time changes (platform handles automatically)
  • ❌ Set unrealistic 24/7 availability on a single agent without redundancy
  • ❌ Change schedules frequently without testing impact on queued calls

Performance Considerations

For High Call Volumes:
  • Configure multiple agents with overlapping schedules
  • Use load balancing across agents
  • Monitor queue depth during business hours
  • Add capacity during peak hours (e.g., lunch time, early morning)
For Global Operations:
  • Create region-specific agents with local timezones
  • Use geographic call routing
  • Maintain consistent hours in local time (e.g., always 9-5 in each region)

Maintenance Windows

When updating schedules on live agents:
  1. Test first: Create test agent with new schedule
  2. Monitor impact: Check queued calls before applying
  3. Communicate: Notify team of schedule changes
  4. Gradual rollout: Update one agent at a time if using multiple
  5. Verify: Check agent availability after changes

Troubleshooting

Agent Not Taking Calls During Business Hours

Possible causes:
  • Agent is disabled (isEnabled: false)
  • Timezone is incorrect (check against your location)
  • Time slots are malformed (start >= end)
  • Current day has empty array []
  • All days are empty, triggering 24/7 fallback (but agent is disabled)
Solution:
// Check agent configuration
const agent = await fetch(`https://blackbox.dasha.ai/api/v1/agents/${agentId}`, {
  headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
}).then(r => r.json());

console.log('Is Enabled:', agent.isEnabled);
console.log('Timezone:', agent.schedule?.timezone);
console.log('Current day schedule:', agent.schedule?.[getCurrentDayKey()]);

Calls Being Rejected Unexpectedly

Possible causes:
  • Schedule recently changed
  • Timezone mismatch (agent in different timezone than expected)
  • Agent is disabled
Solution:
  1. Verify timezone matches your location
  2. Check if agent is enabled
  3. Test with a disabled agent before applying changes

Timezone Issues

Symptoms:
  • Agent available at wrong times
  • Scheduled calls running at unexpected hours
Solution:
  • Verify IANA timezone identifier is correct
  • Check for DST transitions on problematic dates
  • Use ISO 8601 format with timezone offset in API calls

Next Steps

Now that you understand scheduling:
  1. Configure your agent schedule in the Agent Creation flow
  2. Schedule outbound calls using Outbound Calls
  3. Monitor call queue with Call Management
  4. Set up webhooks for outside-hours call handling in Webhooks Overview

API Cross-Refs