Speech Analytics API

Обзор

API для загрузки аудиозаписей звонков и автоматического запуска их транскрибации и анализа с помощью ИИ.

После загрузки файл автоматически:

  1. ✅ Загружается в облачное хранилище

  2. ✅ Отправляется на транскрибацию

  3. ✅ Анализируется с помощью LLM

  4. ✅ Классифицируется по намерениям и сущностям


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 = менеджер, канал 1 = клиент


Структура метаданных

Базовая структура
{
  "interaction_id": "call_123456",
  "channel": "voice",
  "timestamp": "2024-11-25T10:30:00Z",
  "manager": {
    "name": "Иван Петров",
    "id": "emp_001",
    "department": "Продажи"
  },
  "client": {
    "name": "ООО Рога и Копыта",
    "phone": "+79991234567",
    "email": "[email protected]"
  },
  "voice": {
    "recording_mode": "stereo",
    "provider": "zadarma",
    "stereo_mapping": {
      "0": "manager",
      "1": "client"
    }
  }
}

Обязательные поля

  • interaction_id (string) - Уникальный идентификатор звонка

  • channel (string) - Канал коммуникации: "voice", "chat", "email" и т.д.

  • timestamp (string ISO 8601) - Время звонка

Поля для голосовых звонков

Если channel = "voice", обязательно добавьте секцию voice:

{
  "voice": {
    "recording_mode": "stereo",  // "mono" или "stereo"
    "provider": "zadarma",       // название телефонии (опционально)
    "stereo_mapping": {          // только для stereo
      "0": "manager",            // канал 0 = менеджер
      "1": "client"              // канал 1 = клиент
    }
  }
}
Участники звонка
{
  "manager": {
    "name": "Имя менеджера",    // обязательно
    "id": "emp_001",            // опционально
    "department": "Продажи"     // опционально
  },
  "client": {
    "name": "Имя клиента",      // обязательно
    "phone": "+79991234567",    // опционально
    "email": "[email protected]"  // опционально
  }
}

Примеры запросов

cURL - Mono запись
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",
    "manager": {
      "name": "Иван Петров",
      "id": "emp_123"
    },
    "client": {
      "name": "Мария Иванова",
      "phone": "+79991234567"
    },
    "voice": {
      "recording_mode": "mono",
      "provider": "mango"
    }
  }'
cURL - Stereo запись
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",
    "manager": {
      "name": "Петр Сидоров"
    },
    "client": {
      "name": "ООО Компания",
      "phone": "+74951234567"
    },
    "voice": {
      "recording_mode": "stereo",
      "provider": "zadarma",
      "stereo_mapping": {
        "0": "manager",
        "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",
    "manager": {
        "name": "Иван Петров",
        "id": "emp_123"
    },
    "client": {
        "name": "Клиент",
        "phone": "+79991234567"
    },
    "voice": {
        "recording_mode": "stereo",
        "provider": "zadarma",
        "stereo_mapping": {
            "0": "manager",
            "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",
    "manager": {
      "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 Mono
  • Стерео (2 канала): более точное разделение спикеров

    • Канал 0 = менеджер, Канал 1 = клиент

    • Обязательно укажите stereo_mapping

  • Mono (1 канал): разделение по алгоритму speaker diarization

    • Менее точное, но работает без специальной настройки

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"
}

Последнее обновление