HiAPI
Blog

Tutorial

So rufst du gemini-3.1-flash-tts auf HiAPI auf: curl, Python und eine lauffähige Anfrage

Oct 31, 2026
深靛蓝色背景上多层嵌套的宽箭头依次向右上方推进,箭头前缘为杏橙色,构成规整的信号流示意图形,这是文章的封面图。

Was gemini-3.1-flash-tts auf HiAPI für dich tun kann

gemini-3.1-flash-tts ist ein Text-zu-Sprache-Modell, das über die einheitliche API von HiAPI bereitgestellt wird. Du sendest Text und eine Sprachkonfiguration, und die Plattform liefert das erzeugte Audio zurück. Da es über eine einzige, konsistente Schnittstelle bereitgestellt wird, musst du nicht für jedes Modell eine eigene Integration bauen – dieselben Authentifizierungs-Header, dieselbe Basis-URL und dasselbe asynchrone Auftragsmuster gelten für alle TTS-Modelle der Plattform.

Dieses Modell ist die richtige Wahl, wenn du Folgendes brauchst:

  • Narration mit mehreren Sprechern. Skripte, Dialoge oder Inhalte im Podcast-Stil, bei denen verschiedene Abschnitte wie unterschiedliche Stimmen klingen sollen.
  • Schnelle Bearbeitung. Die flash-Reihe ist auf Generierung mit niedriger Latenz ausgelegt, was besonders für interaktive Anwendungen oder Batch-Aufträge mit engem SLA wichtig ist.
  • Vorhersehbare Integrationsoberfläche. Eine einzige Anforderungsform deckt alles ab, von einer einzelnen Textzeile bis hin zu Szenarien mit mehreren Sprechern.

Wenn deine Anwendung bereits andere HiAPI-Modelle aufruft, erfordert das Hinzufügen von Sprachfunktionen nur das Ersetzen der Modellkennung und die Anpassung des Anfragetexts – kein neues SDK und kein neuer Ablauf für Anmeldedaten.

Voraussetzungen und Authentifizierung einrichten

Bevor du den ersten Aufruf machst, stelle sicher, dass du Folgendes hast:

  1. Ein HiAPI-Konto und einen API-Schlüssel. Erzeuge den Schlüssel in der Konsole. Behandle ihn als geheim – committe ihn nicht in die Versionsverwaltung.
  2. Die HiAPI-Basis-URL. Alle Anfragen gehen an denselben Host; nur der Pfad unterscheidet sich je Endpunkt.
  3. Ein Tool zum Senden von HTTP-Anfragen. curl für schnelle Tests sowie Python 3.9+ mit der Bibliothek requests für Skripte.

Die Authentifizierung erfolgt über ein Bearer-Token im Header Authorization:

Authorization: Bearer $HIAPI_API_KEY

Speichere den Schlüssel in einer Umgebungsvariable statt ihn fest zu kodieren:

export HIAPI_API_KEY="your_key_here"

Jeder unten beschriebene Endpunkt – Auftrag übermitteln, Status prüfen und Datei abrufen – verwendet denselben Header. Wenn du ein 401 erhältst, fehlt der Header, er ist falsch formatiert oder der Schlüssel wurde widerrufen. Rotiere den Schlüssel in der Konsole, statt einen einzigen Schlüssel über mehrere Umgebungen hinweg zu teilen.

Anfragetext für Sprache mit mehreren Sprechern erstellen

Der Anfragetext ist JSON. Mindestens müssen die Modellkennung und die Eingabe enthalten sein. Für Ausgaben mit mehreren Sprechern fügst du eine Sprecherkonfiguration hinzu, die benannte Sprecher Stimmen zuordnet, und markierst den Eingabetext mit Sprecher-Tags.

Ein typischer Anfragetext sieht so aus:

{
  "model": "gemini-3.1-flash-tts",
  "input": {
    "text": "[Host] Welcome back to the show. [Guest] Thanks for having me.",
    "multi_speaker": true,
    "speakers": [
      { "name": "Host", "voice": "voice_a" },
      { "name": "Guest", "voice": "voice_b" }
    ]
  }
}

Wichtige Stolperfallen:

  • Sprechernamen müssen exakt übereinstimmen. Der name im speakers-Array muss genau mit dem im Text verwendeten Tag übereinstimmen (in diesem Beispiel in eckigen Klammern). Abweichende Groß-/Kleinschreibung ist die häufigste Ursache für fehlgeschlagenes Rendering mit mehreren Sprechern.
  • Jedes Tag muss deklariert sein. Wenn der Text [Narrator] erwähnt, aber kein Sprecher mit name: "Narrator" definiert ist, wird die Anfrage abgelehnt.
  • Sprachkennungen stammen aus dem Stimmenkatalog der Plattform. Verwende die von HiAPI bereitgestellten Kennungen, statt eigene zu erfinden. Bei Aufträgen mit einem einzelnen Sprecher lässt du multi_speaker und speakers weg und setzt stattdessen ein einzelnes Feld voice.
  • Text wird als einzelner String gesendet. Lange Skripte sind kein Problem, aber beachte die auf der Plattform dokumentierten Limits pro Anfrage.

