Skip to main content

Create Call Batch

Creates a new batch of outbound calls with a list of contacts. Contacts are stored in the campaign_contacts table and processed by the calls-batch-process cron function. Contacts are deduplicated by phone number before insertion.

Endpoint

PropertyValue
Function Namecalls-batch-create
HTTP MethodPOST
AuthenticationSupabase JWT (Bearer token)
Required Roleagency_owner or agency_admin

Request

Headers

Authorization: Bearer <supabase_jwt_token>
Content-Type: application/json

Body

FieldTypeRequiredDescription
agent_mapping_idstring (UUID)YesID from the agent_mappings table. Must belong to the caller's agency.
from_numberstringYesCaller ID in E.164 format (e.g., +15551234567). Must be an active agency phone number.
campaign_idstring (UUID)YesCampaign UUID. Must belong to the caller's agency.
contactsarrayYesArray of contacts to call. Maximum 10,000 per batch. See contact fields below.
calls_per_minutenumberNoRate limit for call throughput. Range: 1–60. Default: 30.
max_concurrentnumberNoMaximum parallel calls. Range: 1–100. Default: 10.
scheduled_forstring (ISO 8601)NoSchedule batch processing for a future time. null or omitted = start when the cron processor picks it up.
mode"immediate" | "scheduled"NoBatch mode. Auto-determined from scheduled_for if omitted.

Contact Fields

FieldTypeRequiredDescription
phone_numberstringYesDestination number in E.164 format
first_namestringNoContact first name
last_namestringNoContact last name
emailstringNoContact email address
companystringNoContact company name
titlestringNoContact job title
timezonestringNoContact timezone (e.g., "EST", "America/New_York")
custom_dataobjectNoArbitrary key-value data passed through to Ultravox metadata
max_attemptsnumberNoMaximum call attempts for this contact. Default: 3.

Response

Success (201)

{
"batch_id": "uuid",
"status": "pending",
"total_contacts": 4850,
"agent_mapping_id": "uuid",
"agent_name": "Sales Agent",
"from_number": "+15551234567",
"campaign_id": "uuid",
"calls_per_minute": 30,
"max_concurrent": 10,
"scheduled_for": null,
"created_at": "2025-01-15T10:30:00Z"
}

The status will be "pending" for immediate batches or "scheduled" if scheduled_for is a future timestamp.

Error Responses

StatusCondition
400agent_mapping_id, from_number, or campaign_id is missing
400contacts array is empty or missing
400More than 10,000 contacts provided
400from_number is not in E.164 format or not active in the agency
400One or more contact phone numbers are not in E.164 format (returns first 10 invalid numbers)
401Missing or invalid authorization header
403User is not associated with an agency
403User role is not agency_owner or agency_admin
404Agent mapping not found or does not belong to the agency
404Campaign not found or does not belong to the agency
405HTTP method is not POST
500Failed to create batch record or insert contacts

Behavior

  • Authenticates the user via Supabase JWT and verifies agency_owner or agency_admin role.
  • Validates all required fields and phone number formats (E.164: + followed by 7–15 digits).
  • Validates that agent_mapping_id, from_number, and campaign_id all belong to the caller's agency.
  • Deduplicates contacts by phone_number — only the first occurrence of each number is kept.
  • Clamps calls_per_minute to 1–60 and max_concurrent to 1–100.
  • Determines batch status: "scheduled" if scheduled_for is a future time, otherwise "pending".
  • Inserts the batch record into call_batches.
  • Inserts contacts into campaign_contacts in chunks of 500 rows to handle large batches.
  • If the first chunk insert fails, marks the batch as "failed" and returns an error. Subsequent chunk failures stop insertion but the batch continues with partially inserted contacts.

Database Tables

TableOperationDescription
usersReadFetches user profile to determine agency_id and role
agent_mappingsReadValidates agent_mapping_id belongs to the agency
agency_phone_numbersReadValidates from_number is active in the agency
campaignsReadValidates campaign_id belongs to the agency
call_batchesInsertCreates the batch record
campaign_contactsInsertStores contacts in 500-row chunks

External APIs

None. Contacts are stored for later processing by calls-batch-process.