Skip to main content

Submitting Call Analysis

Learn how to submit call recordings to the CallCov API for AI-powered analysis. This guide covers audio file uploads, metadata submission, and best practices for integration.

Overview​

CallCov provides two methods for submitting calls:

  1. File Upload - Upload audio files directly (recommended for most use cases)
  2. URL Submission - Provide URLs to audio files stored elsewhere

Both methods return an analysis ID for tracking the processing status.

Endpoint​

POST /api/v1/calls/analyze

Authentication: Required (API Key)

Method 1: File Upload​

Upload audio files directly to CallCov for analysis.

Supported Audio Formats​

FormatExtensionMax SizeRecommended
WAV.wav100 MBβœ… Yes
MP3.mp350 MBβœ… Yes
M4A.m4a50 MBβœ… Yes
FLAC.flac100 MBSupported
OGG.ogg50 MBSupported
Best Quality

For best results, use WAV or FLAC formats with:

  • Sample rate: 16 kHz or higher
  • Bit depth: 16-bit minimum
  • Channels: Mono or stereo (separate channels preferred for multi-speaker)

Basic File Upload​

import requests
API_KEY = "your_api_key_here"
API_URL = "https://api.callcov.com/api/v1"
# Prepare the file and metadata
files = {
"audio_file": open("call_recording.wav", "rb")
}
data = {
"agent_id": "AGENT_001",
"contact_id": "CONTACT_12345",
"call_direction": "inbound",
"call_timestamp": "2024-01-15T10:30:00Z"
}
headers = {"X-API-Key": API_KEY}
# Submit for analysis
response = requests.post(
f"{API_URL}/calls/analyze",
headers=headers,
files=files,
data=data
)
result = response.json()
print(f"Analysis ID: {result['analysis_id']}")
print(f"Status: {result['status']}")

Request Parameters​

ParameterTypeRequiredDescription
audio_fileFileYesThe audio file to analyze
agent_idStringYesUnique identifier for the agent
contact_idStringYesUnique identifier for the contact/customer
call_directionStringNoinbound or outbound
call_timestampStringNoISO 8601 timestamp of when call occurred
metadataObjectNoAdditional custom metadata (JSON string)

Response​

{
"analysis_id": "anl_1a2b3c4d5e",
"status": "processing",
"created_at": "2024-01-15T10:30:05Z",
"estimated_completion": "2024-01-15T10:32:00Z",
"webhook_url": "https://your-app.com/webhooks/callcov"
}

Method 2: URL Submission​

Submit a URL to an audio file hosted elsewhere. CallCov will download and process the file.

