Authentification
Un en-tête Authorization: Bearer sk-echo-... sur chaque requête. La clé est affichée une seule fois quand vous la créez : sauvegardez-la. Si vous la perdez, révoquez-la et créez-en une autre.
Restreindre une clé d'API à certaines IP
Chaque clé d'API peut être limitée aux adresses depuis lesquelles il est logique de l'utiliser. Si votre intégration vit sur un serveur à IP fixe, une clé volée ne vaut rien en dehors de lui.
Cela se configure dans votre compte, dans la colonne IP autorisées de chaque clé. Les adresses individuelles et les réseaux sont acceptés :
203.0.113.7, 198.51.100.0/24, 192.0.2.10
Laissée vide, la clé fonctionne de partout, ce qui est le comportement par défaut.
Une requête depuis une IP qui n'est pas sur la liste reçoit 403 avec le code ip_not_allowed et, dans le corps, l'IP que nous avons vue — ce qui est exactement ce dont vous avez besoin pour l'ajouter si vous en avez oublié une :
{
"error": "ip_not_allowed",
"message": "This API key is restricted to a list of IP addresses and this request does not come from one of them",
"client_ip": "203.0.113.55"
}
403, non un 401. La clé est bonne ; ce qui n'est pas valide, c'est l'endroit d'où elle appelle. Les distinguer compte : un 401 vous ferait faire tourner une clé qui était parfaitement bonne.La restriction couvre chaque endpoint authentifié, y compris /v1/usage/last. Celui qui vole une clé ne veut pas toujours la dépenser ; parfois, voir combien son propriétaire dépense suffit.
client_ip que renvoie le 403, et ajoutez celui-là.Analyse dans la même requête
Une transcription peut amener l'analyse de la voix avec elle sans téléverser l'audio à nouveau. Elles sont demandées dans la chaîne de requête, séparées par des virgules :
curl https://api.uttera.ai/v1/audio/transcriptions?extras=sentiment,profile,diarize \
-H "Authorization: Bearer $UTTERA_API_KEY" \
-F file=@recording.m4a \
-F model=whisper-1
| Extra | Renvoie | Dans la réponse |
|---|---|---|
sentiment | ton émotionnel | sentiment |
profile | profil du locuteur (âge, genre) | profile |
diarize | qui parle et quand | diarize |
Les trois tournent en parallèle sur le même audio, demander trois prend donc presque aussi longtemps que demander un. Chacun est facturé séparément, et seulement s'il tourne : si une analyse échoue, la transcription arrive quand même et la réponse porte un tableau errors indiquant laquelle manquait — et celle-là n'est pas facturée.
sentiment nécessite le plan Developer ou au-dessus ; profile et diarize, tout plan avec de l'audio intelligence. Un nom qui n'est pas l'un des trois renvoie 400 avec la liste valide, non une transcription à laquelle il manque silencieusement son analyse.Pour sentiment avec le détail par segment ou dimensionnel (valence, activation, dominance), utilisez le endpoint autonome /v1/audio/sentiment : dans extras, c'est toujours le niveau global.
Formats et langues
Audio d'entrée : wav, mp3, flac, ogg, opus, aiff, m4a et webm. webm est ce qu'enregistre un navigateur et m4a ce qu'enregistre un téléphone, les deux marchent donc tels quels pour la transcription.
wav, mp3, flac, ogg ou opus : webm et m4a sont rejetés avec 415 avant que rien ne soit dépensé, et la réponse indique avec quels formats réessayer.Audio de sortie (le response_format de la parole) : wav, mp3, opus, flac et pcm. pcm est du PCM brut sans en-tête, l'application web ne le propose donc pas — un navigateur ne peut pas le lire — et en l'utilisant via l'API, vous devez indiquer à votre décodeur les quatre paramètres, parce que le fichier ne les porte pas :
| Voix | Fréquence | Échantillon | Canaux | Ordre des octets |
|---|---|---|---|---|
| standard | 24 000 Hz | 16 bits signés | 1 (mono) | petit-boutiste |
| HD | 48 000 Hz | 16 bits signés | 1 (mono) | petit-boutiste |
La fréquence est celle native de chaque voix et n'est pas rééchantillonnée : la HD génère à 48 kHz et est livrée telle quelle. La seule chose qui diffère entre les deux est la fréquence ; la décoder avec la mauvaise ne sonne pas moins bien, elle sonne à double ou à moitié de vitesse. Avec wav, flac ou opus, cela ne s'applique pas : le fichier le déclare lui-même.
# voix standard
ffmpeg -f s16le -ar 24000 -ac 1 -i voice.pcm voice.wav
# voix HD
ffmpeg -f s16le -ar 48000 -ac 1 -i voice.pcm voice.wav
Toute autre valeur de response_format renvoie 422 avec la liste valide.
Taille : jusqu'à 150 Mo par requête et 2 heures d'audio. Un WAV non compressé de 2 heures n'y tient pas : envoyez le long audio compressé. Le détail est dans taille et durée.
Transcription : détecte la langue automatiquement et couvre celles que prend en charge Whisper.
Parole : dépend du moteur, et la différence est grande. La voix standard (tts-1) parle les neuf du tableau ci-dessous. La voix haute qualité (tts-1-hd) parle environ 30 — outre ces neuf, allemand, russe, polonais, néerlandais, les langues nordiques, grec, turc, arabe, coréen et plusieurs d'Asie du Sud-Est, entre autres — et il n'est pas nécessaire de déclarer la langue : elle est déduite du texte. C'est expliqué dans Trois voix, pas deux.
Traduction : ~50 langues en texte. La chaîne synthétise avec la voix standard, donc en parole ce sont ces neuf :
| Code | Langue | Code | Langue |
|---|---|---|---|
en | Anglais | it | Italien |
en-gb | Anglais britannique | ja | Japonais |
es | Espagnol | pt | Portugais |
fr | Français | zh | Chinois |
hi | Hindi |
Catalogue de voix
Les six voix compatibles OpenAI, disponibles avec model: tts-1 :
alloy · echo · fable · nova · onyx · shimmer
Le catalogue est nettement plus long, et il est interrogé via l'API plutôt que copié ici, de sorte que ce que vous lisez est ce qui est réellement servi en ce moment.
GET /v1/audio/voices
curl https://api.uttera.ai/v1/audio/voices \
-H "Authorization: Bearer $UTTERA_API_KEY"
{
"voices": ["adam", "alex", "alex-pt", "alice", "alloy", …],
"catalog": [
{"name": "adam", "language": "en"},
{"name": "alex", "language": "es"},
{"name": "alex-pt", "language": "pt"},
…
]
}
voices, ce sont les noms nus, pour remplir une liste déroulante ; catalog ajoute la langue de chacun. language peut être null pour les voix qui n'appartiennent pas à une langue particulière. Une voix qui n'est pas sur cette liste renvoie 422.
Crédits
Chaque service facture ce qu'il consomme. Voici les coefficients actuels :
| Service | Facturé selon | Crédits | Une heure d'audio |
|---|---|---|---|
| Transcribe | second of input audio | 0.032673 | 117.6 |
| Standard voice | second of generated audio | 0.027626 | 99.5 |
| Cloned voice | second of generated audio | 0.422204 | 1,519.9 |
| Tone | second of audio | 0.005090 | 18.3 |
| Speaker profile | second of audio | 0.003464 | 12.5 |
| Speakers | second of audio | 0.020938 | 75.4 |
| Translation | second of input audio | 0.080000 | 288.0 |
| Summary (LLM) | input token | 0.001605 | — |
| Summary (LLM) | output token | 0.080650 | — |
Comment se compose chaque service
| Service | Formule |
|---|---|
| Transcrire | STT |
| Transcrire + ton | STT + ton |
| Parole | TTS sur les secondes générées |
| Traduire | STT + TTS de l'audio généré + supplément de traduction |
| Résumer | STT + profil + locuteurs + tokens du modèle |
Un exemple réel
Un enregistrement de 40 minutes (2 424 s) traduit en anglais avec parole :
transcription 79,22 2 424,5 s x 0,032673
parole 43,18 2 055,8 s x 0,021004 (l'anglais sort ~15 % plus court)
traduction 193,96 2 424,5 s x 0,080000
──────
316,36 crédits
Plans et limites
| Plan | €/mois | Crédits | Concurrence | Voix HD | Clonage | Résumer | SLA |
|---|---|---|---|---|---|---|---|
| Free | 0 | 500 | 1 | — | — | — | — |
| Startup | 19 | 7,500 | 3 | yes | yes | yes | — |
| Developer | 99 | 50,000 | 15 | yes | yes | yes | — |
| Professional | 299 | 200,000 | 50 | yes | yes | yes | 95.0 % |
| Business | 999 | 800,000 | 150 | yes | yes | yes | 99.0 % |
| Enterprise | custom | custom | custom | yes | yes | yes | 99.9 % |
Les crédits se renouvellent à votre date d'abonnement, non le 1er. Si vous passez à un plan plus petit, vous conservez les crédits déjà payés jusqu'à la fin de la période.
Ce même tableau est servi en JSON et sans clé, pour qu'un programme —ou un agent qui se configure— puisse lire les limites avant que quiconque s'inscrive :
curl https://api.uttera.ai/v1/plans
{"plans": {"free": {"price_eur_per_month": 0, "credits_per_month": 500,
"max_concurrent": 1, "rate_limits": {"stt": 1, "tts": 1, "sfx": 0,
"intelligence": 0}, "summary_allowed": false, "voice_clone_allowed": false, …}, …}}
C'est la même source qui remplit le tableau ci-dessus : si quelque chose change, les deux changent en même temps.
Limites par seconde
| Plan | Parole | Transcription | Analyse |
|---|---|---|---|
| Free | 1 | 1 | — |
| Startup | 5 | 20 | 5 |
| Developer | 100 | 400 | 50 |
| Professional | 250 | 1,000 | 200 |
| Business | 500 | 2,000 | 500 |
Chaque réponse porte X-RateLimit-Remaining-Second et X-Credits-Remaining-Monthly pour que vous n'ayez pas à deviner.
Taille et durée maximales
| Quoi | Limite |
|---|---|
| Taille du fichier que vous envoyez | 250 Mo |
| Durée de l'audio | 4 heures |
| Prononciation : taille de l'échantillon | 1 Mo — c'est un apprenant lisant une phrase, quelques secondes d'audio |
| Résumer : durée de l'enregistrement | les mêmes 4 heures — il n'a pas de limite propre plus courte |
Synthèse vocale, voix standard (tts-1) | 250 000 caractères — environ quatre à cinq heures de parole, selon la densité du texte |
| Synthèse vocale, voix standard en streaming | aucune limite de longueur |
Synthèse vocale, voix haute qualité et clonée (tts-1-hd) | 2 000 caractères, environ deux minutes et demie |
Longs enregistrements : comment le résumé les gère
Un long enregistrement ne tient pas dans le contexte du modèle en une fois. Plutôt que d'en résumer une partie, nous le découpons, résumons chaque morceau puis fusionnons — et la fusion n'est pas un résumé de résumés, ce qui perdrait de l'information deux fois : on lui demande d'ordonner et combiner les morceaux, en gardant chaque chiffre, date et nom.
Le résumé n'a donc pas de limite propre plus courte : tout ce que vous pouvez transcrire, vous pouvez le résumer. Mesuré de bout en bout sur un enregistrement de quatre heures avec ton, profil du locuteur et diarisation : six minutes, complet, avec le début et la fin tous deux présents.
Si un résumé revenait un jour coupé court, la réponse le dit dans truncated. Ce n'est pas quelque chose que vous devriez voir, et nous préférons vous le dire plutôt que de vous remettre un résumé raccourci qui se lit comme un entier.
Deux heures doivent tenir dans 150 Mo
Les deux limites sont indépendantes et vous devez satisfaire les deux. Pour deux heures pleines, cela signifie rester sous 175 kbps :
| Format | Ce qui tient dans 150 Mo |
|---|---|
| mp3 à 64 kbps | 5 h 27 min |
| mp3 à 128 kbps | 2 h 44 min |
| mp3 à 160 kbps | 2 h 11 min |
| mp3 à 256 kbps | 1 h 22 min |
| wav 16 bits, mono, 16 kHz | 1 h 22 min |
| wav 16 bits, stéréo, 44,1 kHz | 14 min |
Pour la parole, un mp3 à 64 kbps ne perd rien qui compte pour nous et vous laisse beaucoup de marge. Si vous envoyez du wav non compressé, attendez-vous à ce que deux heures ne tiennent pas.
Synthèse vocale : la limite dépend de la voix
Il n'y a pas de limite unique, parce que les deux voix sont produites par des machineries différentes :
Voix standard (tts-1). Elle peut être demandée de deux façons :
- Réponse complète (
/v1/audio/speech) : nous renvoyons tout l'audio une fois terminé. Comme tout doit exister en même temps, le plafond est de 250 000 caractères — environ quatre à cinq heures de parole. Nous disons « environ » à dessein : combien d'audio un caractère devient dépend beaucoup du texte, et mesuré sur de la prose réelle cela va de 12,6 à 17,5 caractères par seconde. Le plafond porte sur le texte, non sur la durée. - Streaming (
/v1/audio/speech/stream) : nous envoyons l'audio à mesure qu'il se génère. Ici, il n'y a aucune limite de longueur, parce que rien ne s'empile.
Pour une longue narration, le streaming reste la meilleure voie. Vous commencez à entendre le résultat en quelques secondes au lieu d'attendre la fin, et rien n'a à tenir dans une seule réponse.
Voix haute qualité et clonée (tts-1-hd). Le plafond est de 2 000 caractères par requête, environ deux minutes et demie de parole. C'est nettement moins, et c'est une limite du modèle derrière cette voix, non une décision commerciale. Pour cette voix, le streaming n'aide pas avec un long texte : utilisez-la par morceaux de quelques milliers de caractères et enchaînez-les.
Erreurs
| Code | Ce que cela signifie | Quoi faire |
|---|---|---|
400 | Le fichier ne peut pas être décodé, ou un paramètre est invalide. | La raison vient dans detail. |
401 | Clé manquante, malformée ou révoquée. | Vérifiez l'en-tête Authorization. |
402 | Quota de crédits épuisé. | Attendez le renouvellement ou passez à un plan supérieur. |
403 | Votre plan n'inclut pas ce service. | Le message indique quel plan le fait. |
413 | Fichier trop grand. | Découpez ou compressez l'audio. |
422 | Requête valide, impossible à servir. | Par exemple, de l'audio dans une langue sans voix. Non facturé. |
429 | Trop de requêtes par seconde. | Respectez Retry-After. |
502 503 | Défaillance temporaire d'un nœud. | C'est réessayé une fois automatiquement. Réessayez vous-même après quelques secondes. |
Vérifier votre consommation
La facturation est calculée après que la réponse vous est envoyée, elle ne vient donc pas à l'intérieur. Pour savoir exactement ce qu'une requête vous a coûté :
GET /v1/usage/last
GET /v1/usage/last?endpoint=/v1/summarize
Elle renvoie les crédits facturés et le détail par étape :
{
"endpoint": "/v1/summarize",
"credits": 108.978,
"breakdown": { "stt": 3.1255, "diarize": 2.0029,
"profile": 0.1946, "llm": 103.655 },
"audio_seconds": 95.66,
"input_tokens": 2776, "output_tokens": 1230
}
Elle garde les dix dernières facturations pendant une heure. C'est pour vérifier sur le moment, non un historique de facturation.
Combien de temps prend chaque chose
Des chiffres mesurés, non des promesses. Ils varient avec le nœud qui vous sert et la charge du moment :
| Opération | Temps typique |
|---|---|
| Transcrire 100 minutes d'audio | 10 à 35 s |
| Transcrire un enregistrement de 40 minutes | moins de 30 s |
| Voix standard, une phrase | dixièmes de seconde |
| Voix clonée | Nettement plus : l'échantillon doit être traité |
| Hit de cache | millisecondes |
| Résumé d'un long enregistrement | La plus lente de ses étapes, non la somme : elles tournent en parallèle |
Ce qu'il faut vraiment régler correctement, c'est le délai d'attente de votre client : le serveur garde la connexion jusqu'à 7200 secondes, et la défaillance la plus courante en intégrant est un client avec un défaut de 30 secondes qui coupe des tâches qui se passaient bien. C'est expliqué dans Intégration.
Versionnage et modifications
Ce que vous intégrez aujourd'hui doit continuer de fonctionner demain. Voici l'engagement :
Pour que cela veuille dire quelque chose, nous devons dire ce qui compte comme cassant et ce qui ne l'est pas :
| Cassant (six mois de préavis) | Non cassant (peut arriver n'importe quel jour) |
|---|---|
| Retirer un endpoint ou un paramètre | Ajouter un nouvel endpoint |
| Retirer ou renommer un champ de réponse | Ajouter un champ à la réponse |
| Changer le type ou le sens d'un champ | Ajouter un paramètre optionnel |
| Changer la valeur par défaut d'un paramètre | Ajouter une voix ou une langue |
| Rendre obligatoire ce qui était optionnel | Ajouter un en-tête de réponse |
| Remplacer un code d'erreur par un autre | Améliorer le texte d'un message d'erreur |
D'où découle la règle pratique pour votre code : ignorez les champs que vous ne reconnaissez pas au lieu d'échouer quand vous les rencontrez. Un client qui explose parce que la réponse porte une nouvelle clé se cassera de lui-même, sans que personne n'ait rien cassé.
Les prix sont un cas à part : ce n'est pas l'interface, mais c'est votre facture. Une hausse des coefficients est annoncée avec trente jours de préavis et n'est pas appliquée à un cycle déjà payé. Une baisse s'applique dès qu'elle existe.
État du service
Si quelque chose se passe mal, la première chose est de savoir si c'est le vôtre ou le nôtre.
GET https://api.uttera.ai/health répond sans clé et dit si l'API est en ligne. C'est la vérification que vous pouvez automatiser.
curl -s https://api.uttera.ai/health
Chaque réponse porte aussi un en-tête X-Request-Id. Gardez-le quand quelque chose échoue : avec cet identifiant, nous pouvons vous dire exactement ce qui est arrivé à votre requête, et sans lui la conversation commence par reconstruire laquelle c'était.
Pour tout incident, écrivez-nous avec le X-Request-Id, l'heure approximative et ce que vous attendiez.
En cours
Des choses que les gens demandent, qui ont du sens, et qui ne sont pas encore là. Nous les mettons ici parce que découvrir que quelque chose n'existe pas après l'avoir intégré est pire que de le savoir maintenant :
| Quoi | Pour quoi | État |
|---|---|---|
| Webhooks | Pour vous notifier quand une longue tâche se termine, au lieu de garder la connexion ouverte | À décider |
| Dictionnaire de prononciation | Indiquer au moteur comment se prononcent les noms propres, marques et acronymes | À décider |
| Comptes de service et utilisateurs multiples | Pour qu'une entreprise puisse avoir plusieurs personnes et des clés séparées sous un compte | Après la bêta |
Si l'une d'elles vous bloque, dites-le-nous : ce que les clients demandent est ce qui décide l'ordre.