Heppu AI

Schedule Call

Schedule a single outbound call with comprehensive metadata and Make.com compatibility

Schedule Call

Schedule a single outbound call to a contact. This endpoint supports rich metadata, timezone-aware scheduling, and is fully compatible with Make.com automation.

Endpoint

POST /api/v1/calls/schedule

Authentication

Supports multiple authentication methods:

# API Key
x-api-key: YOUR_API_KEY

# Bearer Token
Authorization: Bearer YOUR_API_KEY

# Internal API Key (for service-to-service)
x-api-key: INTERNAL_API_KEY

Request Body

Required Fields

FieldTypeDescription
agentIdstring (UUID)ID of the voice agent to use
contactPhonestringContact phone number in E.164 format (e.g., +14155552671)

Optional Fields

FieldTypeDefaultDescription
contactNamestringnullContact's full name
contactEmailstringnullContact's email address
callerIdstringAgent's first phoneSpecific phone number to use as caller ID
scheduledAtstring (ISO 8601)ImmediateWhen to make the call
priorityinteger (0-10)0Call priority (0=highest, 10=lowest)
maxRetriesintegernullMaximum retry attempts (auto-calculated from retry config if not set)
retrySchedulearraynullFixed retry schedule with absolute timestamps
retryIntervalsarraynullRelative retry intervals (e.g., "2 hours", "1 day")
callMetadataobjectRich contact and call context data
metadataobjectAdditional custom metadata

Call Metadata Object

The callMetadata object supports comprehensive contact information and call context:

{
  // Contact Information
  firstName?: string;
  lastName?: string;
  company?: string;
  jobTitle?: string;
  timezone?: string;           // IANA timezone (e.g., "America/New_York")
  preferredLanguage?: string;  // ISO 639-1 code (e.g., "en", "es")

  // Contact Preferences
  preferredCallTime?: string;  // e.g., "09:00-17:00"
  doNotCallBefore?: string;    // ISO 8601 time
  doNotCallAfter?: string;     // ISO 8601 time

  // Context Data
  accountId?: string;
  accountType?: string;        // e.g., "premium", "standard"
  customerSince?: string;      // ISO 8601 date
  lastInteraction?: string;    // ISO 8601 datetime
  purchaseHistory?: array;

  // Call Purpose
  callPurpose?: string;        // e.g., "follow-up", "support", "sales"
  campaignId?: string;
  scriptId?: string;
  expectedDuration?: number;   // in seconds

  // Custom Fields
  customFields?: object;       // Any additional key-value pairs
  tags?: string[];            // Array of tags
  notes?: string;             // Special notes for the agent
}

Retry Configuration

You can configure automatic retries using either relative intervals or fixed schedules:

Use retryIntervals for flexible, relative timing between retry attempts:

{
  retryIntervals: [
    { value: 2, unit: "hours" },   // 1st retry: 2 hours after initial call
    { value: 1, unit: "days" },    // 2nd retry: 1 day after 1st retry
    { value: 3, unit: "days" }     // 3rd retry: 3 days after 2nd retry
  ]
}

Supported units: "minutes", "hours", "days"

Fixed Retry Schedule

Use retrySchedule for absolute timestamps when you need specific retry times:

{
  retrySchedule: [
    "2025-12-02T14:00:00Z",  // 1st retry at specific time
    "2025-12-03T10:00:00Z",  // 2nd retry at specific time
    "2025-12-04T16:00:00Z"   // 3rd retry at specific time
  ]
}

Retry Behavior

  • maxRetries is automatically calculated from the length of retryIntervals or retrySchedule if not explicitly set
  • If no retry configuration is provided, the call will not be retried on failure
  • Retries are triggered when a call fails due to no-answer, busy, or other retriable errors
  • You can use either retryIntervals OR retrySchedule, not both

Response

Response Schema

{
  "data": {
    "id": "string",
    "status": "string",
    "scheduledAt": "string|null",
    "agent": {
      "id": "string",
      "name": "string"
    },
    "contact": {
      "phone": "string",
      "name": "string|null",
      "email": "string|null"
    }
  },
  "message": "Call scheduled successfully"
}

Examples

Basic Call Schedule

