Voice2Doc LogoVoice2Doc
Назад к блогу
V
Voice2Doc
25 мин

Voice2Doc API: Полное руководство по интеграции для разработчиков

Voice2Doc API: Полное руководство по интеграции для разработчиков - изображение статьи Voice2Doc

Voice2Doc API: Полное руководство по интеграции для разработчиков

Если вы разработчик и хотите интегрировать возможности автоматической транскрибации и обработки аудио в ваше приложение, корпоративный портал или CRM — это руководство для вас.

Voice2Doc API предоставляет мощный REST API v2 и систему webhook-уведомлений, которые позволяют автоматизировать весь процесс: от загрузки аудиофайла до получения структурированного документа.

🎯 Что вы получаете с Voice2Doc API

Полнофункциональный REST API v2

  • Загрузка и обработка аудио/видео файлов
  • Управление шаблонами обработки
  • Мониторинг баланса и статусов
  • Получение транскрипций и обработанных документов

Webhook уведомления в реальном времени

  • Автоматические уведомления о статусе обработки
  • HMAC-подписи для безопасности
  • Retry-механизм для надёжной доставки

Гибкая обработка контента

  • Системные шаблоны для типовых задач
  • Создание собственных шаблонов через UI или API
  • Структурированный вывод в нужном формате

🚀 Быстрый старт: первый запрос за 5 минут

Шаг 1: Получите API ключ

  1. Откройте Telegram бот Voice2Doc или веб-приложение
  2. Перейдите в Профиль → API Интеграция
  3. Скопируйте ваш уникальный API ключ

Шаг 2: Проверьте соединение

curl -X GET "https://api.voice2doc.com/api/v2/balance/" \
  -H "x-api-key: ваш-api-ключ"

Ответ:

{
  "total_balance": 150.5,
  "available_balance": 130.0,
  "frozen_balance": 20.5,
  "currency": "minutes"
}

Шаг 3: Загрузите первый файл

curl -X POST "https://api.voice2doc.com/api/v2/records/upload" \
  -H "x-api-key: ваш-api-ключ" \
  -F "file=@meeting.mp3"

Ответ:

{
  "success": true,
  "record_id": "123e4567-e89b-12d3-a456-426614174000",
  "status": "uploaded",
  "message": "Файл успешно загружен и готов к обработке"
}

Шаг 4: Получите результат

curl -X GET "https://api.voice2doc.com/api/v2/records/123e4567-e89b-12d3-a456-426614174000" \
  -H "x-api-key: ваш-api-ключ"

🎉 Поздравляем! Вы только что выполнили свой первый запрос к Voice2Doc API.


💡 Сценарии использования API

🏢 Корпоративные системы

Автоматизация документооборота

  • Интеграция с корпоративным порталом
  • Автоматическая обработка записей совещаний
  • Создание протоколов без ручного ввода
  • Формирование отчётов из голосовых заметок руководителей

Пример workflow:

Совещание → Запись → API загрузка →
Webhook уведомление → Автоматическое сохранение в корпоративную систему

📞 CRM и системы управления

Работа со звонками

  • Транскрибация звонков с клиентами
  • Автоматическое создание карточек встреч
  • Анализ разговоров для контроля качества

Пример интеграции:

// После завершения звонка в CRM
const callRecording = getCallRecording(callId);
const result = await uploadToVoice2Doc(callRecording);
await saveToCRM(callId, result.transcript);

🏥 Медицина

  • Автоматизация медицинских заключений из диктовок врачей
  • Формирование структурированных карт пациентов
  • Интеграция с медицинскими информационными системами

⚖️ Юриспруденция

  • Транскрибация судебных заседаний
  • Обработка юридических консультаций
  • Создание протоколов допросов

💼 Малый бизнес и стартапы

  • Автоматизация обработки заявок по телефону
  • Создание задач из голосовых сообщений
  • Интеграция с мессенджерами и чат-ботами

🔐 Настройка интеграции

API ключ

Где используется:

  • Передаётся в заголовке x-api-key при каждом запросе
  • Идентифицирует ваш аккаунт и контролирует доступ
  • Необходим для всех операций с API

Пример использования:

headers = {
    "x-api-key": "ваш-уникальный-api-ключ"
}
response = requests.get(f"{BASE_URL}/balance/", headers=headers)

⚠️ Когда регенерировать ключ:

  • Ключ был случайно опубликован
  • Обнаружены несанкционированные запросы
  • Бывший сотрудник имел доступ
  • Плановая ротация (рекомендуется каждые 3-6 месяцев)

