Speech Analytics API — Загрузка аудиозаписей
Обзор
API для загрузки аудиозаписей звонков и автоматического запуска их транскрибации и анализа с помощью ИИ.
После загрузки файл автоматически:
- ✅ Загружается в облачное хранилище
- ✅ Отправляется на транскрибацию
- ✅ Анализируется с помощью LLM
- ✅ Классифицируется по намерениям и сущностям
Endpoint
POST /api/v1/speech-analytics/calls/upload/
Аутентификация
Требуется токен авторизации в заголовке:
Authorization: Bearer <your_token>
Параметры запроса
Content-Type
multipart/form-data
Обязательные поля
| Параметр | Тип | Описание |
|---|---|---|
audio_file | File | Аудиофайл звонка |
project | Integer | ID проекта (для определения схемы метаданных) |
metadata | JSON | Метаданные звонка в формате JSON |
Форматы аудио
Поддерживаемые форматы:
- ✅ MP3
- ✅ WAV
- ✅ OGG
- ✅ OPUS
- ✅ M4A
- ✅ FLAC
Ограничения:
- Максимальный размер файла: 20 МБ
- Рекомендуемое качество: 16 kHz, 16-bit
- Для стерео: канал 0 = оператор (agent), канал 1 = клиент
Структура метаданных
Базовая структура
{
"interaction_id": "call_123456",
"channel": "voice",
"timestamp": "2024-11-25T10:30:00Z",
"agent": {
"name": "Иван Петров",
"id": "emp_001",
"department": "Продажи"
},
"client": {
"name": "ООО Рога и Копыта",
"phone": "+79991234567",
"email": "client@example.com"
},
"voice": {
"recording_mode": "stereo",
"provider": "zadarma",
"stereo_mapping": {
"0": "agent",
"1": "client"
}
}
}
Обязательные поля
interaction_id(string) - Уникальный идентификатор звонкаchannel(string) - Канал коммуникации:"voice","chat","email"и т.д.timestamp(string ISO 8601) - Время звонка
Поля для голосовых звонков
Если channel = "voice", обязательно добавьте секцию voice:
{
"voice": {
"recording_mode": "stereo",
"provider": "zadarma",
"stereo_mapping": {
"0": "agent",
"1": "client"
}
}
}
Участники звонка
{
"agent": {
"name": "Имя менеджера",
"id": "emp_001",
"department": "Продажи"
},
"client": {
"name": "Имя клиента",
"phone": "+79991234567",
"email": "client@test.com"
}
}
Примеры запросов
cURL — Моно запись
curl -X POST "https://api.example.com/api/v1/speech-analytics/calls/upload/" \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "audio_file=@/path/to/call.mp3" \
-F "project=42" \
-F 'metadata={
"interaction_id": "call_20241125_001",
"channel": "voice",
"timestamp": "2024-11-25T10:30:00Z",
"agent": {
"name": "Иван Петров",
"id": "emp_123"
},
"client": {
"name": "Мария Иванова",
"phone": "+79991234567"
},
"voice": {
"recording_mode": "mono",
"provider": "mango"
}
}'
cURL — Стерео запись
curl -X POST "https://api.example.com/api/v1/speech-analytics/calls/upload/" \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "audio_file=@/path/to/call_stereo.wav" \
-F "project=42" \
-F 'metadata={
"interaction_id": "call_20241125_002",
"channel": "voice",
"timestamp": "2024-11-25T11:00:00Z",
"agent": {
"name": "Петр Сидоров"
},
"client": {
"name": "ООО Компания",
"phone": "+74951234567"
},
"voice": {
"recording_mode": "stereo",
"provider": "zadarma",
"stereo_mapping": {
"0": "agent",
"1": "client"
}
}
}'
Python (requests)
import requests
import json
url = "https://api.example.com/api/v1/speech-analytics/calls/upload/"
headers = {
"Authorization": "Bearer YOUR_TOKEN"
}
metadata = {
"interaction_id": "call_001",
"channel": "voice",
"timestamp": "2024-11-25T10:30:00Z",
"agent": {
"name": "Иван Петров",
"id": "emp_123"
},
"client": {
"name": "Клиент",
"phone": "+79991234567"
},
"voice": {
"recording_mode": "stereo",
"provider": "zadarma",
"stereo_mapping": {
"0": "agent",
"1": "client"
}
}
}
files = {
'audio_file': open('/path/to/call.mp3', 'rb')
}
data = {
'project': 42,
'metadata': json.dumps(metadata)
}
response = requests.post(url, headers=headers, files=files, data=data)
print(response.json())
JavaScript (fetch)
const formData = new FormData();
formData.append('audio_file', audioFile); // File object
formData.append('project', '42');
formData.append('metadata', JSON.stringify({
interaction_id: 'call_001',
channel: 'voice',
timestamp: new Date().toISOString(),
manager: {
name: 'Иван Петров',
id: 'emp_123'
},
client: {
name: 'Клиент',
phone: '+79991234567'
},
voice: {
recording_mode: 'mono',
provider: 'mango'
}
}));
const response = await fetch('/api/v1/speech-analytics/calls/upload/', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_TOKEN'
},
body: formData
});
const data = await response.json();
console.log(data);
Ответ сервера
Успешная загрузка (200 OK)
{
"id": 12345,
"audio_file_uuid": "550e8400-e29b-41d4-a716-446655440000",
"audio_file_name": "call.mp3",
"status": "uploaded",
"metadata": {
"interaction_id": "call_001",
"channel": "voice",
"timestamp": "2024-11-25T10:30:00Z",
"agent": {
"name": "Иван Петров"
},
"client": {
"name": "Клиент",
"phone": "+79991234567"
},
"voice": {
"recording_mode": "stereo"
}
},
"created_at": "2024-11-25T10:32:15.123Z",
"message": "Call uploaded successfully. Transcription started."
}
Поля ответа
| Поле | Тип | Описание |
|---|---|---|
id | Integer | ID созданного звонка |
audio_file_uuid | UUID | Уникальный идентификатор файла |
audio_file_name | String | Имя загруженного файла |
status | String | Статус обработки (см. ниже) |
metadata | Object | Сохраненные метаданные |
created_at | DateTime | Время создания записи |
message | String | Информационное сообщение |
Статусы обработки
После загрузки звонок проходит через следующие статусы:
| Статус | Описание | Время |
|---|---|---|
uploaded | ✅ Файл загружен в S3 | 1-5 сек |
transcribing | 🔄 Идет транскрибация аудио | 1-10 мин |
transcribed | ✅ Транскрибация завершена | - |
analyzing | 🔄 Идет анализ с помощью LLM | 10-60 сек |
completed | ✅ Обработка завершена полностью | - |
failed | ❌ Ошибка обработки | - |
Опрос статуса:
GET /api/v1/speech-analytics/calls/{id}/
Ошибки
400 Bad Request — Неверный формат файла
{
"audio_file": [
"Unsupported file format. Allowed: mp3, wav, ogg, opus, m4a, flac"
]
}
400 Bad Request — Файл слишком большой
{
"audio_file": [
"File size exceeds maximum allowed size of 100 MB"
]
}
400 Bad Request — Неверные метаданные
{
"metadata": [
"Missing required field: interaction_id"
]
}
400 Bad Request — Валидация по схеме
{
"metadata": [
"Metadata validation failed: 'voice' is a required property"
]
}
400 Bad Request — Нет активной схемы
{
"metadata": [
"No active metadata schema found for project 42"
]
}
403 Forbidden — Нет прав
{
"detail": "You do not have permission to perform this action."
}
404 Not Found — Проект не найден
{
"project": [
"Project not found"
]
}
Лучшие практики
1. Качество аудио
- ✅ Используйте минимум 8 kHz sampling rate (рекомендуется 16 kHz)
- ✅ 16-bit PCM для лучшего качества транскрибации
- ✅ Избегайте высокого сжатия MP3 (используйте bitrate ≥ 128 kbps)
2. Стерео vs Моно
- Стерео (2 канала): более точное разделение спикеров
- Канал 0 = менеджер, Канал 1 = клиент
- Обязательно укажите
stereo_mapping
- Моно (1 канал): разделение спикеров по голосовым признакам
- Менее точное, но работает без специальной настройки
3. Метаданные
- ✅ Заполняйте
interaction_idуникальным значением для каждого звонка - ✅ Указывайте имена участников для лучшей читаемости отчетов
- ✅ Добавляйте данные для связывания с CRM
- ✅ Используйте ISO 8601 формат для
timestamp
4. Обработка ошибок
- ✅ Проверяйте размер файла до загрузки (≤ 20 МБ)
- ✅ Валидируйте формат файла на клиенте
- ✅ Обрабатывайте таймауты (загрузка может занять 10-30 сек)
- ✅ Сохраняйте
idзвонка для последующего опроса статуса
5. Производительность
- 🚀 Используйте асинхронную загрузку когда грузите много файлов
- 🚀 Сжимайте аудио перед загрузкой (MP3 128 kbps оптимально)
- 🚀 Не ждите завершения обработки — используйте webhooks или polling
Получение результатов
Опрос статуса
curl -X GET "https://api.example.com/api/v1/speech-analytics/calls/12345/" \
-H "Authorization: Bearer YOUR_TOKEN"
Ответ со всеми данными
{
"id": 12345,
"status": "completed",
"audio_file_name": "call.mp3",
"audio_duration_seconds": 180,
"metadata": { ... },
"transcript": {
"full_text": "Менеджер: Здравствуйте...",
"language": "ru-RU",
"utterances": [
{
"speaker_role": "manager",
"text": "Здравствуйте",
"start_time_ms": 0,
"end_time_ms": 500,
"intent": "greeting",
"confidence": 0.95
}
]
},
"analysis": {
"overall_quality": "good",
"call_outcome": "sale_completed",
"brief_summary": "Успешная продажа продукта X...",
"communication_score": 8.5,
"product_knowledge_score": 9.0,
"objection_handling_score": 7.5
},
"created_at": "2024-11-25T10:32:15Z"
}