Zum Inhalt
Lumean API

Quickstart: from zero to mp3

Five steps from an empty terminal to a downloaded file — voice, template, order, waiting, link.

Übersetzung in Arbeit

Diese Seite ist noch nicht in Ihre Sprache übersetzt — die Fassung unten ist auf English. Text und Codebeispiele sind dieselben.

Speech synthesis in Lumean is a pipeline of five links, and each link takes an ID from the previous one's response: voice → template → order → waiting → file. No link can be skipped: the voice is set only through a template (there is no orders.voice_id field), and the result is delivered only as a temporary link from POST /storage/url — the order holds paths, not URLs.

Die Pipeline der öffentlichen APIAcht Schritte vom Schlüssel bis zum Link auf die fertige Datei: Schlüssel, Rechte, Stimme, Vorlage, Auftrag, Abschnitte, Dateien, Link.1. SchlüsselX-API-KEY2. Rechteorders.write3. StimmeGET /voices4. VorlagePOST /templates5. AuftragPOST /orders6. AbschnitteGET /orders/{order}7. Dateienresult.files[]8. LinkPOST /storage/url

What you need first

An API key with the voices.read, templates.write, orders.write, and orders.download scopes. You create it in My API keys; every request uses the same header, X-API-KEY.

Stolperfalle

The built-in automation preset does not include templates.write (only templates.read), so you cannot complete this walkthrough with it: step 2 will return 403. Use the full preset, or add templates.write manually when you create the key.

Vorsicht

Step 3 creates a real order: it consumes your subscription quota and is billed like any other. You can cancel an order after it is created (POST /orders/{order}/cancel), but what was spent on completed chunks is not refunded — start with one short phrase, not a book chapter.

Durchgängiges Szenario

Variablen

Die Schritte laufen mit Ihrem Schlüssel. Ohne Schlüssel gibt es nur den Code — kopieren geht trotzdem.

  1. 1

    Stimme wählen

    Suchen Sie eine Stimme im Katalog und merken Sie sich ihre voice_id — die Vorlage braucht sie.

    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'
    In der Referenz öffnen
  2. 2

    Vorlage erstellen

    Die Stimme wird ausschließlich über die Vorlage gesetzt: voice_id gehört in 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
          }
        }
      }
    }'
    In der Referenz öffnen
  3. 3

    Auftrag erstellen

    Der Text gehört in das oberste Feld input_text, die Vorlage in template_id. Die Antwort ist 201 mit Status created.

    Dieser Schritt erzeugt einen echten Auftrag und verbraucht Tokens Ihres Abonnements.

    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."
    }'
    In der Referenz öffnen
  4. 4

    Auf das Ergebnis warten

    Aufträge sind asynchron: Status abfragen oder per WebSocket zuhören. partially_completed ist NICHT terminal.

    curl -X GET 'https://api.lumean.app/api/public/orders/{{order_id}}' \
      -H 'Accept: application/json' \
      -H 'X-API-KEY: YOUR_API_KEY'
    In der Referenz öffnen
  5. 5

    Link zur Datei holen

    result.files[] sind Pfade. Den Download-Link liefert 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
    }'
    In der Referenz öffnen

The full script

A ready-made run from voice to file. You need curl and jq; substitute your own KEY.

#!/usr/bin/env bash
set -euo pipefail

BASE=https://api.lumean.app/api/public
KEY=<your_api_key>
AUTH=(-H "X-API-KEY: $KEY" -H "Content-Type: application/json")

# 1. Voice: take the first voice_id from the ElevenLabs public library.
#    External provider catalogs are wrapped in data.voices[]; pages start at ZERO.
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. A TTS template with this voice. tts_settings.mode is required,
#    language_code (ISO-639-1) is optional.
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. An order from the template. The text goes in top-level input_text, NOT in 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" — this response has no result, and it cannot have one

# 4. Wait until it is ready. Terminal statuses: completed, result_delivered,
#    failed, compensated, cancelled. partially_completed is NOT terminal.
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 "order failed"; exit 1 ;;
  esac
  sleep 5
done

# 5. File: result.files[] are PATHS. Exchange the path for a temporary link and download it.
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

What is easy to get wrong here

PitfallHow it actually works
Looking for voice_id in the order bodyThe voice lives in the template's config.tts_settings.voice_id; POST /orders has no such field
Putting the text in task_data.textFor template-based TTS, the text goes in the top-level input_text
Treating data.result.files[] as linksThey are paths; a link is issued by POST /storage/url, and it is short-lived
Waiting for completed foreverpartially_completed is not a terminal status: some chunks are done, others are waiting for your decision
Pagination of provider catalogsFor ElevenLabs and HeyGen, page is counted from zero; for regular API lists, from one
Leaving the file “for later”Order storage is purged according to retention (by default, 7 days after a terminal status), while the order keeps showing the paths, now dead

If you get an error instead of 201

Three codes come up at step 3 more often than others, and each one is handled differently.

402402 — payment required
Was passiert ist
The order was not created and no money was charged. The code is returned by `POST /orders` and `POST /orders/{order}/retry` — they go through the same billing flow. The body always contains `reason`, and that is what determines whether this is an error or an offer to top up.
Was jetzt zu tun ist
Branch on `reason`, not on `message`: message wording changes without notice and is not an error code. Do not retry blindly: a retry without confirmation returns a fresh 402 with a new `quote_token`, while a blind retry WITH confirmation charges money without the user knowing.
Code-Seite öffnen

402 is not a rejection but a payment fork: payg_topup_required brings the top-up price and a quote_token, which you must send back together with confirm_payg_topup: true. A blind retry here is either useless or charges money without the user's knowledge — see LMC, quotas and PAYG.

429 is five different limits under one code; they are told apart by reason and by the presence of Retry-After (Limits and the 429 code). A 422 without errors but with reason is a domain rejection: the request shape is not the problem, and repeating the same body will get the same response.

Next steps

Diese Seite einer KI geben

.md öffnenllm.md

Aktualisiert 04.09.2026 · Spezifikation 0.0.1