Webhook URL

Назначение: Адрес вашего сервера для получения уведомлений в реальном времени

Требования:

  • Обязательно HTTPS (для безопасности)
  • Должен принимать POST-запросы
  • Должен быть доступен из интернета
  • Рекомендуется возвращать статус 200-299

Пример:

https://your-domain.com/api/webhook

Webhook секрет

Зачем нужен:

  • Гарантирует подлинность запросов от Voice2Doc
  • Защищает от подделки webhook-уведомлений
  • Обеспечивает целостность данных через HMAC-SHA256

📚 REST API Документация

Базовый URL

https://api.voice2doc.com/api/v2

Аутентификация

Все запросы требуют API ключ в заголовке:

x-api-key: ваш-api-ключ

Основные эндпоинты

1️⃣ Баланс

GET /api/v2/balance/

Получить информацию о балансе минут.

curl -X GET "https://api.voice2doc.com/api/v2/balance/" \
  -H "x-api-key: ваш-api-ключ"

Ответ:

{
  "total_balance": 150.5,
  "available_balance": 130.0,
  "frozen_balance": 20.5,
  "currency": "minutes"
}

2️⃣ Шаблоны

GET /api/v2/templates/

Получить список всех доступных шаблонов (системных и личных).

curl -X GET "https://api.voice2doc.com/api/v2/templates/" \
  -H "x-api-key: ваш-api-ключ"

Ответ:

{
  "templates": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Медицинское заключение",
      "is_system": true
    },
    {
      "id": "660e8400-e29b-41d4-a716-446655440001",
      "name": "Мой шаблон",
      "is_system": false
    }
  ],
  "total": 15,
  "system_count": 10,
  "personal_count": 5
}

GET /api/v2/templates/{template_id}

Получить подробную информацию о шаблоне.

3️⃣ Записи

POST /api/v2/records/upload

Загрузить аудио/видео файл для обработки.

Параметры:

  • file (обязательный) — аудио/видео файл
  • template_id (опциональный) — UUID шаблона для обработки

Поддерживаемые форматы: MP3, WAV, OGG, M4A, WebM Максимальный размер: 5GB

curl -X POST "https://api.voice2doc.com/api/v2/records/upload" \
  -H "x-api-key: ваш-api-ключ" \
  -F "file=@meeting.mp3" \
  -F "template_id=550e8400-e29b-41d4-a716-446655440000"

GET /api/v2/records/

Получить список записей с пагинацией.

Параметры:

  • offset (int) — смещение для пагинации (по умолчанию 0)
  • limit (int) — количество записей от 1 до 100 (по умолчанию 50)
  • status (string) — фильтр по статусу
curl -X GET "https://api.voice2doc.com/api/v2/records/?limit=10&status=completed" \
  -H "x-api-key: ваш-api-ключ"

GET /api/v2/records/{record_id}

Получить подробную информацию о записи.

curl -X GET "https://api.voice2doc.com/api/v2/records/123e4567-e89b-12d3-a456-426614174000" \
  -H "x-api-key: ваш-api-ключ"

Ответ:

{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "name": "meeting_recording.mp3",
  "status": "completed",
  "transcript_text": "Расшифрованный текст...",
  "post_processing_text": "Обработанный текст...",
  "template_id": "template-123",
  "processing_error": null,
  "duration": 2550,
  "created_at": "2024-01-15T10:30:00Z"
}

DELETE /api/v2/records/{record_id}

Удалить запись (мягкое удаление).

curl -X DELETE "https://api.voice2doc.com/api/v2/records/123e4567-e89b-12d3-a456-426614174000" \
  -H "x-api-key: ваш-api-ключ"

🔔 Webhook интеграция

Webhook позволяют получать уведомления о событиях обработки в реальном времени.

Типы событий

СобытиеКогда срабатывает
record_successТранскрибация и обработка завершены успешно
record_errorПроизошла ошибка при обработке
not_enough_balanceНедостаточно минут на балансе

Формат webhook запроса

Заголовки:

Content-Type: application/json
X-Webhook-Signature: sha256=<hmac_signature>
User-Agent: Voice2Doc-Webhook/1.0

Структура payload:

{
  "event_type": "record_success",
  "timestamp": "2025-12-28T12:30:45.123456+00:00",
  "record_id": "550e8400-e29b-41d4-a716-446655440000",
  "user_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "record_name": "Встреча с клиентом",
    "template_name": "Протокол встречи",
    "record_url": "https://app.voice2doc.com/records/...",
    "transcription_text": "Текст расшифровки...",
    "post_processing_text": "Структурированный документ..."
  }
}

