UtteraUttera

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.

Ne la mettez pas dans le navigateur. La clé donne accès à votre quota de crédits. Appelez l'API depuis votre serveur, jamais depuis du code que l'utilisateur final peut lire.

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"
}
C'est un 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.

Avant de restreindre une clé en production, vérifiez de quelle IP vous sortez réellement. Ce n'est pas toujours celle que vous croyez : derrière un NAT, un répartiteur de charge, ou une connexion internet à plusieurs lignes, votre trafic peut apparaître depuis différentes adresses. Lancez une requête, regardez le 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
ExtraRenvoieDans la réponse
sentimentton émotionnelsentiment
profileprofil du locuteur (âge, genre)profile
diarizequi parle et quanddiarize

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.

L'analyse de la voix — ton, profil du locuteur, locuteurs — nécessite 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 :

VoixFréquenceÉchantillonCanauxOrdre des octets
standard24 000 Hz16 bits signés1 (mono)petit-boutiste
HD48 000 Hz16 bits signés1 (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 :

CodeLangueCodeLangue
enAnglaisitItalien
en-gbAnglais britanniquejaJaponais
esEspagnolptPortugais
frFrançaiszhChinois
hiHindi

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 :

ServiceFacturé selonCréditsUne heure d'audio
Transcribesecond of input audio0.032673117.6
Standard voicesecond of generated audio0.02762699.5
Cloned voicesecond of generated audio0.4222041,519.9
Tonesecond of audio0.00509018.3
Speaker profilesecond of audio0.00346412.5
Speakerssecond of audio0.02093875.4
Translationsecond of input audio0.080000288.0
Summary (LLM)input token0.001605
Summary (LLM)output token0.080650
Un token de sortie coûte 54 fois un token d'entrée. Générer est bien plus cher que lire, c'est pourquoi la part du modèle domine la facture d'un résumé même quand la transcription est longue.

Comment se compose chaque service

ServiceFormule
TranscrireSTT
Transcrire + tonSTT + ton
ParoleTTS sur les secondes générées
TraduireSTT + TTS de l'audio généré + supplément de traduction
RésumerSTT + 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
Ce qui est facturé, c'est l'audio généré, non l'audio que vous téléversez. En traduisant, la langue cible ne dure presque jamais autant que la source.

Plans et limites

Plan€/moisCréditsConcurrenceVoix HDClonageRésumerSLA
Free05001
Startup197,5003yesyesyes
Developer9950,00015yesyesyes
Professional299200,00050yesyesyes95.0 %
Business999800,000150yesyesyes99.0 %
Enterprisecustomcustomcustomyesyesyes99.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

PlanParoleTranscriptionAnalyse
Free11
Startup5205
Developer10040050
Professional2501,000200
Business5002,000500

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

QuoiLimite
Taille du fichier que vous envoyez250 Mo
Durée de l'audio4 heures
Prononciation : taille de l'échantillon1 Mo — c'est un apprenant lisant une phrase, quelques secondes d'audio
Résumer : durée de l'enregistrementles 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 streamingaucune 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 :

FormatCe qui tient dans 150 Mo
mp3 à 64 kbps5 h 27 min
mp3 à 128 kbps2 h 44 min
mp3 à 160 kbps2 h 11 min
mp3 à 256 kbps1 h 22 min
wav 16 bits, mono, 16 kHz1 h 22 min
wav 16 bits, stéréo, 44,1 kHz14 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 :

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.

Si vous envoyez plus, c'est coupé. Au-dessus de son plafond, la voix haute qualité renvoie de l'audio correct mais incomplet, sans avertissement. Nous ajoutons une vérification qui le rejette avec une erreur au lieu de le rogner ; d'ici là, découpez le texte vous-même et vérifiez la durée de ce que vous recevez.
Les minutes sont une équivalence ; la limite se compte en caractères. La vitesse de lecture dépend du texte : de la prose aux mots longs avance plus vite, en caractères par seconde, qu'un dialogue en phrases courtes. Il y a plus de 20 % de différence entre les deux cas, la durée exacte ne peut donc pas être connue à l'avance.

Erreurs

CodeCe que cela signifieQuoi faire
400Le fichier ne peut pas être décodé, ou un paramètre est invalide.La raison vient dans detail.
401Clé manquante, malformée ou révoquée.Vérifiez l'en-tête Authorization.
402Quota de crédits épuisé.Attendez le renouvellement ou passez à un plan supérieur.
403Votre plan n'inclut pas ce service.Le message indique quel plan le fait.
413Fichier trop grand.Découpez ou compressez l'audio.
422Requête valide, impossible à servir.Par exemple, de l'audio dans une langue sans voix. Non facturé.
429Trop de requêtes par seconde.Respectez Retry-After.
502 503Défaillance temporaire d'un nœud.C'est réessayé une fois automatiquement. Réessayez vous-même après quelques secondes.
Si une étape échoue, elle n'est pas facturée. Dans les chaînes multi-étapes —traduire, résumer— une défaillance au milieu renvoie l'erreur sans facturer de crédits, et une défaillance partielle renvoie ce qui a pu être fait avec un avertissement, ne facturant que cette partie.

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érationTemps typique
Transcrire 100 minutes d'audio10 à 35 s
Transcrire un enregistrement de 40 minutesmoins de 30 s
Voix standard, une phrasedixièmes de seconde
Voix clonéeNettement plus : l'échantillon doit être traité
Hit de cachemillisecondes
Résumé d'un long enregistrementLa 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 :

Six mois de préavis pour tout changement cassant. Si un jour nous devons changer quelque chose de façon incompatible, la version précédente continue de fonctionner pendant au moins six mois à compter de l'annonce, et nous vous prévenons par e-mail à l'adresse de votre compte.

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ètreAjouter un nouvel endpoint
Retirer ou renommer un champ de réponseAjouter un champ à la réponse
Changer le type ou le sens d'un champAjouter un paramètre optionnel
Changer la valeur par défaut d'un paramètreAjouter une voix ou une langue
Rendre obligatoire ce qui était optionnelAjouter un en-tête de réponse
Remplacer un code d'erreur par un autreAmé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.

Et il y a une page d'état publique : uttera.ai/fr/status. Elle vérifie l'API en direct et porte l'historique des incidents, avec la durée et la cause de chacun. Chaque interruption qui a affecté des requêtes de clients est publiée, y compris les courtes : un historique qui ne montre que les grosses pannes ne sert à rien pour juger un fournisseur.

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 :

QuoiPour quoiÉtat
WebhooksPour vous notifier quand une longue tâche se termine, au lieu de garder la connexion ouverteÀ décider
Dictionnaire de prononciationIndiquer au moteur comment se prononcent les noms propres, marques et acronymesÀ décider
Comptes de service et utilisateurs multiplesPour qu'une entreprise puisse avoir plusieurs personnes et des clés séparées sous un compteAprè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.