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
| Property | Value |
|---|---|
| Function Name | calls-batch-create |
| HTTP Method | POST |
| Authentication | Supabase JWT (Bearer token) |
| Required Role | agency_owner or agency_admin |
Request
Headers
Authorization: Bearer <supabase_jwt_token>
Content-Type: application/json
Body
| Field | Type | Required | Description |
|---|---|---|---|
agent_mapping_id | string (UUID) | Yes | ID from the agent_mappings table. Must belong to the caller's agency. |
from_number | string | Yes | Caller ID in E.164 format (e.g., +15551234567). Must be an active agency phone number. |
campaign_id | string (UUID) | Yes | Campaign UUID. Must belong to the caller's agency. |
contacts | array | Yes | Array of contacts to call. Maximum 10,000 per batch. See contact fields below. |
calls_per_minute | number | No | Rate limit for call throughput. Range: 1–60. Default: 30. |
max_concurrent | number | No | Maximum parallel calls. Range: 1–100. Default: 10. |
scheduled_for | string (ISO 8601) | No | Schedule batch processing for a future time. null or omitted = start when the cron processor picks it up. |
mode | "immediate" | "scheduled" | No | Batch mode. Auto-determined from scheduled_for if omitted. |
Contact Fields
| Field | Type | Required | Description |
|---|---|---|---|
phone_number | string | Yes | Destination number in E.164 format |
first_name | string | No | Contact first name |
last_name | string | No | Contact last name |
email | string | No | Contact email address |
company | string | No | Contact company name |
title | string | No | Contact job title |
timezone | string | No | Contact timezone (e.g., "EST", "America/New_York") |
custom_data | object | No | Arbitrary key-value data passed through to Ultravox metadata |
max_attempts | number | No | Maximum 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
| Status | Condition |
|---|---|
| 400 | agent_mapping_id, from_number, or campaign_id is missing |
| 400 | contacts array is empty or missing |
| 400 | More than 10,000 contacts provided |
| 400 | from_number is not in E.164 format or not active in the agency |
| 400 | One or more contact phone numbers are not in E.164 format (returns first 10 invalid numbers) |
| 401 | Missing or invalid authorization header |
| 403 | User is not associated with an agency |
| 403 | User role is not agency_owner or agency_admin |
| 404 | Agent mapping not found or does not belong to the agency |
| 404 | Campaign not found or does not belong to the agency |
| 405 | HTTP method is not POST |
| 500 | Failed to create batch record or insert contacts |
Behavior
- Authenticates the user via Supabase JWT and verifies
agency_owneroragency_adminrole. - Validates all required fields and phone number formats (E.164:
+followed by 7–15 digits). - Validates that
agent_mapping_id,from_number, andcampaign_idall belong to the caller's agency. - Deduplicates contacts by
phone_number— only the first occurrence of each number is kept. - Clamps
calls_per_minuteto 1–60 andmax_concurrentto 1–100. - Determines batch status:
"scheduled"ifscheduled_foris a future time, otherwise"pending". - Inserts the batch record into
call_batches. - Inserts contacts into
campaign_contactsin 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
| Table | Operation | Description |
|---|---|---|
users | Read | Fetches user profile to determine agency_id and role |
agent_mappings | Read | Validates agent_mapping_id belongs to the agency |
agency_phone_numbers | Read | Validates from_number is active in the agency |
campaigns | Read | Validates campaign_id belongs to the agency |
call_batches | Insert | Creates the batch record |
campaign_contacts | Insert | Stores contacts in 500-row chunks |
External APIs
None. Contacts are stored for later processing by calls-batch-process.
Related Functions
- List Call Batches -- View all batches with summary stats
- Get Call Batch -- View batch details with paginated contacts
- Process Call Batches -- Cron function that initiates calls from queued batches
- Pause Call Batch -- Pause a processing batch
- Cancel Call Batch -- Cancel a batch and skip remaining contacts