Верификация подписи

⚠️ Критически важно: Всегда верифицируйте подпись webhook для защиты от подделок!

Алгоритм:

  1. Получите raw body запроса (байты, НЕ JSON)
  2. Извлеките подпись из заголовка X-Webhook-Signature
  3. Уберите префикс sha256=
  4. Вычислите HMAC-SHA256 от raw body
  5. Используйте безопасное сравнение

Пример на Python (Flask):

import hmac
import hashlib
from flask import Flask, request, jsonify

app = Flask(__name__)

def verify_webhook_signature(payload_bytes, signature_header, secret):
    """Верификация HMAC-SHA256 подписи webhook"""
    if not signature_header.startswith('sha256='):
        return False

    received_signature = signature_header[7:]

    expected_signature = hmac.new(
        secret.encode('utf-8'),
        payload_bytes,
        hashlib.sha256
    ).hexdigest()

    return hmac.compare_digest(received_signature, expected_signature)

@app.route('/webhook', methods=['POST'])
def handle_webhook():
    # Получаем raw body (ВАЖНО!)
    payload_bytes = request.get_data()
    signature = request.headers.get('X-Webhook-Signature', '')
    webhook_secret = 'ваш-webhook-secret'

    # Верифицируем
    if not verify_webhook_signature(payload_bytes, signature, webhook_secret):
        return jsonify({'error': 'Invalid signature'}), 401

    # Обрабатываем
    payload = request.get_json()
    event_type = payload['event_type']

    if event_type == 'record_success':
        record_id = payload['record_id']
        transcription = payload['data']['transcription_text']
        print(f"✅ Запись {record_id} обработана")
        # Ваша логика

    return jsonify({'status': 'ok'}), 200

Пример на Node.js (Express):

const crypto = require('crypto');
const express = require('express');

function verifyWebhookSignature(payloadBody, signatureHeader, secret) {
    if (!signatureHeader.startsWith('sha256=')) {
        return false;
    }

    const receivedSignature = signatureHeader.substring(7);
    const expectedSignature = crypto
        .createHmac('sha256', secret)
        .update(payloadBody)
        .digest('hex');

    return crypto.timingSafeEqual(
        Buffer.from(receivedSignature),
        Buffer.from(expectedSignature)
    );
}

const app = express();

app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
    const signature = req.headers['x-webhook-signature'] || '';
    const webhookSecret = 'ваш-webhook-secret';

    if (!verifyWebhookSignature(req.body, signature, webhookSecret)) {
        return res.status(401).json({error: 'Invalid signature'});
    }

    const payload = JSON.parse(req.body.toString());

    switch (payload.event_type) {
        case 'record_success':
            console.log(`✅ Запись ${payload.record_id} обработана`);
            break;
        case 'record_error':
            console.log(`❌ Ошибка: ${payload.data.error_message}`);
            break;
    }

    res.json({status: 'ok'});
});

💻 Примеры интеграции

Пример 1: Простая интеграция на Python

import requests
import time
import os

API_KEY = os.getenv('VOICE2DOC_API_KEY')
BASE_URL = "https://api.voice2doc.com/api/v2"
headers = {"x-api-key": API_KEY}

def upload_and_process(file_path, template_id=None):
    """Загрузить файл и дождаться обработки"""

    # 1. Загружаем файл
    print(f"📤 Загружаем файл: {file_path}")
    with open(file_path, 'rb') as f:
        files = {'file': f}
        data = {}
        if template_id:
            data['template_id'] = template_id

        response = requests.post(
            f"{BASE_URL}/records/upload",
            headers=headers,
            files=files,
            data=data
        )

    if response.status_code != 201:
        print(f"❌ Ошибка загрузки: {response.text}")
        return None

    result = response.json()
    record_id = result['record_id']
    print(f"✅ Файл загружен. Record ID: {record_id}")

    # 2. Ждём завершения обработки
    print("⏳ Ожидаем обработки...")
    while True:
        response = requests.get(
            f"{BASE_URL}/records/{record_id}",
            headers=headers
        )

        if response.status_code != 200:
            print(f"❌ Ошибка получения статуса: {response.text}")
            return None

        record = response.json()
        status = record['status']

        if status == 'completed':
            print("✅ Обработка завершена!")
            return record
        elif status == 'failed':
            error = record.get('processing_error', 'Unknown error')
            print(f"❌ Ошибка обработки: {error}")
            return None

        time.sleep(5)