curl -X POST https://v2.heppu.ai/api/v1/calls/schedule \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "550e8400-e29b-41d4-a716-446655440000",
    "contactPhone": "+14155552671",
    "contactName": "John Doe",
    "scheduledAt": "2025-12-02T14:00:00Z"
  }'
const response = await fetch('https://v2.heppu.ai/api/v1/calls/schedule', {
  method: 'POST',
  headers: {
    'x-api-key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    agentId: '550e8400-e29b-41d4-a716-446655440000',
    contactPhone: '+14155552671',
    contactName: 'John Doe',
    scheduledAt: '2025-12-02T14:00:00Z'
  })
});

const data = await response.json();
console.log('Call scheduled:', data.data);
import requests
from datetime import datetime, timedelta

# Schedule for tomorrow at 2 PM UTC
scheduled_time = (datetime.utcnow() + timedelta(days=1)).replace(
    hour=14, minute=0, second=0, microsecond=0
)

response = requests.post(
    'https://v2.heppu.ai/api/v1/calls/schedule',
    headers={'x-api-key': 'YOUR_API_KEY'},
    json={
        'agentId': '550e8400-e29b-41d4-a716-446655440000',
        'contactPhone': '+14155552671',
        'contactName': 'John Doe',
        'scheduledAt': scheduled_time.isoformat() + 'Z'
    }
)

data = response.json()
print(f"Call scheduled: {data['data']}")

Immediate Call

curl -X POST https://v2.heppu.ai/api/v1/calls/schedule \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "550e8400-e29b-41d4-a716-446655440000",
    "contactPhone": "+14155552671",
    "priority": 0
  }'
// Immediate call with high priority
const response = await fetch('https://v2.heppu.ai/api/v1/calls/schedule', {
  method: 'POST',
  headers: {
    'x-api-key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    agentId: '550e8400-e29b-41d4-a716-446655440000',
    contactPhone: '+14155552671',
    priority: 0  // High priority
  })
});

const data = await response.json();
console.log('Immediate call initiated:', data.data);
# Immediate call (no scheduledAt specified)
response = requests.post(
    'https://v2.heppu.ai/api/v1/calls/schedule',
    headers={'x-api-key': 'YOUR_API_KEY'},
    json={
        'agentId': '550e8400-e29b-41d4-a716-446655440000',
        'contactPhone': '+14155552671',
        'priority': 0  # High priority
    }
)

Call with Retry Intervals

Schedule a call with automatic retries using relative time intervals:

curl -X POST https://v2.heppu.ai/api/v1/calls/schedule \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "550e8400-e29b-41d4-a716-446655440000",
    "contactPhone": "+14155552671",
    "contactName": "John Doe",
    "scheduledAt": "2025-12-02T10:00:00Z",
    "retryIntervals": [
      { "value": 2, "unit": "hours" },
      { "value": 1, "unit": "days" }
    ]
  }'
// Schedule call with automatic retries
const response = await fetch('https://v2.heppu.ai/api/v1/calls/schedule', {
  method: 'POST',
  headers: {
    'x-api-key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    agentId: '550e8400-e29b-41d4-a716-446655440000',
    contactPhone: '+14155552671',
    contactName: 'John Doe',
    scheduledAt: '2025-12-02T10:00:00Z',
    retryIntervals: [
      { value: 2, unit: 'hours' },   // Retry after 2 hours
      { value: 1, unit: 'days' }     // Then retry after 1 day
    ]
  })
});

const data = await response.json();
console.log('Call scheduled with retries:', data.data);
# Schedule call with automatic retries
response = requests.post(
    'https://v2.heppu.ai/api/v1/calls/schedule',
    headers={'x-api-key': 'YOUR_API_KEY'},
    json={
        'agentId': '550e8400-e29b-41d4-a716-446655440000',
        'contactPhone': '+14155552671',
        'contactName': 'John Doe',
        'scheduledAt': '2025-12-02T10:00:00Z',
        'retryIntervals': [
            {'value': 2, 'unit': 'hours'},   # Retry after 2 hours
            {'value': 1, 'unit': 'days'}     # Then retry after 1 day
        ]
    }
)

Call with Fixed Retry Schedule

Schedule a call with retries at specific times (useful for single-timezone campaigns):