Nachdem der Anfragetext die Validierung bestanden hat, wird der Auftrag angenommen und eine Auftragskennung zurückgegeben, die du zum Polling verwendest.

Mit curl ausführen

Speichere den obigen Anfragetext als payload.json und übermittle ihn dann:

curl -X POST "$HIAPI_BASE_URL/v1/audio/speech/jobs" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d @payload.json

Die Antwort enthält ein Auftragsobjekt mit den Feldern id und status (normalerweise queued oder processing):

{ "id": "job_abc123", "status": "queued" }

Um den Fortschritt zu prüfen, rufe den Auftrag anhand der ID ab:

curl "$HIAPI_BASE_URL/v1/audio/speech/jobs/job_abc123" \
  -H "Authorization: Bearer $HIAPI_API_KEY"

Wenn status zu succeeded wird, enthält die Antwort eine Audiodateireferenz (URL oder Datei-ID), die du über eine nachfolgende Anfrage herunterladen kannst – siehe den Abschnitt zum Polling weiter unten. Wenn der Auftrag fehlschlägt, ist status gleich failed und ein Feld error gibt den Grund an.

Für schnelle Experimente kannst du die Datei überspringen und das JSON direkt inline angeben:

curl -X POST "$HIAPI_BASE_URL/v1/audio/speech/jobs" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"gemini-3.1-flash-tts","input":{"text":"Hello from HiAPI.","voice":"voice_a"}}'

Mit Python ausführen

Die Python-Version verwendet requests und eine kleine Hilfsfunktion, damit die Polling-Schleife lesbar bleibt. Der Anfragetext ist identisch mit dem curl-Beispiel.

import os
import time
import requests

API_KEY = os.environ["HIAPI_API_KEY"]
BASE_URL = os.environ["HIAPI_BASE_URL"]
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

payload = {
    "model": "gemini-3.1-flash-tts",
    "input": {
        "text": "[Host] Welcome back to the show. [Guest] Thanks for having me.",
        "multi_speaker": True,
        "speakers": [
            {"name": "Host", "voice": "voice_a"},
            {"name": "Guest", "voice": "voice_b"},
        ],
    },
}

resp = requests.post(
    f"{BASE_URL}/v1/audio/speech/jobs",
    headers={**HEADERS, "Content-Type": "application/json"},
    json=payload,
    timeout=30,
)
resp.raise_for_status()
job = resp.json()
job_id = job["id"]
print("submitted", job_id)

while True:
    r = requests.get(f"{BASE_URL}/v1/audio/speech/jobs/{job_id}", headers=HEADERS, timeout=30)
    r.raise_for_status()
    status = r.json()
    if status["status"] in ("succeeded", "failed"):
        break
    time.sleep(2)

if status["status"] == "failed":
    raise RuntimeError(status.get("error"))

print("audio ready:", status["output"])

Hinweise:

  • Timeouts sind wichtig. Setze für jede Anfrage explizit ein Timeout; eine hängende Polling-Schleife ist schlimmer als eine fehlgeschlagene.
  • Nicht zu häufig pollen. Ein Abstand von zwei Sekunden ist für kurze Skripte angemessen; bei langen Skripten solltest du das Intervall erhöhen.
  • Anfragetext in eine Funktion packen. Im echten Code solltest du Text, Sprecher und Stimme parametrisieren, damit du dieselbe Übermittlungslogik für Aufträge mit einem einzelnen Sprecher wiederverwenden kannst.

Asynchrone Aufträge pollen und Audio herunterladen

Die Sprachgenerierung ist asynchron: Du übermittelst einen Auftrag und prüfst dann den Status, bis der Auftrag einen Endzustand erreicht. Es gibt zwei Endzustände – succeeded und failed. Alle anderen Zustände solltest du als „weiter warten“ behandeln.

Ein robustes Polling-Programm sollte:

  1. Die Gesamtwartezeit begrenzen. Selbst ein schnelles Modell kann hinter anderer Arbeit in der Warteschlange stehen. Höre nach einer angemessenen Obergrenze auf und gib die Auftrags-ID aus, damit der Aufrufer erneut versuchen kann.
  2. Exponentielles Backoff verwenden. Beginne mit ein bis zwei Sekunden und verdopple das Intervall schrittweise bis zu einer Obergrenze. So vermeidest du bei langen Aufträgen eine übermäßige Belastung der API.
  3. Fehler explizit behandeln. Wenn status == "failed", lies das Feld error und protokolliere es – es weist meist auf ein Problem im Anfragetext hin (nicht deklarierter Sprecher, leerer Text, nicht unterstützte Stimme).

Wenn der Auftrag erfolgreich ist, enthält die Statusantwort eine Ausgabereferenz. Lade sie mit denselben Authentifizierungs-Headern herunter:

