Быстрый старт: от нуля до mp3
Пять шагов от пустого терминала до скачанного файла — голос, шаблон, заказ, ожидание, ссылка.
Синтез речи в Lumean устроен как конвейер из пяти звеньев, и каждое следующее берёт
идентификатор из ответа предыдущего: голос → шаблон → заказ → ожидание → файл. Ни одно звено
не пропускается: голос задаётся только через шаблон (поля orders.voice_id не существует),
а результат отдаётся только временной ссылкой из POST /storage/url — в заказе лежат пути,
а не URL.
Что нужно заранее
Ключ с правами voices.read, templates.write, orders.write, orders.download. Создаётся
в разделе Мои API-ключи; заголовок у всех запросов один — X-API-KEY.
Ловушка
Готовый пресет automation не включает templates.write (только templates.read), поэтому
пройти этот сценарий целиком на нём нельзя: шаг 2 вернёт 403. Берите пресет full либо
добавьте templates.write вручную при создании ключа.
Осторожно
Шаг 3 создаёт настоящий заказ: он расходует квоту подписки и тарифицируется, как любой
другой. Отменить уже созданный заказ можно (POST /orders/{order}/cancel), но потраченное
на выполненные чанки не возвращается — начинайте с одной короткой фразы, а не с главы книги.
Сквозной сценарий
Шаги выполняются вашим ключом. Без ключа доступен только код — его можно скопировать.
# 1. Выбрать голос → voice_id
curl -X GET 'https://api.lumean.app/api/public/voices/elevenlabs/library?page=0&page_size=20' \
-H 'Accept: application/json' \
-H 'X-API-KEY: YOUR_API_KEY'
# 2. Создать шаблон → template_id
curl -X POST 'https://api.lumean.app/api/public/templates' \
-H 'Accept: application/json' \
-H 'X-API-KEY: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"service_key": "elevenlabs",
"name": "API quickstart",
"config": {
"tts_settings": {
"mode": "mode_v1",
"model_id": "eleven_multilingual_v2",
"voice_id": "{{voice_id}}",
"advanced_voice_settings": true,
"voice_settings": {
"stability": 0.5,
"similarity_boost": 0.75,
"use_speaker_boost": true,
"speed": 1.0
}
}
}
}'
# 3. Создать заказ → order_id
curl -X POST 'https://api.lumean.app/api/public/orders' \
-H 'Accept: application/json' \
-H 'X-API-KEY: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"template_id": "{{template_id}}",
"input_text": "Hello from the Lumean public API."
}'
# 4. Дождаться результата → path
curl -X GET 'https://api.lumean.app/api/public/orders/{{order_id}}' \
-H 'Accept: application/json' \
-H 'X-API-KEY: YOUR_API_KEY'
# 5. Получить ссылку на файл → url
curl -X POST 'https://api.lumean.app/api/public/storage/url' \
-H 'Accept: application/json' \
-H 'X-API-KEY: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"path": "{{path}}",
"download": true
}'- 1
Выбрать голос
Найдите голос в каталоге и запомните его voice_id — он понадобится шаблону.
curl -X GET 'https://api.lumean.app/api/public/voices/elevenlabs/library?page=0&page_size=20' \ -H 'Accept: application/json' \ -H 'X-API-KEY: YOUR_API_KEY' - 2
Создать шаблон
Голос задаётся только шаблоном: voice_id кладётся в config.tts_settings.
curl -X POST 'https://api.lumean.app/api/public/templates' \ -H 'Accept: application/json' \ -H 'X-API-KEY: YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "service_key": "elevenlabs", "name": "API quickstart", "config": { "tts_settings": { "mode": "mode_v1", "model_id": "eleven_multilingual_v2", "voice_id": "{{voice_id}}", "advanced_voice_settings": true, "voice_settings": { "stability": 0.5, "similarity_boost": 0.75, "use_speaker_boost": true, "speed": 1.0 } } } }' - 3
Создать заказ
Текст идёт в top-level input_text, шаблон — в template_id. В ответе 201 и статус created.
Этот шаг создаст настоящий заказ и спишет токены вашей подписки.
curl -X POST 'https://api.lumean.app/api/public/orders' \ -H 'Accept: application/json' \ -H 'X-API-KEY: YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "template_id": "{{template_id}}", "input_text": "Hello from the Lumean public API." }' - 4
Дождаться результата
Заказ асинхронный: опрашивайте статус или слушайте WebSocket. partially_completed НЕ терминальный.
curl -X GET 'https://api.lumean.app/api/public/orders/{{order_id}}' \ -H 'Accept: application/json' \ -H 'X-API-KEY: YOUR_API_KEY' - 5
Получить ссылку на файл
result.files[] — это пути. Ссылку на скачивание выдаёт POST /storage/url.
curl -X POST 'https://api.lumean.app/api/public/storage/url' \ -H 'Accept: application/json' \ -H 'X-API-KEY: YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "path": "{{path}}", "download": true }'
Весь скрипт целиком
Готовый прогон от голоса до файла. Нужен curl и jq; KEY подставьте свой.
#!/usr/bin/env bash
set -euo pipefail
BASE=https://api.lumean.app/api/public
KEY=<ваш_api_ключ>
AUTH=(-H "X-API-KEY: $KEY" -H "Content-Type: application/json")
# 1. Голос: берём первый voice_id из публичной библиотеки ElevenLabs.
# Обёртка каталогов внешних провайдеров — data.voices[], страницы с НУЛЯ.
VOICE_ID=$(curl -s "$BASE/voices/elevenlabs/library?page=0&page_size=20" \
-H "X-API-KEY: $KEY" | jq -r '.data.voices[0].voice_id')
# 2. Шаблон TTS с этим голосом. tts_settings.mode обязателен,
# language_code (ISO-639-1) — опционален.
TEMPLATE_UUID=$(curl -s -X POST "$BASE/templates" "${AUTH[@]}" -d '{
"service_key": "elevenlabs",
"name": "My TTS",
"config": {
"tts_settings": {
"mode": "mode_v1",
"model_id": "eleven_multilingual_v2",
"voice_id": "'"$VOICE_ID"'",
"advanced_voice_settings": true,
"voice_settings": {
"stability": 0.5, "similarity_boost": 0.75,
"use_speaker_boost": true, "speed": 1.0
}
}
}
}' | jq -r '.data.id')
# 3. Заказ по шаблону. Текст — в top-level input_text, НЕ в task_data.
ORDER_UUID=$(curl -s -X POST "$BASE/orders" "${AUTH[@]}" -d '{
"template_id": "'"$TEMPLATE_UUID"'",
"input_text": "Привет! Это тестовая озвучка через Lumean API."
}' | jq -r '.data.id')
# → status: "created" — результата в этом ответе нет и быть не может
# 4. Ждём готовности. Терминальные статусы: completed, result_delivered,
# failed, compensated, cancelled. partially_completed терминальным НЕ является.
while :; do
STATUS=$(curl -s "$BASE/orders/$ORDER_UUID" -H "X-API-KEY: $KEY" | jq -r '.data.status')
echo "status: $STATUS"
case "$STATUS" in
completed|partially_completed|result_delivered) break ;;
failed|cancelled|compensated) echo "заказ не выполнен"; exit 1 ;;
esac
sleep 5
done
# 5. Файл: result.files[] — это ПУТИ. Меняем путь на временную ссылку и качаем.
PATHNAME=$(curl -s "$BASE/orders/$ORDER_UUID" -H "X-API-KEY: $KEY" \
| jq -r '.data.result.files[0]')
URL=$(curl -s -X POST "$BASE/storage/url" "${AUTH[@]}" \
-d '{ "path": "'"$PATHNAME"'", "download": true }' | jq -r '.data.url')
curl -sL "$URL" -o result.mp3Что здесь легко сделать неправильно
| Ловушка | Как на самом деле |
|---|---|
Искать voice_id в теле заказа | Голос живёт в config.tts_settings.voice_id шаблона; у POST /orders такого поля нет |
Класть текст в task_data.text | Для TTS по шаблону текст — в top-level input_text |
Считать data.result.files[] ссылками | Это пути; ссылку выдаёт POST /storage/url и живёт она недолго |
Ждать completed вечно | partially_completed — не терминальный статус: часть чанков готова, часть ждёт вашего решения |
| Пагинация каталогов провайдеров | У ElevenLabs и HeyGen page считается с нуля, у обычных списков API — с единицы |
| Оставить файл «на потом» | Storage заказа чистится по ретенции (по умолчанию 7 дней после терминального статуса), а пути в заказе продолжают показываться мёртвыми |
Если вместо 201 пришла ошибка
Три кода на шаге 3 встречаются чаще прочих, и лечатся они по-разному.
- Что произошло
- Заказ не создан и деньги не списаны. Код приходит на `POST /orders` и на `POST /orders/{order}/retry` — они проходят один и тот же биллинг-flow. В теле обязателен `reason`, и именно от него зависит, ошибка это или предложение доплатить.
- Что сделать прямо сейчас
- Ветвиться по `reason`, а не по `message`: формулировки сообщений меняются без предупреждения и кодом ошибки не являются. Не ретраить вслепую: повтор без подтверждения выдаст свежий 402 с новым `quote_token`, а слепой повтор С подтверждением спишет деньги без ведома пользователя.
402 — не отказ, а развилка оплаты: payg_topup_required приносит цену доплаты и quote_token,
который надо вернуть вместе с confirm_payg_topup: true. Слепой ретрай здесь либо бесполезен,
либо спишет деньги без ведома пользователя — см. LMC, квоты и PAYG.
429 — пять разных ограничений под одним кодом; различаются по reason и наличию Retry-After
(Лимиты и код 429). 422 без errors, но с reason — доменный
отказ: форма запроса ни при чём, повтор того же тела даст тот же ответ.
Что дальше
- Ключ, права и заголовки — одиннадцать прав, wildcard и три пресета.
- Асинхронная модель — девять статусов и что считать завершением.
- Realtime — те же статусы событиями, без опроса.
- Шаблоны — конфиг сервиса и
GET /templates/config-options. - Текст озвучки — паузы, разметка и что из неё не тарифицируется.
- Файлы и хранение — субтитры в
result.service_files[]и ретенция. - Соглашения — конверт ответа и 422 вне его.
- Пагинация — две базы отсчёта страниц.
- Голоса — три каталога и где брать
voice_id. - Лимиты и код 429 — пять ограничений под одним кодом.
- Токены, квоты, LMC и PAYG — за что и чем вы платите.
- Ретраи и идемпотентность — четыре разных «повтора».
- Операции сценария: POST /orders, POST /templates, POST /storage/url.
Скормить страницу ИИ
Обновлено 04.09.2026 · спека 0.0.1