Skip to content

TOOLS: szövegből beszéd (TTS)

Ez a dokumentum az admin TOOLS aszinkron Text-to-Speech API-t írja le. Szöveg → WAV hang (MCP GLC-TTS). Hangpresetek: magyar és angol.

Integration source of truth: OpenAPI / Redoc.


Összefoglaló

Prefix/api/v1/tools/tts
AuthJWT Bearer
Szerepkörcreate/list/audio: EDITOR+; DELETE: TENANT_ADMIN+
Billingglc_text_to_voice (bemeneti szöveg tokenizálás)
Korlátmax 1 aktív TTS job / tenant (409); egyenleg 402
Szöveg1–100 000 karakter
Speed0.3–2.0 (default 1.0)

Endpointok

MethodPathLeírás
GET/api/v1/tools/tts/voicesHanglista (language?, refresh?)
POST/api/v1/tools/tts/jobsÚj job
GET/api/v1/tools/tts/jobsLista
GET/api/v1/tools/tts/jobs/{job_id}Státusz (DB-only)
GET/api/v1/tools/tts/jobs/{job_id}/audioWAV letöltés (ha kész)
DELETE/api/v1/tools/tts/jobs/{job_id}Törlés (TENANT_ADMIN+)

Státuszok

QUEUEDMCP_QUEUEDMCP_RUNNINGFINALIZINGCOMPLETED | FAILED

Create body

json
{
  "text": "Szöveg, amit fel szeretnél olvastatni.",
  "voice_id": "pattila",
  "speed": 1.0,
  "title": "Demo",
  "language": "hu"
}

A voice_id a GET /voices listából jön (pl. magyar / angol presetek). A nyelv tipikusan a hangpresetet követi.


Példa: hangok → job → poll → audio

Python

python
import time
import requests

BASE_URL = "https://<your-api-host>"
JWT = "your-jwt-token"
headers = {"Authorization": f"Bearer {JWT}", "Content-Type": "application/json"}

# 1) voices
voices = requests.get(
    f"{BASE_URL}/api/v1/tools/tts/voices",
    headers=headers,
    params={"refresh": "1"},
).json()
voice_id = voices.get("default_voice_id") or voices["voices"][0]["id"]
print("voice_id:", voice_id)

# 2) create
r = requests.post(
    f"{BASE_URL}/api/v1/tools/tts/jobs",
    headers=headers,
    json={
        "text": "Üdvözöljük a GLC-RAG szövegből beszéd demójában.",
        "voice_id": voice_id,
        "speed": 1.0,
        "title": "Demo TTS",
        "language": "hu",
    },
)
r.raise_for_status()
job_id = r.json()["job_id"]

# 3) poll
while True:
    st = requests.get(f"{BASE_URL}/api/v1/tools/tts/jobs/{job_id}", headers=headers).json()
    status = st.get("status")
    print(status, st.get("progress_pct"))
    if status in ("COMPLETED", "FAILED"):
        break
    time.sleep(2)

# 4) download WAV
if status == "COMPLETED":
    audio = requests.get(
        f"{BASE_URL}/api/v1/tools/tts/jobs/{job_id}/audio",
        headers={"Authorization": f"Bearer {JWT}"},
    )
    audio.raise_for_status()
    with open("out.wav", "wb") as f:
        f.write(audio.content)
    print("saved out.wav", len(audio.content), "bytes")

TypeScript

typescript
const BASE_URL = "https://<your-api-host>";
const JWT = "your-jwt-token";
const headers = {
  Authorization: `Bearer ${JWT}`,
  "Content-Type": "application/json",
};

const voices = await fetch(`${BASE_URL}/api/v1/tools/tts/voices?refresh=1`, {
  headers,
}).then((r) => r.json());
const voiceId = voices.default_voice_id ?? voices.voices[0].id;

const created = await fetch(`${BASE_URL}/api/v1/tools/tts/jobs`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    text: "Hello from GLC-RAG text-to-speech.",
    voice_id: voiceId,
    speed: 1.0,
    title: "Demo EN",
    language: "en",
  }),
}).then((r) => r.json());

let status = created.status as string;
const jobId = created.job_id as string;
while (status !== "COMPLETED" && status !== "FAILED") {
  await new Promise((r) => setTimeout(r, 2000));
  const st = await fetch(`${BASE_URL}/api/v1/tools/tts/jobs/${jobId}`, { headers }).then((r) =>
    r.json(),
  );
  status = st.status;
}

if (status === "COMPLETED") {
  const blob = await fetch(`${BASE_URL}/api/v1/tools/tts/jobs/${jobId}/audio`, {
    headers: { Authorization: `Bearer ${JWT}` },
  }).then((r) => r.blob());
  console.log("audio bytes", blob.size);
}

cURL

bash
BASE_URL="https://<your-api-host>"
JWT="your-jwt-token"

curl -sS "$BASE_URL/api/v1/tools/tts/voices?refresh=1" \
  -H "Authorization: Bearer $JWT"

curl -sS -X POST "$BASE_URL/api/v1/tools/tts/jobs" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{"text":"Üdvözlet a demóból.","voice_id":"VOICE_ID","speed":1.0,"language":"hu"}'

curl -sS "$BASE_URL/api/v1/tools/tts/jobs/JOB_ID" \
  -H "Authorization: Bearer $JWT"

curl -sS "$BASE_URL/api/v1/tools/tts/jobs/JOB_ID/audio" \
  -H "Authorization: Bearer $JWT" \
  -o out.wav

PHP

php
<?php
$BASE_URL = "https://<your-api-host>";
$JWT = "your-jwt-token";

function http_json(string $method, string $url, string $jwt, ?array $body = null): array {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CUSTOMREQUEST => $method,
        CURLOPT_HTTPHEADER => [
            "Authorization: Bearer $jwt",
            "Content-Type: application/json",
        ],
    ]);
    if ($body !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
    }
    $raw = curl_exec($ch);
    curl_close($ch);
    return json_decode($raw, true) ?: [];
}

$voices = http_json("GET", "$BASE_URL/api/v1/tools/tts/voices?refresh=1", $JWT);
$voiceId = $voices["default_voice_id"] ?? ($voices["voices"][0]["id"] ?? null);

$created = http_json("POST", "$BASE_URL/api/v1/tools/tts/jobs", $JWT, [
    "text" => "Üdvözlet a demóból.",
    "voice_id" => $voiceId,
    "speed" => 1.0,
    "language" => "hu",
]);
$jobId = $created["job_id"];

do {
    sleep(2);
    $st = http_json("GET", "$BASE_URL/api/v1/tools/tts/jobs/$jobId", $JWT);
    $status = $st["status"] ?? "";
} while ($status !== "COMPLETED" && $status !== "FAILED");

if ($status === "COMPLETED") {
    $ch = curl_init("$BASE_URL/api/v1/tools/tts/jobs/$jobId/audio");
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => ["Authorization: Bearer $JWT"],
    ]);
    $bin = curl_exec($ch);
    curl_close($ch);
    file_put_contents("out.wav", $bin);
    echo "saved out.wav\n";
}

Hibák

KódJelentés
401 / 403Auth / szerepkör
402Nincs egyenleg
409Aktív job már fut
404Audio még nincs / job hiányzik
502Hanglista / MCP hiba

Kapcsolódó

  • 56-tools-stt.md – beszédből szöveg
  • Admin UI: TOOLS → Szövegből beszéd
  • Séma: scripts/migration/022_tools_tts.sql
  • Marketing: /tools-beszed