Batch Call Upload
Upload 1 to 100 call recordings to Aila in one asynchronous request. Use it to send calls from a system Aila doesn't connect to directly, or to backfill history.
Before you start:
- Your API key needs the
calls:writescope. See Authentication. - Your organization needs the API upload connection enabled. If the request returns
404 Upload connection not found, email support@aila.fyi.
Endpoint Specification
POST https://app.aila.fyi/api/v1/calls/upload/batch
Authorization: Bearer <YOUR_API_KEY>
Content-Type: application/jsonRequest Body Schema
| Field | Type | Required | Description |
|---|---|---|---|
calls | Array | Yes | Array of 1 to 100 call objects. |
calls[].audio_url | String (URL) | Yes | URL Aila can download the audio from. Aila copies the file into its own storage. |
calls[].recorded_at | String (ISO 8601) | Yes | Timestamp when the call occurred. |
calls[].agent_name | String | Yes | Name of the team member on the call. |
calls[].agent_email | String (Email) | Yes | Email of the team member. If no Aila user has this email, Aila creates one as a Member and adds them to your organization. |
calls[].contact_name | String | No | Customer or lead name. |
calls[].contact_phone | String | No | Customer phone number in E.164 format. |
calls[].duration | Integer | No | Call length in seconds. |
calls[].external_id | String | No | ID from your dialer or telephony system. |
calls[].tags | Array<string> | No | Up to 10 metadata tags. |
calls[].metadata | Object | No | Key-value dictionary of custom metadata. |
Example Request
{
"calls": [
{
"audio_url": "https://storage.example.com/recordings/call_001.mp3",
"recorded_at": "2026-08-24T14:30:00Z",
"agent_name": "Sarah Connor",
"agent_email": "sarah@company.com",
"contact_name": "John Smith",
"contact_phone": "+15551234567",
"external_id": "dialer_rec_987"
}
]
}Response
The API returns 202 Accepted:
{
"success": true,
"data": {
"batch_id": "ai_call_batch_...",
"total_calls": 2,
"status": "queued",
"calls": [
{ "call_id": "ai_call_...", "external_id": "dialer_rec_987", "status": "queued" },
{ "call_id": null, "external_id": "dialer_rec_988", "status": "failed", "error": "..." }
],
"status_url": "https://app.aila.fyi/api/v1/batches/ai_call_batch_..."
}
}A batch can partly succeed. Check each call's status; failed calls have call_id: null and an error.
Polling Batch Status
Query batch progress using the status URL:
GET https://app.aila.fyi/api/v1/batches/{batch_id}
Authorization: Bearer <YOUR_API_KEY>Batch Status Response
{
"success": true,
"data": {
"batch_id": "batch_abc123",
"total_calls": 10,
"processed": 8,
"failed": 0,
"in_progress": 2,
"status": "processing",
"progress_percentage": 80,
"calls": [
{ "call_id": "ai_call_...", "external_id": "dialer_rec_987", "status": "complete" }
],
"created_at": "2026-09-30T14:30:00.000Z",
"estimated_completion": "2026-09-30T14:40:00.000Z"
}
}Batch status is queued, processing, completed, or failed. Each call's status is queued, processing, complete, or failed.
Subscribe to the call.completed webhook instead of polling if you need to act on each call.