Tutoriale
Come chiamare gemini-3.1-flash-tts su HiAPI: curl, Python e una richiesta eseguibile
Cosa può fare gemini-3.1-flash-tts per te su HiAPI
gemini-3.1-flash-tts è un modello di sintesi vocale (text-to-speech) fornito tramite l'API unificata di HiAPI. Invii il testo e la configurazione vocale, e la piattaforma restituisce l'audio generato. Poiché è esposto tramite un'interfaccia unica e coerente, non è necessario integrare ogni modello separatamente: gli stessi header di autenticazione, lo stesso URL di base e lo stesso modello di attività asincrona valgono per tutti i modelli TTS della piattaforma.
Puoi scegliere questo modello quando hai bisogno di:
- Narrazione multi-speaker. Script, dialoghi o contenuti in stile podcast, in cui segmenti diversi devono suonare come voci diverse.
- Tempi di risposta rapidi. La serie
flashè pensata per la generazione a bassa latenza, particolarmente importante per applicazioni interattive o processi batch con SLA stringenti. - Un'interfaccia di integrazione prevedibile. Un'unica forma di richiesta copre tutti i casi, da una singola riga di testo agli scenari multi-speaker.
Se la tua applicazione chiama già altri modelli HiAPI, aggiungere la funzionalità vocale richiede solo di sostituire l'identificatore del modello e modificare il corpo della richiesta: nessun nuovo SDK, nessun nuovo flusso di credenziali.
Prerequisiti e configurazione dell'autenticazione
Prima della prima chiamata, assicurati di avere:
- Un account HiAPI e una chiave API. Genera la chiave dalla console. Trattala come un segreto: non salvarla nel controllo del codice sorgente.
- L'URL di base di HiAPI. Tutte le richieste vanno allo stesso host; solo il percorso di ciascun endpoint cambia.
- Uno strumento per effettuare richieste HTTP.
curlper test rapidi, e Python 3.9+ con la libreriarequestsper gli script.
L'autenticazione avviene tramite un token bearer nell'header Authorization:
Authorization: Bearer $HIAPI_API_KEY
Salva la chiave in una variabile d'ambiente, non codificarla direttamente:
export HIAPI_API_KEY="your_key_here"
Ogni endpoint descritto di seguito — invio dell'attività, controllo dello stato e recupero del file — usa lo stesso header. Se ricevi 401, significa che l'header è mancante, malformato oppure che la chiave è stata revocata. Ruota la chiave dalla console invece di condividere la stessa tra ambienti diversi.
Costruire il corpo della richiesta per voci multi-speaker
Il corpo della richiesta è JSON. Come minimo deve contenere l'identificatore del modello e il contenuto di input. Per l'output multi-speaker, devi aggiungere una configurazione degli speaker che mappa gli speaker nominati alle voci, e contrassegnare il testo di input con i tag degli speaker.
Un corpo di richiesta tipico è il seguente:
{
"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" }
]
}
}
Punti chiave che causano errori:
- I nomi degli speaker devono corrispondere esattamente. Il campo
namenell'arrayspeakersdeve coincidere esattamente con il tag usato nel testo (in questo esempio, tra parentesi quadre). Un errore di maiuscole/minuscole è la causa più comune di errori nel rendering multi-speaker. - Ogni tag deve essere dichiarato. Se il testo fa riferimento a
[Narrator]ma non viene definito uno speaker conname: "Narrator", la richiesta verrà rifiutata. - Gli identificatori vocali provengono dal catalogo voci della piattaforma. Usa gli identificatori forniti da HiAPI, non inventarli. Per le attività a singolo speaker, ometti
multi_speakerespeakerse imposta invece un singolo campovoice. - Il testo viene inviato come singola stringa. Gli script lunghi non sono un problema, ma tieni presente i limiti per richiesta documentati sulla piattaforma.
Una volta superata la validazione, l'attività viene accettata e viene restituito un identificatore di attività, che userai per il polling.
Esecuzione con curl
Salva il corpo della richiesta sopra in payload.json, poi invialo:
curl -X POST "$HIAPI_BASE_URL/v1/audio/speech/jobs" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d @payload.json
La risposta contiene un oggetto attività con i campi id e status (di solito queued o processing):
{ "id": "job_abc123", "status": "queued" }
Per controllare l'avanzamento, recupera l'attività tramite l'ID:
curl "$HIAPI_BASE_URL/v1/audio/speech/jobs/job_abc123" \
-H "Authorization: Bearer $HIAPI_API_KEY"
Quando status diventa succeeded, la risposta contiene un riferimento al file audio (URL o ID file), che puoi scaricare con una richiesta successiva — vedi la sezione sul polling più avanti. Se l'attività fallisce, status sarà failed e ci sarà un campo error che ne spiega il motivo.
Per esperimenti rapidi, puoi saltare il file e usare JSON inline:
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"}}'
Esecuzione con Python
La versione Python usa requests e una piccola funzione di supporto per mantenere leggibile il ciclo di polling. Il corpo della richiesta è identico all'esempio curl.
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"])
Note:
- I timeout sono importanti. Imposta esplicitamente un timeout per ogni richiesta; un ciclo di polling bloccato è peggio di uno fallito.
- Non fare polling troppo frequentemente. Un intervallo di due secondi va bene per script brevi; per script lunghi è meglio un backoff.
- Metti il corpo della richiesta in una funzione. Nel codice reale, parametrizza testo, speaker e voce, così puoi riutilizzare la stessa logica di invio per attività a singolo speaker.
Polling delle attività asincrone e download dell'audio
La generazione vocale è asincrona: invii l'attività, poi controlli lo stato finché non raggiunge uno stato finale. Esistono due stati finali: succeeded e failed. Tutti gli altri stati vanno considerati come "continua ad attendere".
Un programma di polling robusto dovrebbe:
- Limitare il tempo totale di attesa. Anche un modello veloce può essere in coda dopo altro lavoro. Fermati dopo un limite ragionevole ed esponi l'ID dell'attività, così il chiamante può riprovare.
- Backoff esponenziale. Inizia da uno o due secondi e raddoppia progressivamente fino a un limite massimo. Questo evita di sovraccaricare l'API durante attività lunghe.
- Gestire esplicitamente gli errori. Quando
status == "failed", leggi e registra il campoerror: di solito indica un problema nel corpo della richiesta (speaker non dichiarato, testo vuoto, voce non supportata).
Quando l'attività ha successo, la risposta di stato contiene un riferimento all'output. Scaricalo con gli stessi header di autenticazione:
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)
Se la risposta restituisce un ID file invece di un URL, recuperalo tramite l'endpoint file corrispondente su HiAPI. Conserva l'ID originale dell'attività insieme al file salvato: è l'unico modo affidabile per risalire in seguito a un rendering scadente e alla sua richiesta.
Capire la fatturazione per carattere
gemini-3.1-flash-tts su HiAPI viene fatturato in base al numero di caratteri del testo di input. Non ci sono componenti per richiesta o per minuto da modellare: il costo dell'attività scala con la quantità di testo inviata, il che rende la stima semplice: il numero totale di caratteri di tutti gli script moltiplicato per la tariffa corrente per carattere.
Implicazioni pratiche:
- Stima prima di andare in produzione. Somma il volume di testo mensile previsto e confrontalo con la tariffa corrente mostrata nel pannello dei prezzi. Non codificare la tariffa nel codice; leggila dalla piattaforma in fase di build oppure salvala in configurazione.
- I contenuti lunghi dominano i costi. Una narrazione di dieci minuti è principalmente un costo di testo. Se devi generare audiolibri o materiale didattico, modella prima i volumi.
- I tentativi falliti generano costi. Le attività che falliscono dopo la generazione possono comunque essere fatturate, a seconda della modalità di errore. Valida lato client prima dell'invio: verifica che ogni tag speaker sia dichiarato e che il testo non sia vuoto.
- Usa attivamente la cache. Se lo stesso script viene renderizzato ripetutamente (ad esempio in demo o fixture di test), salva l'audio generato e riutilizzalo, invece di addebitare ripetutamente gli stessi caratteri.
Per le tariffe correnti e eventuali livelli di volume, consulta il pannello dei prezzi sul sito: è l'unica fonte di verità.
Punti di errore comuni e come risolverli
La maggior parte dei problemi di integrazione rientra in poche categorie. Esaminale in ordine.
401 Non autorizzato
Il tuo header Authorization è mancante o malformato. Verifica che la chiave sia impostata nell'ambiente e che il contenuto dell'header sia esattamente Bearer <key>. Se la chiave è stata ruotata, aggiorna il tuo ambiente.
400 Bad Request — speaker sconosciuto
Il testo contiene un tag [Name] non dichiarato in speakers, oppure con maiuscole/minuscole diverse. Rendi tag e campo name identici byte per byte.
400 Bad Request — input vuoto o troppo grande
Un testo vuoto non supera immediatamente la validazione. Script molto lunghi possono superare il limite per richiesta; suddividili in più attività invece di troncarli.
400 Bad Request — identificatore vocale non valido
I nomi delle voci devono provenire dal catalogo della piattaforma. Copia esattamente gli identificatori; non inventare nomi descrittivi.
Attività bloccata in stato processing
Di solito si tratta di coda, non di un bug. Applica backoff e un timeout totale. Se persiste molto oltre il tempo normale, registra l'ID dell'attività e riprova una volta con un corpo di richiesta più piccolo, per capire se la dimensione è il problema.
Attività failed con errore di generazione
Leggi il campo error. Di solito indica un problema di contenuto o configurazione, non un guasto transitorio. Correggi il corpo della richiesta, invia di nuovo ed evita cicli di retry ciechi: ogni tentativo può essere fatturato per carattere.
L'audio si scarica ma non si riproduce
Prima di dare per scontato che il file sia danneggiato, controlla il content-type del file scaricato. Salvalo con l'estensione corretta corrispondente al formato restituito e verifica che la lunghezza in byte non sia zero. Un file troncato di solito significa che la richiesta di download è stata interrotta: riprova il download, non la generazione.
Con questi controlli, la maggior parte dei problemi di integrazione del primo giorno si risolve in pochi minuti invece che in ore.
Articoli correlati
Vedi tutti gli articoli →-
Tutoriale
Come chiamare hailuo-2.3-fast/image-to-video tramite l'API HiAPI: pratica con curl e Python
La prima richiesta funzionante per il livello image-to-video veloce ed economico — dall'ID del modello al download di un MP4
-
Tutoriale
Come chiamare hailuo-2.3/text-to-video tramite l'API HiAPI: curl, Python ed esempi di richiesta eseguibili
-
Tutoriale
Utilizzare Kandinsky 6.0 Pro su HiAPI per la generazione di video da testo: tutorial con curl e Python
Dimostrazione pratica guidata dalla richiesta: costruire la chiamata da prompt a clip video, inviare la richiesta, monitorare lo stato di completamento e scaricare il risultato