Appearance
TOOLS: beszédből szöveg (STT)
Ez a dokumentum az admin TOOLS aszinkron Speech-to-Text API-t írja le. Hosszú hanganyag → átirat (és opcionális SRT / LLM javítás).
Nem ugyanaz, mint a chat mikrofonos STT: 15-chat-transcribe.md (POST /chat/transcribe, sync, max ~25 MB, billing: whisper_stt).
Integration source of truth: OpenAPI / Redoc; eltérés esetén az OpenAPI az irányadó.
Összefoglaló
| TOOLS STT | Chat transcribe (15) | |
|---|---|---|
| Prefix | /api/v1/tools/stt | POST /chat/transcribe |
| Modell | Aszinkron job + poll | Szinkron JSON |
| Méret | max 1 GiB | ~25 MB |
| Billing | whisper_v_to_text (+ opcionális tools_stt_correct) | whisper_stt |
| UI | Admin → TOOLS → Beszédből szöveg | Chat input |
Auth: JWT (Authorization: Bearer …).
Szerepkör: létrehozás / lista / result: EDITOR | TENANT_ADMIN | SYSTEM_ADMIN.
Törlés: csak TENANT_ADMIN | SYSTEM_ADMIN.
Nincs API-key / widget token.
Korlátok: tenantenként max 1 aktív STT job (különben 409). Nincs egyenleg → 402.
Endpointok
| Method | Path | Leírás |
|---|---|---|
| POST | /api/v1/tools/stt/jobs | Job URL-ből (source_url) |
| POST | /api/v1/tools/stt/jobs/upload | Job fájlfeltöltés (multipart) |
| GET | /api/v1/tools/stt/jobs | Lista (q, status, limit, offset) |
| GET | /api/v1/tools/stt/jobs/{job_id} | Státusz / részletek (DB-only, nincs MCP a request szálon) |
| GET | /api/v1/tools/stt/jobs/{job_id}/result | Teljes átirat (409, ha nem COMPLETED) |
| GET | /api/v1/tools/stt/jobs/{job_id}/download.txt | Letöltés (variant=raw|corrected) |
| GET | /api/v1/tools/stt/jobs/{job_id}/download.srt | SRT letöltés |
| POST | /api/v1/tools/stt/jobs/{job_id}/llm-correct | LLM javítás (targets: plain / srt) |
| DELETE | /api/v1/tools/stt/jobs/{job_id} | Törlés (TENANT_ADMIN+) |
Státuszok
PENDING_UPLOAD → QUEUED → MCP_QUEUED → MCP_RUNNING → FINALIZING → COMPLETED | FAILED
LLM javítás után a job mezőin: llm_correct_plain_status / llm_correct_srt_status: idle | running | done | failed.
Aszinkron folyamat
POST …/jobsvagy…/jobs/upload→ azonnali{job_id, status}- Háttér worker: Whisper MCP → transcript mentés → billing (
whisper_v_to_text, kimeneti szöveg) - Kliens: poll
GET …/jobs/{job_id}amígCOMPLETED/FAILED - Eredmény:
GET …/resultvagy download végpontok
Példa: URL-ből job + poll + result
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) create
r = requests.post(
f"{BASE_URL}/api/v1/tools/stt/jobs",
headers=headers,
json={
"source_url": "https://example.com/meeting.mp3",
"title": "Meeting 2026-07-30",
"language": "hu",
},
)
r.raise_for_status()
job_id = r.json()["job_id"]
print("job_id:", job_id)
# 2) poll
while True:
st = requests.get(f"{BASE_URL}/api/v1/tools/stt/jobs/{job_id}", headers=headers)
st.raise_for_status()
body = st.json()
status = body.get("status")
print(status, body.get("progress_pct"), body.get("status_message"))
if status in ("COMPLETED", "FAILED"):
break
time.sleep(3)
# 3) result
if status == "COMPLETED":
res = requests.get(f"{BASE_URL}/api/v1/tools/stt/jobs/{job_id}/result", headers=headers)
res.raise_for_status()
print(res.json().get("text_raw", "")[:500])TypeScript
typescript
const BASE_URL = "https://<your-api-host>";
const JWT = "your-jwt-token";
const headers = {
Authorization: `Bearer ${JWT}`,
"Content-Type": "application/json",
};
const created = await fetch(`${BASE_URL}/api/v1/tools/stt/jobs`, {
method: "POST",
headers,
body: JSON.stringify({
source_url: "https://example.com/meeting.mp3",
title: "Meeting 2026-07-30",
language: "hu",
}),
}).then((r) => r.json());
const jobId = created.job_id as string;
let status = created.status as string;
while (status !== "COMPLETED" && status !== "FAILED") {
await new Promise((r) => setTimeout(r, 3000));
const st = await fetch(`${BASE_URL}/api/v1/tools/stt/jobs/${jobId}`, { headers }).then((r) =>
r.json(),
);
status = st.status;
console.log(status, st.progress_pct);
}
if (status === "COMPLETED") {
const result = await fetch(`${BASE_URL}/api/v1/tools/stt/jobs/${jobId}/result`, {
headers,
}).then((r) => r.json());
console.log(result.text_raw?.slice(0, 500));
}cURL
bash
BASE_URL="https://<your-api-host>"
JWT="your-jwt-token"
# create
curl -sS -X POST "$BASE_URL/api/v1/tools/stt/jobs" \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{"source_url":"https://example.com/meeting.mp3","title":"Meeting","language":"hu"}'
# poll (cseréld a JOB_ID-t)
curl -sS "$BASE_URL/api/v1/tools/stt/jobs/JOB_ID" \
-H "Authorization: Bearer $JWT"
# result
curl -sS "$BASE_URL/api/v1/tools/stt/jobs/JOB_ID/result" \
-H "Authorization: Bearer $JWT"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);
$headers = ["Authorization: Bearer $jwt", "Content-Type: application/json"];
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => $headers,
]);
if ($body !== null) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
}
$raw = curl_exec($ch);
curl_close($ch);
return json_decode($raw, true) ?: [];
}
$created = http_json("POST", "$BASE_URL/api/v1/tools/stt/jobs", $JWT, [
"source_url" => "https://example.com/meeting.mp3",
"title" => "Meeting",
"language" => "hu",
]);
$jobId = $created["job_id"];
do {
sleep(3);
$st = http_json("GET", "$BASE_URL/api/v1/tools/stt/jobs/$jobId", $JWT);
$status = $st["status"] ?? "";
} while ($status !== "COMPLETED" && $status !== "FAILED");
if ($status === "COMPLETED") {
$res = http_json("GET", "$BASE_URL/api/v1/tools/stt/jobs/$jobId/result", $JWT);
echo substr($res["text_raw"] ?? "", 0, 500), "\n";
}Feltöltés (multipart)
bash
curl -sS -X POST "$BASE_URL/api/v1/tools/stt/jobs/upload" \
-H "Authorization: Bearer $JWT" \
-F "file=@./meeting.mp3" \
-F "title=Meeting upload" \
-F "language=hu"LLM javítás (opcionális)
bash
curl -sS -X POST "$BASE_URL/api/v1/tools/stt/jobs/JOB_ID/llm-correct" \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{"targets":["plain","srt"]}'Billing: tools_stt_correct.
Hibák
| Kód | Jelentés |
|---|---|
| 401 | Hiányzó / érvénytelen JWT |
| 403 | Nincs jogosultság (pl. DELETE EDITOR-ként) |
| 402 | Nincs token egyenleg |
| 409 | Van már aktív job / result nem COMPLETED |
| 413 | Túl nagy fájl (>1 GiB) |
| 502 | MCP / külső hiba (pl. voices / worker) |
Kapcsolódó
- 15-chat-transcribe.md – sync chat STT
- 57-tools-tts.md – szövegből beszéd
- Admin UI: TOOLS → Beszédből szöveg
- Séma:
scripts/migration/021_tools_stt.sql