Tutoriel
Comment appeler gemini-3.1-flash-tts sur HiAPI : curl, Python et une requête exécutable
Ce que gemini-3.1-flash-tts peut faire pour vous sur HiAPI
gemini-3.1-flash-tts est un modèle de synthèse vocale proposé via l'API unifiée de HiAPI. Vous envoyez un texte et une configuration vocale, la plateforme renvoie l'audio généré. Comme il est exposé via une interface unique et cohérente, vous n'avez pas besoin d'intégrer chaque modèle séparément : les mêmes en-têtes d'authentification, la même URL de base et le même modèle de tâche asynchrone s'appliquent à tous les modèles TTS de la plateforme.
Vous pouvez choisir ce modèle lorsque vous avez besoin des capacités suivantes :
- Narration multi-locuteurs. Des scripts, des dialogues ou du contenu de style podcast, où différents segments doivent sonner comme des voix différentes.
- Réactivité rapide. La série
flashvise une génération à faible latence, ce qui est particulièrement important pour les applications interactives ou les tâches par lots soumises à des SLA stricts. - Une interface d'intégration prévisible. Une seule forme de requête couvre tous les cas, du texte d'une seule ligne aux scénarios multi-locuteurs.
Si l'application que vous développez appelle déjà d'autres modèles HiAPI, ajouter la fonctionnalité vocale ne demande que de remplacer l'identifiant du modèle et d'ajuster le corps de la requête — sans nouveau SDK ni nouveau flux d'identifiants.
Prérequis et configuration de l'authentification
Avant le premier appel, assurez-vous de disposer de :
- Un compte HiAPI et une clé API. Générez la clé depuis la console. Traitez-la comme un secret — ne la validez pas dans le contrôle de source.
- L'URL de base de HiAPI. Toutes les requêtes sont envoyées au même hôte ; seul le chemin diffère selon l'endpoint.
- Un outil pour émettre des requêtes HTTP.
curlpour les tests rapides, ainsi que Python 3.9+ et la bibliothèquerequestspour les scripts.
L'authentification consiste à transmettre un jeton bearer dans l'en-tête Authorization :
Authorization: Bearer $HIAPI_API_KEY
Stockez la clé dans une variable d'environnement plutôt que de la coder en dur :
export HIAPI_API_KEY="your_key_here"
Chaque endpoint décrit ci-dessous — soumission de tâche, vérification de l'état et récupération de fichier — utilise le même en-tête. Si vous recevez un 401, cela signifie que l'en-tête est absent, mal formé ou que la clé a été révoquée. Renouvelez la clé dans la console plutôt que de partager une même clé entre environnements.
Construire le corps de requête pour une voix multi-locuteurs
Le corps de la requête est en JSON. Il doit contenir au minimum l'identifiant du modèle et le contenu d'entrée. Pour une sortie multi-locuteurs, vous devez ajouter une configuration de locuteurs qui associe des locuteurs nommés à des voix, et marquer le texte d'entrée avec des balises de locuteur.
Un corps de requête typique ressemble à ceci :
{
"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" }
]
}
}
Les points clés qui piègent facilement :
- Les noms de locuteurs doivent correspondre exactement. Le
namedans le tableauspeakersdoit correspondre exactement aux balises utilisées dans le texte (ici entre crochets). Une différence de casse est la cause la plus fréquente d'échec du rendu multi-locuteurs. - Chaque balise doit être déclarée. Si le texte référence
[Narrator]sans qu'un locuteurname: "Narrator"soit défini, la requête sera rejetée. - Les identifiants de voix proviennent du catalogue de voix de la plateforme. Utilisez les identifiants fournis par HiAPI, ne les devinez pas. Pour les tâches mono-locuteur, omettez
multi_speakeretspeakers, et définissez plutôt un seul champvoice. - Le texte est envoyé sous forme d'une seule chaîne. Les scripts longs ne posent pas de problème, mais respectez les limites par requête documentées sur la plateforme.
Une fois le corps de requête validé, la tâche est acceptée et renvoie un identifiant de tâche que vous utiliserez pour interroger son état.
Exécution avec curl
Enregistrez le corps de requête ci-dessus dans payload.json, puis soumettez-le :
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 réponse contient un objet tâche avec les champs id et status (généralement queued ou processing) :
{ "id": "job_abc123", "status": "queued" }
Pour vérifier la progression, récupérez la tâche par son ID :
curl "$HIAPI_BASE_URL/v1/audio/speech/jobs/job_abc123" \
-H "Authorization: Bearer $HIAPI_API_KEY"
Lorsque status passe à succeeded, la réponse contient une référence au fichier audio (URL ou ID de fichier) que vous pouvez télécharger via une requête ultérieure — voir la section sur l'interrogation ci-dessous. Si la tâche échoue, status sera failed et un champ error en indiquera la raison.
Pour une expérimentation rapide, vous pouvez vous passer de fichier et envoyer le JSON directement :
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"}}'
Exécution avec Python
La version Python utilise requests et une petite fonction utilitaire pour garder la boucle d'interrogation lisible. Le corps de requête est identique à l'exemple 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"])
Points d'attention :
- Les timeouts sont importants. Définissez explicitement un timeout pour chaque requête ; une boucle d'interrogation qui reste bloquée est pire qu'une boucle qui échoue.
- N'interrogez pas trop fréquemment. Un intervalle de deux secondes convient pour un script court ; pour un script long, appliquez un backoff.
- Placez le corps de requête dans une fonction. Dans le code réel, paramétrez le texte, les locuteurs et les voix afin de pouvoir réutiliser la même logique de soumission pour les tâches mono-locuteur.
Interroger les tâches asynchrones et télécharger l'audio
La génération vocale est asynchrone : vous soumettez une tâche, puis vérifiez son état jusqu'à ce qu'elle atteigne un état terminal. Il existe deux états terminaux — succeeded et failed. Tous les autres états doivent être considérés comme « continuer à attendre ».
Une boucle d'interrogation robuste doit :
- Limiter le temps d'attente total. Même un modèle rapide peut être placé derrière d'autres travaux. Arrêtez après un plafond raisonnable et exposez l'ID de tâche pour que l'appelant puisse réessayer.
- Appliquer un backoff exponentiel. Commencez par une à deux secondes, puis doublez progressivement jusqu'à un plafond. Cela évite de trop solliciter l'API sur les tâches longues.
- Gérer explicitement les échecs. Lorsque
status == "failed", lisez et journalisez le champerror— il pointe généralement vers un problème de corps de requête (locuteur non déclaré, texte vide, voix non prise en charge).
Lorsque la tâche réussit, la réponse d'état contient une référence de sortie. Téléchargez-la avec les mêmes en-têtes d'authentification :
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)
Si la réponse renvoie un ID de fichier plutôt qu'une URL, récupérez-le via l'endpoint de fichiers correspondant sur HiAPI. Conservez l'ID de tâche d'origine avec le fichier enregistré — c'est le seul moyen fiable de relier ultérieurement un rendu défectueux à sa requête.
Comprendre la facturation au caractère
Sur HiAPI, gemini-3.1-flash-tts est facturé en fonction du nombre de caractères du texte d'entrée. Aucune composante par requête ou par minute n'est à modéliser — le coût d'une tâche évolue avec le volume de texte envoyé, ce qui rend l'estimation simple : le nombre total de caractères de tous les scripts multiplié par le tarif actuel par caractère.
Implications pratiques :
- Estimez avant de mettre en production. Additionnez votre volume de texte mensuel prévu et vérifiez-le par rapport au tarif actuel affiché sur le panneau de tarification. Ne codez pas le tarif en dur dans le code ; lisez-le depuis la plateforme au moment de la construction ou conservez-le dans une configuration.
- Le contenu long domine les coûts. Dix minutes de narration représentent essentiellement un coût de texte. Si vous produisez des livres audio ou du matériel de cours, modélisez d'abord le volume.
- Les réessais engendrent des frais. Une tâche qui échoue après génération peut tout de même être facturée, selon le mode d'échec. Validez côté client avant la soumission — vérifiez que chaque balise de locuteur est déclarée et que le texte n'est pas vide.
- Cachez agressivement. Si le même script est rendu de façon répétée (par exemple pour des démos ou des fixtures de test), enregistrez l'audio généré et réutilisez-le au lieu de refacturer les mêmes caractères.
Pour les tarifs actuels et les éventuels paliers de volume, consultez le panneau de tarification sur le site — c'est la seule source de vérité.
Points de défaillance courants et comment les corriger
La plupart des problèmes d'intégration se répartissent en quelques catégories. Examinez-les dans l'ordre.
401 Non autorisé
Votre en-tête Authorization est absent ou mal formé. Vérifiez que la clé est définie dans l'environnement et que le contenu de l'en-tête est exactement Bearer <key>. Si la clé a été renouvelée, mettez à jour votre environnement.
400 Requête invalide — locuteur inconnu
Le texte contient une balise [Name] non déclarée dans speakers, ou la casse ne correspond pas. Faites en sorte que les balises et les champs name soient identiques octet par octet.
400 Requête invalide — entrée vide ou trop volumineuse
Un texte vide échoue immédiatement à la validation. Un script très long peut dépasser la limite par requête ; divisez-le en plusieurs tâches plutôt que de le tronquer.
400 Requête invalide — identifiant de voix invalide
Les noms de voix doivent provenir du catalogue de la plateforme. Copiez les identifiants exactement ; n'inventez pas de noms conviviaux.
La tâche reste bloquée à l'état processing
Il s'agit généralement d'une mise en file d'attente, pas d'un bug. Appliquez un backoff et un timeout total. Si cela persiste bien au-delà de la durée normale, enregistrez l'ID de tâche et réessayez une fois avec un corps de requête plus petit pour déterminer si la taille est en cause.
La tâche est failed avec une erreur de génération
Lisez le champ error. Il pointe généralement vers un problème de contenu ou de configuration, pas vers une panne transitoire. Corrigez le corps de requête, soumettez à nouveau et évitez les boucles de réessai aveugles — chaque tentative peut être facturée au caractère.
L'audio peut être téléchargé mais ne peut pas être lu
Avant de supposer que le fichier est corrompu, vérifiez le type de contenu du fichier téléchargé. Enregistrez-le avec l'extension correcte correspondant au format renvoyé et vérifiez que la longueur en octets n'est pas nulle. Un fichier tronqué signifie généralement que la requête de téléchargement a été interrompue — réessayez le téléchargement plutôt que de régénérer.
Avec ces vérifications, la plupart des problèmes d'intégration du premier jour se résolvent en quelques minutes plutôt qu'en quelques heures.
Articles similaires
Voir tous les articles →-
Tutoriel
Comment appeler hailuo-2.3-fast/image-to-video via l'API HiAPI : curl et Python en pratique
La première requête exploitable du palier image-vers-vidéo rapide et économique — de l'ID du modèle au téléchargement du MP4
-
Tutoriel
Comment appeler hailuo-2.3/text-to-video via l'API HiAPI : curl, Python et exemples de requêtes exécutables
-
Tutoriel
Utiliser Kandinsky 6.0 Pro texte-vers-vidéo sur HiAPI : tutoriel curl et Python
Démonstration pratique axée sur la requête : construire l'appel du prompt au clip vidéo, soumettre la requête, interroger l'état d'achèvement et télécharger le résultat