import requests
API_KEY = "your_api_key_here"
API_URL = "https://api.callcov.com/api/v1"
# Submit audio URL
payload = {
"audio_url": "https://your-storage.com/recordings/call_12345.wav",
"agent_id": "AGENT_001",
"contact_id": "CONTACT_12345",
"call_direction": "outbound",
"call_timestamp": "2024-01-15T14:20:00Z"
}
headers = {
"X-API-Key": API_KEY,
"Content-Type": "application/json"
}
response = requests.post(
f"{API_URL}/calls/analyze",
headers=headers,
json=payload
)
result = response.json()
print(f"Analysis ID: {result['analysis_id']}")
URL Requirements
  • URL must be publicly accessible or include authentication in the URL
  • Must return Content-Type: audio/* header
  • File size limits still apply
  • HTTPS URLs recommended for security

Checking Analysis Status​

After submission, poll the status endpoint to check progress:

import requests
import time
def wait_for_analysis(analysis_id, api_key, max_wait=300):
"""Poll until analysis completes or timeout"""
api_url = "https://api.callcov.com/api/v1"
headers = {"X-API-Key": api_key}
start_time = time.time()
while time.time() - start_time < max_wait:
response = requests.get(
f"{api_url}/calls/analyze/{analysis_id}",
headers=headers
)
result = response.json()
status = result['status']
if status == 'completed':
print("Analysis completed!")
return result
elif status == 'failed':
print(f"Analysis failed: {result.get('error')}")
return None
print(f"Status: {status} - waiting...")
time.sleep(5) # Poll every 5 seconds
print("Timeout waiting for analysis")
return None
# Usage
analysis_id = "anl_1a2b3c4d5e"
result = wait_for_analysis(analysis_id, "your_api_key_here")
if result:
print(f"Sentiment: {result['analysis']['sentiment']}")
print(f"Summary: {result['analysis']['summary']}")
Better Approach: Use Webhooks

Instead of polling, configure a webhook to receive notifications when analysis completes. See the Webhooks Guide for details.

Batch Submissions​

Submit multiple calls efficiently:

import requests
import os
from concurrent.futures import ThreadPoolExecutor, as_completed
API_KEY = "your_api_key_here"
API_URL = "https://api.callcov.com/api/v1"
def submit_call(file_path, agent_id, contact_id):
"""Submit a single call for analysis"""
files = {"audio_file": open(file_path, "rb")}
data = {
"agent_id": agent_id,
"contact_id": contact_id
}
headers = {"X-API-Key": API_KEY}
response = requests.post(
f"{API_URL}/calls/analyze",
headers=headers,
files=files,
data=data
)
return response.json()
# Batch submit with threading
calls_to_submit = [
("recording1.wav", "AGENT_001", "CONTACT_001"),
("recording2.wav", "AGENT_001", "CONTACT_002"),
("recording3.wav", "AGENT_002", "CONTACT_003"),
]
results = []
with ThreadPoolExecutor(max_workers=5) as executor:
futures = [
executor.submit(submit_call, file_path, agent_id, contact_id)
for file_path, agent_id, contact_id in calls_to_submit
]
for future in as_completed(futures):
try:
result = future.result()
results.append(result)
print(f"Submitted: {result['analysis_id']}")
except Exception as e:
print(f"Error: {e}")
print(f"\nSubmitted {len(results)} calls for analysis")

Best Practices​

Audio Quality​

  • Sample rate: 16 kHz minimum, 44.1 kHz recommended
  • Codec: Uncompressed (WAV, FLAC) for best results
  • Channels: Separate channels for agent and customer when possible
  • Background noise: Minimize for better transcription accuracy

Performance Optimization​

  1. Use webhooks instead of polling for results
  2. Compress large files before upload (but not too much - quality matters)
  3. Batch submit during off-peak hours for large volumes
  4. Cache results to avoid reprocessing the same calls

Error Handling​

Always implement retry logic with exponential backoff:

import time
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
def create_retry_session(retries=3, backoff_factor=0.3):
"""Create session with automatic retry"""
session = requests.Session()
retry = Retry(
total=retries,
read=retries,
connect=retries,
backoff_factor=backoff_factor,
status_forcelist=(500, 502, 503, 504),
)
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)
return session
# Usage
session = create_retry_session()
response = session.post(
f"{API_URL}/calls/analyze",
headers=headers,
files=files,
data=data
)

Rate Limits​

Submission rate limits vary by plan:

PlanSubmissions/MinuteConcurrent Processing
Free51
Starter305
Business15025
EnterpriseCustomCustom

Common Errors​

400 Bad Request​

{
"error": {
"code": "invalid_file_format",
"message": "Audio file must be in WAV, MP3, M4A, FLAC, or OGG format"
}
}

Solution: Check file format and ensure it's supported.

413 Payload Too Large​

{
"error": {
"code": "file_too_large",
"message": "Audio file exceeds maximum size of 100 MB"
}
}

Solution: Compress the audio or split into smaller segments.

429 Too Many Requests​

{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Please try again in 32 seconds."
}
}

Solution: Implement rate limiting and exponential backoff in your code.

Next Steps​

Need Help?​