# Руководство разработчика BlooTube Voice Public API v1

Официальная техническая документация программного интерфейса студии нейросетевого синтеза речи **BlooTube Voice**.

> **Планируемый базовый адрес API:** `https://api.apexcorelink.org/voice/api/v1` — endpoint ещё не активирован.

---

## Оглавление

1. [Обзор платформы и возможности](#1-обзор-платформы-и-возможности)
2. [Аутентификация и безопасность](#2-аутентификация-и-безопасность)
3. [Возможности движка (GET /capabilities)](#3-возможности-движка-get-capabilities)
4. [Профиль и остаток квоты (GET /me и GET /usage)](#4-профиль-и-остаток-квоты-get-me-и-get-usage)
5. [Каталог дикторов (GET /voices и GET /voices/{voice_id})](#5-каталог-дикторов-get-voices-и-get-voicesvoice_id)
6. [Создание задачи озвучки (POST /tasks)](#6-создание-задачи-озвучки-post-tasks)
7. [Разметка интонаций BlooTube Voice Markup (Beta)](#7-разметка-интонаций-blootube-voice-markup-beta)
8. [Жизненный цикл, прогресс и скачивание MP3](#8-жизненный-цикл-прогресс-и-скачивание-mp3)
9. [История и список задач (GET /tasks)](#9-история-и-список-задач-get-tasks)
10. [Клонирование голоса (POST /clones)](#10-клонирование-голоса-post-clones)
11. [Словари произношения (/pronunciation-dictionaries)](#11-словари-произношения-pronunciation-dictionaries)
12. [Лимиты частоты запросов (Rate Limits)](#12-лимиты-частоты-запросов-rate-limits)
13. [Справочник ошибок и коды HTTP](#13-справочник-ошибок-и-коды-http)
14. [Сквозные сценарии интеграции (Workflows)](#14-сквозные-сценарии-интеграции-workflows)
15. [Версионирование](#15-версионирование)

---

## 1. Обзор платформы и возможности

**BlooTube Voice Public API** — высокопроизводительный REST API для коммерческой автоматизации озвучки видеороликов, аудиокниг, подкастов, обучающих курсов и медиаконтента.

### Ключевые возможности:
- **Сверхдлинные тексты:** до 600 000 символов на тарифе **PRO STUDIO** и до 1 200 000 символов на тарифе **ULTRA VIP** в рамках одного запроса.
- **Интонационная разметка (Markup Beta):** фрагментное управление скоростью, громкостью, эмоциями, паузами и смехом через лаконичный встроенный XML-синтаксис.
- **Гарантия сохранности квоты:** Повторные запросы, ошибки и отмены защищены от двойного списания символов.
- **Студийный звук:** готовые файлы в стандарте MP3 44.1 кГц / 128 кбит/с с доступом на скачивание в течение 5 часов.
- **Публичные нейроклоны:** возможность создания голоса по 5–30-секундному аудиообразцу с автоматической публикацией в общем каталоге.

---

## 2. Аутентификация и безопасность

Каждый HTTP-запрос к API должен содержать заголовок `Authorization` с секретным ключом разработчика:

```http
Authorization: Bearer btv_live_YOUR_SECRET_API_KEY
```

### Правила и рекомендации безопасности:
1. **Формат ключа:** префикс `btv_live_`, за которым следуют публичный идентификатор и криптографический секрет.
2. **Безопасное хранение:** храните ключи исключительно в переменных окружения на стороне доверенного бэкенда (`process.env`, `os.environ`). Никогда не передавайте ключ в браузерном коде клиента.
3. **Ротация и отзыв:** в Telegram Mini App в разделе «API для разработчиков» доступен мгновенный отзыв скомпрометированных ключей в один клик.

---

## 3. Возможности движка (GET /capabilities)

Эндпоинт `GET /voice/api/v1/capabilities` возвращает спецификацию всех возможностей движка и утверждённых диапазонов параметров:

```bash
curl -X GET "https://api.apexcorelink.org/voice/api/v1/capabilities" \
  -H "Authorization: Bearer btv_live_YOUR_API_KEY"
```

### Эталонные диапазоны регуляторов речи:
| Регулятор | Тип | Минимум | Максимум | По умолчанию | Описание |
|---|:---:|:---:|:---:|:---:|---|
| **`speed`** | `float` | `0.6` | `1.5` | `1.0` | Нейросетевой темп речи диктора |
| **`volume`** | `float` | `0.5` | `2.0` | `1.0` | Коэффициент громкости |
| **`dsp_speed`** | `float` | `1.0` | `2.0` | `1.0` | Монтажное pitch-preserving ускорение темпа без изменения тональности |
| **`emotion`** | `string` | — | — | `null` | Эмоциональный тон (естественный тон диктора). `neutral` задается явно. |

### Утверждённые эмоциональные стили (7 Curated Emotions):
- `neutral` — сдержанный, дикторский стиль;
- `calm` — спокойное, размеренное повествование;
- `content` — удовлетворённый, мягкий тон;
- `excited` — воодушевлённый, динамичный тон;
- `sad` — грустный, меланхоличный стиль;
- `angry` — раздражённый, экспрессивный тон;
- `scared` — испуганный, тревожный тон.

---

## 4. Профиль и остаток квоты (GET /me и GET /usage)

### Проверка профиля (GET /me)
Возвращает полную сводку по аккаунту, остатку суточной квоты символов и лимитам тарифа:

```bash
curl -X GET "https://api.apexcorelink.org/voice/api/v1/me" \
  -H "Authorization: Bearer btv_live_YOUR_API_KEY"
```

Пример успешного ответа:
```json
{
  "ok": true,
  "account": {
    "telegram_id": 7894208047,
    "username": "studio_creator",
    "full_name": "Alex Dev",
    "tier": "pro",
    "tier_display": "PRO STUDIO",
    "has_active_license": true,
    "license_expires_at": "2026-10-18T00:00:00+00:00",
    "api_access_enabled": true
  },
  "quota": {
    "daily_limit_chars": 600000,
    "used_chars": 45000,
    "reserved_chars": 12000,
    "remaining_chars": 543000,
    "resets_at": "2026-09-20T00:00:00+00:00"
  },
  "limits": {
    "in_flight_concurrency": 2,
    "active_jobs_running": 1,
    "max_job_chars": 600000,
    "rate_limits": {
      "post_tasks_rpm": 10,
      "poll_tasks_rpm": 120,
      "general_rpm": 60
    }
  },
  "api_key": {
    "public_id": "btv_pub_a8b2c4d6e8f0",
    "name": "Production Key",
    "scopes": ["voices:read", "tts:create", "tasks:read"],
    "created_at": "2026-09-18T14:30:00+00:00"
  }
}
```

### Быстрая проверка квоты (GET /usage)
```bash
curl -X GET "https://api.apexcorelink.org/voice/api/v1/usage" \
  -H "Authorization: Bearer btv_live_YOUR_API_KEY"
```

---

## 5. Каталог дикторов (GET /voices и GET /voices/{voice_id})

### Список голосов (GET /voices)
Поддерживает фильтрацию по языку (`language`), полу (`gender`) и категории (`category`):

```bash
curl -X GET "https://api.apexcorelink.org/voice/api/v1/voices?language=ru&gender=male" \
  -H "Authorization: Bearer btv_live_YOUR_API_KEY"
```

### Информация о конкретном дикторе (GET /voices/{voice_id})
```bash
curl -X GET "https://api.apexcorelink.org/voice/api/v1/voices/VOICE_ID_FROM_CATALOG" \
  -H "Authorization: Bearer btv_live_YOUR_API_KEY"
```

Структура объекта Voice:
```json
{
  "id": "VOICE_ID_FROM_CATALOG",
  "name": "Владимир (Диктор)",
  "gender": "male",
  "language": "ru",
  "languages": ["ru", "en"],
  "is_cloned": false,
  "is_public": true,
  "source_type": "catalog",
  "created_by_me": false,
  "can_delete": false,
  "description": "Студийный баритон для озвучки документальных фильмов и обзоров",
  "preview_url": "/voice/api/voices/VOICE_ID_FROM_CATALOG/preview.mp3",
  "tags": ["BlooTube", "HD", "Студийный"]
}
```

---

## 6. Создание задачи озвучки (POST /tasks)

Синтез речи является асинхронным: сервер принимает запрос, валидирует синтаксис, резервирует суточную квоту и возвращает статус `202 Accepted` с идентификатором задачи `task_id`.

```bash
curl -X POST "https://api.apexcorelink.org/voice/api/v1/tasks" \
  -H "Authorization: Bearer btv_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: task-run-20260919-01" \
  -d '{
    "voice_id": "VOICE_ID_FROM_CATALOG",
    "text": "Здравствуйте! Это демонстрация профессиональной нейроозвучки BlooTube Voice.",
    "speed": 1.05,
    "volume": 1.0,
    "dsp_speed": 1.0,
    "emotion": null
  }'
```

### Параметры запроса POST /tasks:
| Параметр | Тип | Обязательный | Описание и ограничения |
|---|:---:|:---:|---|
| `text` | `string` | Да | Текст для озвучки (PRO: до 600 000, ULTRA: до 1 200 000 символов). Поддерживает разметку Markup Beta. |
| `voice_id` | `string` | Да | Идентификатор диктора из каталога (`VOICE_ID_FROM_CATALOG`) |
| `speed` | `float` | Нет | Темп речи диктора (`0.6` – `1.5`, по умолчанию `1.0`) |
| `volume` | `float` | Нет | Громкость (`0.5` – `2.0`, по умолчанию `1.0`) |
| `dsp_speed` | `float` | Нет | Монтажное pitch-preserving ускорение (`1.0` – `2.0`, по умолчанию `1.0`) |
| `emotion` | `string` | Нет | Стиль интонации (`null` по умолчанию, либо одна из 7 утверждённых эмоций) |
| `language` | `string` | Нет | Код языка (`ru`, `en`, `de` и др.) |
| `locale` | `string` | Нет | Региональная локаль (например, `ru-RU`, `en-US`) |
| `accent` | `string` | Нет | Акцент диктора |
| `pronunciation_dictionary_id` | `string` | Нет | ID пользовательского словаря произношения |
| `client_task_id` | `string` | Нет | Ключ идемпотентности (дублирует заголовок `Idempotency-Key`) |
| `callback_url` | `string` | Нет | Webhook для уведомления о готовности |

---

## 7. Разметка интонаций BlooTube Voice Markup (Beta)

BlooTube Voice Markup Beta позволяет точно управлять интонациями, паузами и динамикой отдельных фраз внутри текста.

### Поддерживаемые теги:
- **Скорость фразы:** `<speed val="1.2">быстрый текст</speed>` (`0.6` – `1.5`)
- **Громкость фразы:** `<volume val="1.4">громкий фрагмент</volume>` (`0.5` – `2.0`)
- **Эмоция фразы:** `<emotion val="excited">радостная новость</emotion>`
- **Пауза:** `<break time="500ms"/>` (от `50ms` до `5000ms`)
- **Смех и дыхание:** `<laugh/>`

### Пример текста с разметкой:
```xml
Внимание! <speed val="1.1"><emotion val="excited">Отличные новости!</emotion></speed>
<break time="600ms"/>
Мы обновили возможности платформы. <volume val="0.8">Теперь звук звучит ещё чище.</volume>
```

---

## 8. Жизненный цикл, прогресс и скачивание MP3

### Проверка статуса (GET /tasks/{task_id})
```bash
curl -X GET "https://api.apexcorelink.org/voice/api/v1/tasks/TASK_ID" \
  -H "Authorization: Bearer btv_live_YOUR_API_KEY"
```

Ответ готовой задачи:
```json
{
  "ok": true,
  "task_id": "TASK_ID",
  "status": "completed",
  "progress": 100,
  "chunks_completed": 3,
  "total_chunks": 3,
  "duration_ms": 11840,
  "size_bytes": 189440,
  "download_url": "/voice/api/v1/tasks/TASK_ID/download",
  "expires_at": "2026-09-19T21:35:00+00:00"
}
```

### Статусы задачи:
- `queued` — задача ожидает очереди обработки;
- `processing` — выполняется синтез (поле `progress` от 0 до 99%);
- `completed` — синтез завершён, аудио доступно для скачивания;
- `failed` — ошибка синтеза (причина указана в поле `error`);
- `cancelled` — задача отменена пользователем.

### Скачивание готового MP3
```bash
curl -X GET "https://api.apexcorelink.org/voice/api/v1/tasks/TASK_ID/download" \
  -H "Authorization: Bearer btv_live_YOUR_API_KEY" \
  --output "result.mp3"
```
> **Срок хранения файлов (Retention):** Готовый MP3 файл хранится на сервере ровно **5 часов** с момента завершения синтеза. После истечения срока файл автоматически удаляется.

### Отмена задачи (POST /tasks/{task_id}/cancel)
Отменяет задачу в очереди и мгновенно возвращает символы:
```bash
curl -X POST "https://api.apexcorelink.org/voice/api/v1/tasks/TASK_ID/cancel" \
  -H "Authorization: Bearer btv_live_YOUR_API_KEY"
```

---

## 9. История и список задач (GET /tasks)

Позволяет просматривать задачи вашего аккаунта с пагинацией:

```bash
curl -X GET "https://api.apexcorelink.org/voice/api/v1/tasks?status=completed&limit=10&offset=0" \
  -H "Authorization: Bearer btv_live_YOUR_API_KEY"
```

Все активные API-ключи вашего аккаунта имеют полный доступ к просмотру и управлению задачами аккаунта.

---

## 10. Клонирование голоса (POST /clones)

Создает персональный нейроклон по короткому аудиофайлу:

```bash
curl -X POST "https://api.apexcorelink.org/voice/api/v1/clones" \
  -H "Authorization: Bearer btv_live_YOUR_API_KEY" \
  -F "sample_file=@sample_voice.wav" \
  -F "name=Студийный Голос Диктора" \
  -F "gender=male" \
  -F "language=ru"
```

### Особенности и ограничения клонирования:
- **Требования к образцу:** длительность от 5 до 30 секунд, чистая запись без фоновой музыки и шумов, форматы WAV, MP3, M4A, OGG до 16 МБ.
- **Лимиты слотов по тарифам:**
  - **PRO STUDIO:** 1 слот клонирования;
  - **ULTRA VIP:** 3 слота клонирования.
- **Публичный каталог:** После успешного создания голос автоматически публикуется в общем каталоге BlooTube Voice и становится доступен другим пользователям сервиса для синтеза.
- **Удаление клона:** `DELETE https://api.apexcorelink.org/voice/api/v1/clones/VOICE_ID` освобождает слот для создания нового клона.

---

## 11. Словари произношения (/pronunciation-dictionaries)

Словари позволяют автоматически заменять сложные термины, аббревиатуры и профессиональный сленг на понятные диктору транскрипции.

### Создание словаря:
```bash
curl -X POST "https://api.apexcorelink.org/voice/api/v1/pronunciation-dictionaries" \
  -H "Authorization: Bearer btv_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "IT Сленг и бренды",
    "description": "Словарь для озвучки технического контента",
    "entries": [
      {
        "text": "PostgreSQL",
        "phonemes": "постгрэс кью эл",
        "case_sensitive": false,
        "alphabet": "sounds-like"
      },
      {
        "text": "Kubernetes",
        "phonemes": "кубернэтис",
        "case_sensitive": false,
        "alphabet": "sounds-like"
      }
    ]
  }'
```

### Семантика словарей:
- `text` — исходное слово или фраза (до 100 символов);
- `phonemes` — замена или транскрипция (до 250 символов);
- `case_sensitive` — учитывать ли регистр букв (`true` / `false`);
- `alphabet` — тип правила:
  - `sounds-like` — интуитивное написание на русском или латинице;
  - `ipa` — Международный фонетический алфавит.

---

## 12. Лимиты частоты запросов (Rate Limits)

API применяет ограничение частоты запросов скользящим окном для стабильности платформы:

| Тарифный план | Создание задач (`POST /tasks`) | Опрос статуса (`GET /tasks`) | Общие запросы (`GET /voices`, `/me`) |
|---|:---:|:---:|:---:|
| **PRO STUDIO** | 10 запросов / мин | 120 запросов / мин | 60 запросов / мин |
| **ULTRA VIP** | 30 запросов / мин | 240 запросов / мин | 120 запросов / мин |

При превышении лимита возвращается HTTP-статус `429 Too Many Requests`.

---

## 13. Справочник ошибок и коды HTTP

Все ошибки API возвращаются в едином структурированном конверте:

```json
{
  "error": {
    "code": "DAILY_QUOTA_EXCEEDED",
    "message": "Недостаточно суточной квоты символов. Требуется: 15000, доступно: 12000 (лимит 600000).",
    "request_id": "req_8f1b2c3d4e5f6071",
    "details": {
      "required_chars": 15000,
      "remaining_chars": 12000,
      "daily_limit_chars": 600000
    }
  }
}
```

Каждый ответ API сопровождается уникальным идентификатором запроса в заголовке `X-Request-ID` и в поле `request_id`.

| HTTP Статус | Код ошибки (`code`) | Причина и действия разработчика |
|---|---|---|
| **400** | `BAD_REQUEST` | Некорректное тело запроса или пустой текст |
| **400** | `JOB_TEXT_LIMIT_EXCEEDED` | Длина текста превышает лимит тарифа (PRO: 600k, ULTRA: 1.2M) |
| **401** | `UNAUTHORIZED` | API-ключ отсутствует, недействителен или отозван |
| **402** | `DAILY_QUOTA_EXCEEDED` | Исчерпана суточная квота символов. Квота обновляется ежедневно в 00:00 UTC |
| **403** | `FORBIDDEN` | Доступ к Public API разрешён только для тарифов PRO STUDIO и ULTRA VIP |
| **404** | `NOT_FOUND` | Запрашиваемый голос, задача или словарь не найдены |
| **409** | `CONFLICT` | Попытка отменить уже завершённую задачу или повтор с другим телом |
| **413** | `PAYLOAD_TOO_LARGE` | Размер тела запроса превышает допустимый предел |
| **422** | `VALIDATION_ERROR` | Ошибка валидации полей или синтаксиса разметки Markup Beta |
| **429** | `RATE_LIMIT_EXCEEDED` | Превышен лимит вызовов в минуту |
| **503** | `SERVICE_UNAVAILABLE` | Сервер находится на кратковременном техническом обслуживании |

---

## 14. Сквозные сценарии интеграции (Workflows)

### Пример на Python (полный цикл):
```python
import time
import requests

API_KEY = "btv_live_YOUR_API_KEY"
BASE_URL = "https://api.apexcorelink.org/voice/api/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

# 1. Проверка доступной квоты
me = requests.get(f"{BASE_URL}/me", headers=HEADERS).json()
print(f"Тариф: {me['account']['tier_display']}, Остаток квоты: {me['quota']['remaining_chars']} симв.")

# 2. Создание задачи озвучки
payload = {
    "voice_id": "VOICE_ID_FROM_CATALOG",
    "text": "Привет! Это автоматический синтез речи через официальный API BlooTube Voice.",
    "speed": 1.0,
    "volume": 1.0,
    "dsp_speed": 1.0
}
task = requests.post(f"{BASE_URL}/tasks", headers=HEADERS, json=payload).json()
task_id = task["task_id"]
print(f"Задача создана: {task_id}")

# 3. Опрос статуса выполнения
while True:
    st = requests.get(f"{BASE_URL}/tasks/{task_id}", headers=HEADERS).json()
    status = st["status"]
    progress = st.get("progress", 0)
    print(f"Статус: {status} ({progress}%)")
    if status == "completed":
        break
    elif status in ("failed", "cancelled"):
        raise RuntimeError(f"Синтез завершился с ошибкой: {st.get('error')}")
    time.sleep(1.5)

# 4. Скачивание готового MP3 файла
audio_res = requests.get(f"{BASE_URL}/tasks/{task_id}/download", headers=HEADERS)
with open("result.mp3", "wb") as f:
    f.write(audio_res.content)
print("Готово! Аудио сохранено в result.mp3")
```

### Пример на JavaScript / Node.js:
```javascript
const API_KEY = "btv_live_YOUR_API_KEY";
const BASE_URL = "https://api.apexcorelink.org/voice/api/v1";
const headers = { "Authorization": `Bearer ${API_KEY}`, "Content-Type": "application/json" };

async function generateVoice() {
  // 1. Создание задачи
  const createRes = await fetch(`${BASE_URL}/tasks`, {
    method: "POST",
    headers,
    body: JSON.stringify({
      voice_id: "VOICE_ID_FROM_CATALOG",
      text: "Тестовая генерация речи на Node.js.",
      speed: 1.0
    })
  });
  const { task_id } = await createRes.json();
  console.log(`Задача принята: ${task_id}`);

  // 2. Ожидание завершения
  let status = "queued";
  while (status !== "completed") {
    await new Promise(r => setTimeout(r, 1500));
    const poll = await (await fetch(`${BASE_URL}/tasks/${task_id}`, { headers })).json();
    status = poll.status;
    console.log(`Прогресс: ${poll.progress}%`);
    if (status === "failed") throw new Error(poll.error);
  }

  // 3. Скачивание MP3
  const audioBlob = await (await fetch(`${BASE_URL}/tasks/${task_id}/download`, { headers })).blob();
  console.log(`Аудио готово к сохранению (${audioBlob.size} байт)`);
}

generateVoice().catch(console.error);
```

---

## 15. Версионирование

* **v1.0.0 (2026-09-19):** Стабильный контракт API v1.
  - Канонические диапазоны регуляторов: `speed` [0.6, 1.5], `volume` [0.5, 2.0], `dsp_speed` [1.0, 2.0].
  - 7 утверждённых эмоциональных стилей (по умолчанию `null` — нативный тон диктора).
  - Поддержка разметки интонаций BlooTube Voice Markup (Beta).
  - Защита квоты от двойных списаний при повторных запросах, отменах и сетевых сбоях.
  - Срок хранения готовых аудиофайлов: 5 часов.