curl -X POST https://v2.heppu.ai/api/v1/calls/schedule \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "550e8400-e29b-41d4-a716-446655440000",
    "contactPhone": "+14155552671",
    "contactName": "John Doe",
    "scheduledAt": "2025-12-02T10:00:00Z",
    "retrySchedule": [
      "2025-12-02T14:00:00Z",
      "2025-12-03T10:00:00Z"
    ]
  }'
// Schedule call with fixed retry times
const response = await fetch('https://v2.heppu.ai/api/v1/calls/schedule', {
  method: 'POST',
  headers: {
    'x-api-key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    agentId: '550e8400-e29b-41d4-a716-446655440000',
    contactPhone: '+14155552671',
    contactName: 'John Doe',
    scheduledAt: '2025-12-02T10:00:00Z',
    retrySchedule: [
      '2025-12-02T14:00:00Z',  // 1st retry at 2 PM
      '2025-12-03T10:00:00Z'   // 2nd retry next day at 10 AM
    ]
  })
});

const data = await response.json();
console.log('Call scheduled with fixed retries:', data.data);
# Schedule call with fixed retry times
response = requests.post(
    'https://v2.heppu.ai/api/v1/calls/schedule',
    headers={'x-api-key': 'YOUR_API_KEY'},
    json={
        'agentId': '550e8400-e29b-41d4-a716-446655440000',
        'contactPhone': '+14155552671',
        'contactName': 'John Doe',
        'scheduledAt': '2025-12-02T10:00:00Z',
        'retrySchedule': [
            '2025-12-02T14:00:00Z',  # 1st retry at 2 PM
            '2025-12-03T10:00:00Z'   # 2nd retry next day at 10 AM
        ]
    }
)

Call with Rich Metadata

curl -X POST https://v2.heppu.ai/api/v1/calls/schedule \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "550e8400-e29b-41d4-a716-446655440000",
    "contactPhone": "+14155552671",
    "contactName": "John Doe",
    "contactEmail": "john.doe@example.com",
    "scheduledAt": "2025-12-02T14:00:00Z",
    "priority": 5,
    "callMetadata": {
      "firstName": "John",
      "lastName": "Doe",
      "company": "Acme Corp",
      "jobTitle": "CTO",
      "timezone": "America/New_York",
      "preferredLanguage": "en",
      "accountId": "ACC-12345",
      "accountType": "premium",
      "customerSince": "2024-01-15",
      "callPurpose": "product_demo",
      "campaignId": "holiday-2025",
      "tags": ["vip", "tech-savvy"],
      "notes": "Interested in enterprise features"
    }
  }'
const response = await fetch('https://v2.heppu.ai/api/v1/calls/schedule', {
  method: 'POST',
  headers: {
    'x-api-key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    agentId: '550e8400-e29b-41d4-a716-446655440000',
    contactPhone: '+14155552671',
    contactName: 'John Doe',
    contactEmail: 'john.doe@example.com',
    scheduledAt: '2025-12-02T14:00:00Z',
    priority: 5,
    callMetadata: {
      firstName: 'John',
      lastName: 'Doe',
      company: 'Acme Corp',
      jobTitle: 'CTO',
      timezone: 'America/New_York',
      preferredLanguage: 'en',
      accountId: 'ACC-12345',
      accountType: 'premium',
      customerSince: '2024-01-15',
      callPurpose: 'product_demo',
      campaignId: 'holiday-2025',
      tags: ['vip', 'tech-savvy'],
      notes: 'Interested in enterprise features',
      customFields: {
        productInterest: 'Enterprise Suite',
        budget: 'high',
        decisionMaker: true
      }
    }
  })
});

const data = await response.json();
console.log('Call scheduled with metadata:', data.data);
from datetime import datetime, timedelta

response = requests.post(
    'https://v2.heppu.ai/api/v1/calls/schedule',
    headers={'x-api-key': 'YOUR_API_KEY'},
    json={
        'agentId': '550e8400-e29b-41d4-a716-446655440000',
        'contactPhone': '+14155552671',
        'contactName': 'John Doe',
        'contactEmail': 'john.doe@example.com',
        'scheduledAt': (datetime.utcnow() + timedelta(days=1)).isoformat() + 'Z',
        'priority': 5,
        'callMetadata': {
            'firstName': 'John',
            'lastName': 'Doe',
            'company': 'Acme Corp',
            'jobTitle': 'CTO',
            'timezone': 'America/New_York',
            'preferredLanguage': 'en',
            'accountId': 'ACC-12345',
            'accountType': 'premium',
            'customerSince': '2024-01-15',
            'callPurpose': 'product_demo',
            'campaignId': 'holiday-2025',
            'tags': ['vip', 'tech-savvy'],
            'notes': 'Interested in enterprise features',
            'customFields': {
                'productInterest': 'Enterprise Suite',
                'budget': 'high',
                'decisionMaker': True
            }
        }
    }
)