out = status["output"]
audio = requests.get(out["url"], headers=HEADERS, timeout=60)
audio.raise_for_status()
with open("narration.wav", "wb") as f:
    f.write(audio.content)

Wenn die Antwort eine Datei-ID statt einer URL zurückgibt, rufe sie über den entsprechenden Datei-Endpunkt auf HiAPI ab. Speichere die ursprüngliche Auftrags-ID zusammen mit der gespeicherten Datei – nur so kannst du eine schlechte Rendering-Ausgabe später zuverlässig ihrer Anfrage zuordnen.

Abrechnung nach Zeichen verstehen

gemini-3.1-flash-tts auf HiAPI wird nach der Zeichenzahl des eingegebenen Textes abgerechnet. Es gibt keine Komponente pro Anfrage oder pro Minute, die du modellieren müsstest – die Auftragskosten skalieren mit der Textmenge, die du sendest, was die Schätzung einfach macht: Gesamtzeichenzahl aller Skripte multipliziert mit dem aktuellen Preis pro Zeichen.

Praktische Auswirkungen:

  • Vor dem Livegang schätzen. Summiere deine erwartete monatliche Textmenge und gleiche sie mit dem aktuellen Tarif ab, der im Preisbereich angezeigt wird. Kodiere den Tarif nicht fest im Code; lies ihn zur Build-Zeit von der Plattform oder speichere ihn in der Konfiguration.
  • Lange Inhalte dominieren die Kosten. Eine zehnminütige Narration besteht überwiegend aus Textkosten. Wenn du Hörbücher oder Kursmaterial erzeugst, modelliere zuerst das Volumen.
  • Wiederholungen verursachen Kosten. Aufträge, die nach der Generierung fehlschlagen, können je nach Fehlermuster trotzdem abgerechnet werden. Validiere clientseitig vor dem Übermitteln – prüfe, dass jedes Sprecher-Tag deklariert ist und der Text nicht leer ist.
  • Aktiv cachen. Wenn dasselbe Skript wiederholt gerendert wird (z. B. für Demos oder Test-Fixtures), speichere das erzeugte Audio und verwende es wieder, statt dieselben Zeichen erneut zu bezahlen.

Aktuelle Tarife und etwaige Mengenstaffelungen findest du im Preisbereich auf der Website – das ist die einzige verlässliche Quelle.

Häufige Fehlerquellen und ihre Behebung

Die meisten Integrationsprobleme fallen in wenige Kategorien. Gehe sie der Reihe nach durch.

401 Nicht autorisiert

Dein Authorization-Header fehlt oder ist falsch formatiert. Stelle sicher, dass der Schlüssel in der Umgebung gesetzt ist und der Header-Inhalt genau Bearer <key> lautet. Wenn der Schlüssel rotiert wurde, aktualisiere deine Umgebung.

400 Bad Request – unbekannter Sprecher

Der Text enthält ein [Name]-Tag, das nicht in speakers deklariert ist, oder die Groß-/Kleinschreibung stimmt nicht überein. Mache Tag und Feld name bytegenau identisch.

400 Bad Request – Eingabe leer oder zu groß

Leerer Text besteht die Validierung sofort nicht. Sehr lange Skripte können das Limit pro Anfrage überschreiten; teile sie auf mehrere Aufträge auf, statt sie abzuschneiden.

400 Bad Request – ungültige Sprachkennung

Stimmenamen müssen aus dem Katalog der Plattform stammen. Kopiere die Kennung exakt; erfinde keine eigenen benutzerfreundlichen Namen.

Auftrag hängt im Status processing

Das ist meist Warteschlange, kein Bug. Wende Backoff und ein Gesamt-Timeout an. Wenn der Zustand weit über die normale Zeit hinaus anhält, protokolliere die Auftrags-ID und versuche es einmal mit einem kleineren Anfragetext, um festzustellen, ob die Größe das Problem ist.

Auftrag failed mit einem Generierungsfehler

Lies das Feld error. Es weist meist auf ein Inhalts- oder Konfigurationsproblem hin, nicht auf eine vorübergehende Störung. Korrigiere den Anfragetext, übermittle erneut und vermeide blinde Wiederholungsschleifen – jeder Versuch kann Zeichen kosten.

Audio lässt sich herunterladen, aber nicht abspielen

Prüfe den Inhaltstyp der heruntergeladenen Datei, bevor du annimmst, dass sie beschädigt ist. Speichere sie mit der richtigen Erweiterung für das zurückgegebene Format und prüfe, dass die Bytelänge nicht null ist. Eine abgeschnittene Datei bedeutet meist, dass die Download-Anfrage unterbrochen wurde – wiederhole den Download, statt neu zu generieren.

Mit diesen Prüfungen lassen sich die meisten Integrationsprobleme am ersten Tag in Minuten statt Stunden lösen.

Ähnliche Artikel

Alle Artikel ansehen →

Starte mit persistenten KI-Artefakten

Hol dir deinen API-Key und rufe Bild-, Video- und Audiomodelle über eine einzige task-basierte API auf.

API-Dokumentation lesen