# Использование
if __name__ == "__main__":
    record = upload_and_process('meeting.mp3')

    if record:
        print("\n📄 Результат:")
        print(f"Транскрипция: {record['transcript_text'][:200]}...")
        print(f"\nОбработанный текст: {record['post_processing_text'][:200]}...")

Пример 2: Интеграция с webhook на Flask

from flask import Flask, request, jsonify
import requests
import hmac
import hashlib
import os

app = Flask(__name__)

API_KEY = os.getenv('VOICE2DOC_API_KEY')
WEBHOOK_SECRET = os.getenv('VOICE2DOC_WEBHOOK_SECRET')
BASE_URL = "https://api.voice2doc.com/api/v2"

def verify_webhook_signature(payload_bytes, signature_header, secret):
    if not signature_header.startswith('sha256='):
        return False
    received_signature = signature_header[7:]
    expected_signature = hmac.new(
        secret.encode('utf-8'),
        payload_bytes,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(received_signature, expected_signature)

@app.route('/api/upload', methods=['POST'])
def upload_file():
    """API endpoint для загрузки файлов"""
    if 'file' not in request.files:
        return jsonify({'error': 'No file provided'}), 400

    file = request.files['file']
    template_id = request.form.get('template_id')

    # Загружаем в Voice2Doc
    files = {'file': (file.filename, file.stream, file.content_type)}
    data = {}
    if template_id:
        data['template_id'] = template_id

    response = requests.post(
        f"{BASE_URL}/records/upload",
        headers={"x-api-key": API_KEY},
        files=files,
        data=data
    )

    if response.status_code == 201:
        result = response.json()
        return jsonify({
            'success': True,
            'record_id': result['record_id'],
            'message': 'Файл загружен. Результат придёт на webhook.'
        }), 201
    else:
        return jsonify({
            'success': False,
            'error': response.text
        }), response.status_code

@app.route('/webhook', methods=['POST'])
def handle_webhook():
    """Обработчик webhook от Voice2Doc"""
    payload_bytes = request.get_data()
    signature = request.headers.get('X-Webhook-Signature', '')

    if not verify_webhook_signature(payload_bytes, signature, WEBHOOK_SECRET):
        return jsonify({'error': 'Invalid signature'}), 401

    payload = request.get_json()
    event_type = payload['event_type']
    record_id = payload['record_id']

    if event_type == 'record_success':
        data = payload['data']
        transcription = data['transcription_text']
        processed = data['post_processing_text']

        print(f"✅ Запись {record_id} обработана")

        # Ваша бизнес-логика:
        # - Сохранить в БД
        # - Отправить уведомление
        # - Интегрировать с CRM

    elif event_type == 'record_error':
        error_msg = payload['data']['error_message']
        print(f"❌ Ошибка обработки {record_id}: {error_msg}")

    return jsonify({'status': 'ok'}), 200

if __name__ == '__main__':
    app.run(port=5000)

Пример 3: Интеграция с Telegram ботом

import os
import requests
from telegram import Update
from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes

API_KEY = os.getenv('VOICE2DOC_API_KEY')
TELEGRAM_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN')
BASE_URL = "https://api.voice2doc.com/api/v2"

async def handle_audio(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Обработка аудио файлов"""
    message = update.message

    # Получаем файл от Telegram
    if message.voice:
        file = await message.voice.get_file()
    elif message.audio:
        file = await message.audio.get_file()
    else:
        await message.reply_text("Пожалуйста, отправьте аудио файл")
        return

    await message.reply_text("⏳ Загружаю файл в Voice2Doc...")

    # Скачиваем файл
    file_path = f"/tmp/{file.file_id}.ogg"
    await file.download_to_drive(file_path)

    # Отправляем в Voice2Doc
    try:
        with open(file_path, 'rb') as f:
            response = requests.post(
                f"{BASE_URL}/records/upload",
                headers={"x-api-key": API_KEY},
                files={'file': f}
            )

        if response.status_code == 201:
            result = response.json()
            record_id = result['record_id']

            await message.reply_text(
                f"✅ Файл загружен!\n"
                f"ID записи: `{record_id}`\n"
                f"Статус: обрабатывается...\n\n"
                f"Используйте /status {record_id} для проверки",
                parse_mode='Markdown'
            )
        else:
            await message.reply_text(f"❌ Ошибка: {response.text}")

    except Exception as e:
        await message.reply_text(f"❌ Ошибка: {str(e)}")

    os.remove(file_path)

def main():
    app = Application.builder().token(TELEGRAM_TOKEN).build()

    app.add_handler(MessageHandler(filters.VOICE | filters.AUDIO, handle_audio))

    print("🤖 Бот запущен!")
    app.run_polling()

if __name__ == '__main__':
    main()

🔒 Безопасность

✅ Рекомендации по API ключам

DO — Делайте так:

  • Храните ключи в переменных окружения
  • Используйте разные ключи для dev/prod
  • Регулярно ротируйте ключи (каждые 3-6 месяцев)
  • Используйте системы управления секретами

DON'T — Не делайте так:

  • ❌ Не коммитьте ключи в Git
  • ❌ Не передавайте через URL параметры
  • ❌ Не храните в frontend коде
  • ❌ Не используйте один ключ для всех проектов

✅ Рекомендации по Webhook

DO — Делайте так:

  • Всегда верифицируйте подпись
  • Используйте HTTPS (обязательно!)
  • Проверяйте timestamp для защиты от replay-атак
  • Логируйте все входящие webhook

DON'T — Не делайте так:

  • ❌ Не пропускайте проверку подписи
  • ❌ Не используйте HTTP вместо HTTPS
  • ❌ Не храните webhook_secret в публичном коде

Пример безопасного хранения

.env файл (добавьте в .gitignore!):

VOICE2DOC_API_KEY=ваш-api-ключ
VOICE2DOC_WEBHOOK_SECRET=ваш-webhook-секрет

Python:

import os
from dotenv import load_dotenv

load_dotenv()

API_KEY = os.getenv('VOICE2DOC_API_KEY')
WEBHOOK_SECRET = os.getenv('VOICE2DOC_WEBHOOK_SECRET')

Node.js:

require('dotenv').config();

const API_KEY = process.env.VOICE2DOC_API_KEY;
const WEBHOOK_SECRET = process.env.VOICE2DOC_WEBHOOK_SECRET;

🐛 Устранение проблем

❌ Ошибка 401: Invalid API key

Причины:

  • API ключ неверный или устарел
  • Ключ не передан в заголовке
  • Ключ был регенерирован

Решение:

# ✅ Правильно
headers = {"x-api-key": "ваш-ключ"}

# ❌ Неправильно
headers = {"Authorization": "Bearer ваш-ключ"}  # Неверный заголовок

❌ Ошибка 413: File too large

Причина: Размер файла превышает 5GB

Решение:

  • Разбейте файл на части
  • Сожмите аудио с меньшим битрейтом
  • Используйте формат с лучшим сжатием (MP3, OGG)

❌ Webhook не приходят

Чек-лист:

  1. Проверьте что Webhook URL заполнен
  2. Убедитесь что endpoint доступен из интернета
  3. Проверьте что возвращается статус 200
  4. Используйте webhook.site для тестирования

❌ Ошибка "Invalid signature"

Частые причины:

# ❌ Используете JSON вместо raw body
payload = request.get_json()
verify_signature(str(payload), signature, secret)

# ✅ Правильно - используйте raw body
payload_bytes = request.get_data()
verify_signature(payload_bytes, signature, secret)

📊 Лимиты и ограничения

Файлы

ПараметрЗначение
Максимальный размер5 GB
ФорматыMP3, WAV, OGG, M4A, WebM
Максимальная длительностьЗависит от баланса

API запросы

ПараметрЗначение
Rate limitingВ разработке
Лимит записей на странице1-100 (по умолчанию 50)
Timeout запроса30 секунд

Webhook

ПараметрЗначение
Попытки доставки3
Задержки между попытками1s, 2s, 4s
Timeout доставки10 секунд

🎓 Рекомендуемый workflow для начала работы

  1. Тестирование — используйте curl или Postman для первых запросов
  2. Настройка webhook — для асинхронной обработки
  3. Верификация подписей — обязательно для безопасности
  4. Обработка ошибок — учитывайте все возможные статусы
  5. Мониторинг баланса — отслеживайте расход минут

🔗 Полезные ссылки


💬 Нужна помощь?

Если возникли вопросы или проблемы:

  • Обратитесь в поддержку через Telegram бота
  • Опишите проблему подробно: код ошибки, record_id, примеры запросов
  • Проверьте раздел "Устранение проблем" выше

Успешной интеграции! 🚀


Теги статьи: #API #разработка #интеграция #Voice2Doc #REST #webhook #автоматизация #транскрибация

Готовы попробовать Voice2Doc?

Создавайте протоколы совещаний за 2 минуты с помощью AI

Попробовать бесплатно