print(f"Call scheduled: {response.json()}")

Make.com Integration

The endpoint is fully compatible with Make.com and handles hidden characters automatically:

// Make.com HTTP Module Configuration
{
  "url": "https://v2.heppu.ai/api/v1/calls/schedule",
  "method": "POST",
  "headers": {
    "x-api-key": "{{YOUR_API_KEY}}",
    "Content-Type": "application/json"
  },
  "body": {
    "agentId": "{{agentId}}",
    "contactPhone": "{{phoneNumber}}",
    "contactName": "{{firstName}} {{lastName}}",
    "contactEmail": "{{email}}",
    "scheduledAt": "{{scheduledTime}}",
    "callMetadata": {
      "firstName": "{{firstName}}",
      "lastName": "{{lastName}}",
      "company": "{{company}}",
      "campaignId": "{{campaignId}}"
    }
  }
}

Response Examples

Success Response (Scheduled)

{
  "data": {
    "id": "call_abc123",
    "status": "initiated",
    "scheduledAt": "2025-12-02T14:00:00Z",
    "agent": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Customer Support Agent"
    },
    "contact": {
      "phone": "+14155552671",
      "name": "John Doe",
      "email": "john.doe@example.com"
    }
  },
  "message": "Call scheduled successfully"
}

Success Response (Immediate)

{
  "data": {
    "id": "call_def456",
    "status": "initiated",
    "scheduledAt": null,
    "agent": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Sales Agent"
    },
    "contact": {
      "phone": "+14155552672",
      "name": null,
      "email": null
    }
  },
  "message": "Call initiated successfully"
}

Error Responses

Missing Required Fields

{
  "error": {
    "message": "Missing required fields: agentId and contactPhone are required",
    "code": 400
  }
}

Invalid Phone Number Format

{
  "error": {
    "message": "Invalid phone number format. Must be E.164 format (e.g., +1234567890)",
    "code": 400
  }
}

Agent Not Found

{
  "error": {
    "message": "Agent not found or access denied",
    "code": 404
  }
}

Agent Not Voice Type

{
  "error": {
    "message": "Agent must be a voice agent to schedule calls",
    "code": 400
  }
}

No Phone Number Assigned

{
  "error": {
    "message": "Agent does not have a phone number assigned",
    "code": 400
  }
}

Invalid Scheduled Time

{
  "error": {
    "message": "Invalid scheduledAt format. Use ISO 8601 format",
    "code": 400
  }
}

Validation Rules

Phone Number (E.164 Format)

Must match the pattern: ^\+[1-9]\d{1,14}$

Valid examples:

  • US: +14155552671
  • UK: +442071838750
  • Germany: +493012345678

Invalid examples:

  • Missing +: 14155552671
  • Has spaces: +1 415 555 2671
  • Has dashes: +1-415-555-2671
  • Too long: +123456789012345678

Scheduled Time

  • Must be ISO 8601 format: YYYY-MM-DDTHH:mm:ssZ
  • If time is in the past, will be automatically adjusted to 5 seconds from now
  • Optional field - omit for immediate calls

Priority

  • Integer from 0 to 10
  • 0-3: High priority (processed first)
  • 4-6: Normal priority (default: 5)
  • 7-10: Low priority (processed last)

Use Cases

CRM Integration

Schedule follow-up calls from your CRM:

async function scheduleFollowUpCall(crmContact, agentId) {
  // Calculate best time to call (next business day at 10 AM)
  const scheduledTime = getNextBusinessDay();
  scheduledTime.setHours(10, 0, 0, 0);

  const response = await fetch('https://v2.heppu.ai/api/v1/calls/schedule', {
    method: 'POST',
    headers: {
      'x-api-key': 'YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      agentId: agentId,
      contactPhone: crmContact.phone,
      contactName: crmContact.fullName,
      contactEmail: crmContact.email,
      scheduledAt: scheduledTime.toISOString(),
      priority: crmContact.vip ? 0 : 5,
      callMetadata: {
        firstName: crmContact.firstName,
        lastName: crmContact.lastName,
        company: crmContact.company,
        accountId: crmContact.id,
        accountType: crmContact.tier,
        customerSince: crmContact.createdAt,
        lastInteraction: crmContact.lastContactedAt,
        callPurpose: 'follow_up',
        notes: crmContact.notes,
        customFields: {
          dealValue: crmContact.dealValue,
          dealStage: crmContact.dealStage,
          assignedTo: crmContact.salesRep
        }
      }
    })
  });

  return response.json();
}

function getNextBusinessDay() {
  const date = new Date();
  date.setDate(date.getDate() + 1);

  // Skip weekends
  while (date.getDay() === 0 || date.getDay() === 6) {
    date.setDate(date.getDate() + 1);
  }

  return date;
}

Appointment Reminder Calls

Schedule reminder calls for appointments:

def schedule_appointment_reminder(appointment, agent_id):
    """Schedule a reminder call 24 hours before appointment"""

    from datetime import datetime, timedelta

    # Calculate reminder time (24 hours before appointment)
    appointment_time = datetime.fromisoformat(appointment['scheduledAt'])
    reminder_time = appointment_time - timedelta(hours=24)

    response = requests.post(
        'https://v2.heppu.ai/api/v1/calls/schedule',
        headers={'x-api-key': 'YOUR_API_KEY'},
        json={
            'agentId': agent_id,
            'contactPhone': appointment['customerPhone'],
            'contactName': appointment['customerName'],
            'contactEmail': appointment['customerEmail'],
            'scheduledAt': reminder_time.isoformat() + 'Z',
            'priority': 3,  # High priority for reminders
            'callMetadata': {
                'firstName': appointment['customerFirstName'],
                'lastName': appointment['customerLastName'],
                'callPurpose': 'appointment_reminder',
                'appointmentId': appointment['id'],
                'appointmentTime': appointment['scheduledAt'],
                'appointmentType': appointment['type'],
                'provider': appointment['providerName'],
                'location': appointment['location'],
                'notes': f"Reminder for {appointment['type']} appointment"
            }
        }
    )

    return response.json()

Customer Outreach Campaign

Schedule personalized outreach calls:

async function scheduleCampaignCalls(customers, agentId, campaignId) {
  const results = [];

  for (const customer of customers) {
    try {
      // Calculate best time based on customer timezone
      const scheduledTime = calculateBestCallTime(
        customer.timezone,
        customer.preferredCallTime
      );

      const response = await fetch('https://v2.heppu.ai/api/v1/calls/schedule', {
        method: 'POST',
        headers: {
          'x-api-key': 'YOUR_API_KEY',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          agentId: agentId,
          contactPhone: customer.phone,
          contactName: customer.name,
          contactEmail: customer.email,
          scheduledAt: scheduledTime.toISOString(),
          priority: customer.segment === 'vip' ? 2 : 5,
          callMetadata: {
            firstName: customer.firstName,
            lastName: customer.lastName,
            company: customer.company,
            timezone: customer.timezone,
            preferredLanguage: customer.language,
            accountType: customer.segment,
            customerSince: customer.signupDate,
            purchaseHistory: customer.recentPurchases,
            callPurpose: 'product_promotion',
            campaignId: campaignId,
            tags: customer.tags,
            customFields: {
              segment: customer.segment,
              lifetimeValue: customer.ltv,
              engagementScore: customer.engagementScore
            }
          }
        })
      });

      const data = await response.json();
      results.push({
        customer: customer.id,
        success: true,
        callId: data.data.id
      });

    } catch (error) {
      results.push({
        customer: customer.id,
        success: false,
        error: error.message
      });
    }
  }

  return results;
}

Best Practices

  1. Use E.164 format - Always format phone numbers correctly
  2. Provide rich metadata - More context helps agents perform better
  3. Set appropriate priority - Use priority to manage call queue
  4. Include timezone - Store contact timezone for better scheduling
  5. Handle errors - Always check response status and handle errors
  6. Validate before scheduling - Verify agent exists and has phone number
  7. Use ISO 8601 dates - Ensure scheduled times are in correct format

On this page