Timezone-Aware Scheduling
Schedule calls across multiple timezones while respecting local business hours and customer preferences
Overview
Heppu AI's timezone-aware scheduling ensures your calls reach customers at the right time in their local timezone. Schedule calls using local time references, configure business hours, exclude weekends, and set minimum intervals between calls to maximize contact rates while respecting customer preferences.
Local Time Scheduling
Using targetLocalTime
Schedule calls to execute at a specific time in the recipient's local timezone:
{
"agentId": "agent_abc123",
"phoneNumber": "+12125551234",
"targetLocalTime": "09:00",
"timezone": "America/New_York"
}This call will execute at 9:00 AM Eastern Time, regardless of your server's timezone.
Multiple Timezone Example
Schedule the same time across different timezones:
JavaScript
const contacts = [
{ phone: '+12125551234', timezone: 'America/New_York' }, // 9 AM EST
{ phone: '+13125551234', timezone: 'America/Chicago' }, // 9 AM CST
{ phone: '+14155551234', timezone: 'America/Los_Angeles' }, // 9 AM PST
{ phone: '+14425551234', timezone: 'Europe/London' }, // 9 AM GMT
{ phone: '+4989551234', timezone: 'Europe/Berlin' } // 9 AM CET
];
const calls = contacts.map(contact => ({
agentId: 'agent_abc123',
phoneNumber: contact.phone,
targetLocalTime: '09:00',
timezone: contact.timezone,
metadata: {
scheduledFor: '9:00 AM local time'
}
}));
// Schedule all calls
const response = await fetch('https://v2.heppu.ai/api/v1/calls/batch', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({ agentId: 'agent_abc123', calls })
});Python
contacts = [
{'phone': '+12125551234', 'timezone': 'America/New_York'},
{'phone': '+13125551234', 'timezone': 'America/Chicago'},
{'phone': '+14155551234', 'timezone': 'America/Los_Angeles'},
{'phone': '+14425551234', 'timezone': 'Europe/London'},
{'phone': '+4989551234', 'timezone': 'Europe/Berlin'}
]
calls = [
{
'agentId': 'agent_abc123',
'phoneNumber': contact['phone'],
'targetLocalTime': '09:00',
'timezone': contact['timezone'],
'metadata': {
'scheduledFor': '9:00 AM local time'
}
}
for contact in contacts
]
response = requests.post(
'https://v2.heppu.ai/api/v1/calls/batch',
headers={
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={'agentId': 'agent_abc123', 'calls': calls}
)cURL
curl -X POST https://v2.heppu.ai/api/v1/calls/batch \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agentId": "agent_abc123",
"calls": [
{
"phoneNumber": "+12125551234",
"targetLocalTime": "09:00",
"timezone": "America/New_York"
},
{
"phoneNumber": "+13125551234",
"targetLocalTime": "09:00",
"timezone": "America/Chicago"
},
{
"phoneNumber": "+14155551234",
"targetLocalTime": "09:00",
"timezone": "America/Los_Angeles"
}
]
}'Business Hours Configuration
Basic Business Hours
Restrict calls to specific hours of the day:
{
"agentId": "agent_abc123",
"phoneNumber": "+12125551234",
"timezone": "America/New_York",
"businessHours": {
"start": "09:00",
"end": "17:00"
}
}This ensures calls only execute between 9 AM and 5 PM in the recipient's timezone.
Advanced Business Hours with Days
Configure different hours for different days:
{
"agentId": "agent_abc123",
"phoneNumber": "+12125551234",
"timezone": "America/New_York",
"businessHours": {
"monday": { "start": "09:00", "end": "17:00" },
"tuesday": { "start": "09:00", "end": "17:00" },
"wednesday": { "start": "09:00", "end": "17:00" },
"thursday": { "start": "09:00", "end": "17:00" },
"friday": { "start": "09:00", "end": "17:00" },
"saturday": { "start": "10:00", "end": "14:00" },
"sunday": null
}
}Business Hours Best Practices
| Industry | Recommended Hours | Timezone Considerations |
|---|---|---|
| B2B | 9 AM - 5 PM | Use recipient's business timezone |
| Retail | 10 AM - 8 PM | Consider store hours |
| Healthcare | 8 AM - 6 PM | Respect patient privacy times |
| Financial | 9 AM - 4 PM | Align with market hours |
Weekend Exclusion
Exclude Weekends
Automatically skip Saturday and Sunday:
{
"agentId": "agent_abc123",
"phoneNumber": "+12125551234",
"excludeWeekends": true,
"businessHours": {
"start": "09:00",
"end": "17:00"
}
}If a call is scheduled for Saturday, it will automatically move to the next Monday.
Holiday Exclusion
Combine with custom date exclusions:
async function scheduleWithHolidayExclusion(phoneNumber, agentId, timezone) {
const holidays = [
'2024-12-25', // Christmas
'2024-01-01', // New Year's Day
'2024-07-04' // Independence Day (US)
];
const scheduledDate = new Date();
// Check if scheduled date is a holiday
const dateString = scheduledDate.toISOString().split('T')[0];
if (holidays.includes(dateString)) {
// Move to next business day
scheduledDate.setDate(scheduledDate.getDate() + 1);
}
return fetch('https://v2.heppu.ai/api/v1/calls/schedule', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
agentId,
phoneNumber,
scheduleAt: scheduledDate.toISOString(),
timezone,
excludeWeekends: true
})
});
}Minimum Interval Between Calls
Setting Minimum Intervals
Prevent calling the same number too frequently:
{
"agentId": "agent_abc123",
"phoneNumber": "+12125551234",
"minIntervalHours": 24
}If this number was called within the last 24 hours, the call will be automatically rescheduled.
Interval Strategies
| Interval | Use Case | Recommended For |
|---|---|---|
| 1 hour | Urgent follow-ups | Support callbacks |
| 4 hours | Same-day retries | Appointment reminders |
| 24 hours | Daily check-ins | Lead nurturing |
| 72 hours | Gentle persistence | Cold outreach |
| 168 hours (1 week) | Respectful spacing | Follow-up campaigns |
Combined with Retry Logic
{
"agentId": "agent_abc123",
"phoneNumber": "+12125551234",
"minIntervalHours": 24,
"maxRetries": 3,
"retryOnNoAnswer": true,
"businessHours": {
"start": "09:00",
"end": "17:00"
}
}This configuration will:
- Try calling during business hours
- Retry up to 3 times if no answer
- Wait at least 24 hours between attempts
IANA Timezone Database
Common Timezones
Heppu AI uses the IANA timezone database. Here are commonly used timezones:
United States
America/New_York (EST/EDT)
America/Chicago (CST/CDT)
America/Denver (MST/MDT)
America/Los_Angeles (PST/PDT)
America/Phoenix (MST, no DST)
America/Anchorage (AKST/AKDT)
America/Honolulu (HST, no DST)Europe
Europe/London (GMT/BST)
Europe/Paris (CET/CEST)
Europe/Berlin (CET/CEST)
Europe/Rome (CET/CEST)
Europe/Madrid (CET/CEST)
Europe/Amsterdam (CET/CEST)Asia-Pacific
Asia/Tokyo (JST)
Asia/Shanghai (CST)
Asia/Singapore (SGT)
Asia/Dubai (GST)
Australia/Sydney (AEDT/AEST)
Pacific/Auckland (NZDT/NZST)Finding the Right Timezone
Use this helper function to determine timezone from phone number:
function getTimezoneFromPhone(phoneNumber) {
const countryCode = phoneNumber.substring(0, 2);
const timezoneMap = {
'+1': 'America/New_York', // Default US
'+44': 'Europe/London', // UK
'+49': 'Europe/Berlin', // Germany
'+33': 'Europe/Paris', // France
'+81': 'Asia/Tokyo', // Japan
'+86': 'Asia/Shanghai', // China
'+61': 'Australia/Sydney', // Australia
};
return timezoneMap[countryCode] || 'America/New_York';
}For more accurate timezone detection, use a phone number validation service or maintain a CRM database with timezone preferences.
Full IANA List
For the complete list of timezones, visit: IANA Timezone Database
Complete Example: Multi-Timezone Campaign
Schedule 100 calls across US timezones, respecting local business hours:
JavaScript
async function scheduleUSCampaign(contacts) {
// Group contacts by timezone
const timezoneGroups = {
'America/New_York': [],
'America/Chicago': [],
'America/Denver': [],
'America/Los_Angeles': []
};
contacts.forEach(contact => {
const timezone = contact.timezone || getTimezoneFromPhone(contact.phone);
if (timezoneGroups[timezone]) {
timezoneGroups[timezone].push(contact);
}
});
const allCalls = [];
// Schedule each timezone group
for (const [timezone, groupContacts] of Object.entries(timezoneGroups)) {
const calls = groupContacts.map(contact => ({
agentId: 'agent_abc123',
phoneNumber: contact.phone,
targetLocalTime: '10:00', // 10 AM local time
timezone: timezone,
businessHours: {
start: '09:00',
end: '18:00'
},
excludeWeekends: true,
minIntervalHours: 48,
maxRetries: 3,
retryOnNoAnswer: true,
retryOnBusy: true,
metadata: {
campaignId: 'us_rollout_2024',
timezone: timezone,
contactName: contact.name
}
}));
allCalls.push(...calls);
}
// Submit in batches of 1000
const BATCH_SIZE = 1000;
const results = [];
for (let i = 0; i < allCalls.length; i += BATCH_SIZE) {
const batch = allCalls.slice(i, i + BATCH_SIZE);
const response = await fetch('https://v2.heppu.ai/api/v1/calls/batch', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
agentId: 'agent_abc123',
calls: batch
})
});
results.push(await response.json());
// Rate limiting
await new Promise(resolve => setTimeout(resolve, 2000));
}
return results;
}
// Usage
const contacts = [
{ phone: '+12125551001', name: 'John Doe', timezone: 'America/New_York' },
{ phone: '+13125551002', name: 'Jane Smith', timezone: 'America/Chicago' },
// ... 98 more contacts
];
scheduleUSCampaign(contacts).then(results => {
console.log('Campaign scheduled:', results);
});Python
import requests
from typing import List, Dict
from collections import defaultdict
import time
def schedule_us_campaign(contacts: List[Dict]) -> List[Dict]:
"""Schedule calls across US timezones respecting business hours"""
# Group contacts by timezone
timezone_groups = defaultdict(list)
for contact in contacts:
timezone = contact.get('timezone') or get_timezone_from_phone(contact['phone'])
timezone_groups[timezone].append(contact)
all_calls = []
# Schedule each timezone group
for timezone, group_contacts in timezone_groups.items():
calls = [
{
'agentId': 'agent_abc123',
'phoneNumber': contact['phone'],
'targetLocalTime': '10:00', # 10 AM local time
'timezone': timezone,
'businessHours': {
'start': '09:00',
'end': '18:00'
},
'excludeWeekends': True,
'minIntervalHours': 48,
'maxRetries': 3,
'retryOnNoAnswer': True,
'retryOnBusy': True,
'metadata': {
'campaignId': 'us_rollout_2024',
'timezone': timezone,
'contactName': contact.get('name')
}
}
for contact in group_contacts
]
all_calls.extend(calls)
# Submit in batches of 1000
BATCH_SIZE = 1000
results = []
for i in range(0, len(all_calls), BATCH_SIZE):
batch = all_calls[i:i + BATCH_SIZE]
response = requests.post(
'https://v2.heppu.ai/api/v1/calls/batch',
headers={
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
'agentId': 'agent_abc123',
'calls': batch
}
)
results.append(response.json())
# Rate limiting
time.sleep(2)
return results
def get_timezone_from_phone(phone: str) -> str:
"""Determine timezone from phone number"""
timezone_map = {
'+1212': 'America/New_York',
'+1312': 'America/Chicago',
'+1415': 'America/Los_Angeles',
# Add more mappings
}
for prefix, timezone in timezone_map.items():
if phone.startswith(prefix):
return timezone
return 'America/New_York' # Default
# Usage
contacts = [
{'phone': '+12125551001', 'name': 'John Doe', 'timezone': 'America/New_York'},
{'phone': '+13125551002', 'name': 'Jane Smith', 'timezone': 'America/Chicago'},
# ... 98 more contacts
]
results = schedule_us_campaign(contacts)
print('Campaign scheduled:', results)Common Pitfalls and Solutions
Pitfall 1: Ignoring Daylight Saving Time
Problem: Hardcoding UTC offsets instead of using IANA timezones
Wrong:
{
"timezone": "UTC-5" // Breaks during DST
}Correct:
{
"timezone": "America/New_York" // Automatically handles DST
}Pitfall 2: Not Accounting for Business Hours
Problem: Scheduling calls at inappropriate times
Solution: Always set business hours constraints
{
"businessHours": {
"start": "09:00",
"end": "17:00"
},
"excludeWeekends": true
}Pitfall 3: Over-Calling Contacts
Problem: Multiple calls to the same number in short succession
Solution: Use minimum intervals
{
"minIntervalHours": 24
}Pitfall 4: Wrong Timezone Format
Problem: Using abbreviations instead of IANA names
Wrong:
{
"timezone": "EST" // Ambiguous
}Correct:
{
"timezone": "America/New_York"
}