Live WebSocket API
Cette API permet de streamer l’audio et de recevoir des événements de transcription en temps réel.
Endpoints
Init session (HTTP)
POST /api/v1/live/sessions
Authentification requise : header x-ephia-key ou Authorization: Bearer <API_KEY>
Réponse :
{
"success": true,
"session_id": "session_abc123",
"org_id": "org_xyz"
}Le session_id peut être utilisé pour le tracking, mais la connexion WebSocket se fait directement avec le token API.
WebSocket
wss://api.ephia.ai/api/v1/audio/live?token=<API_KEY>
Le token peut être passé directement dans l’URL via le paramètre token, ou via le header Authorization: Bearer <token>.
Règle d’or
Ouvrir un seul WebSocket par session et le garder ouvert jusqu’à la fin.
Protocole
Ordre des messages
- Connexion WS
configure(obligatoire, premier message)configured- Audio binaire (frames PCM)
- Événements
transcript/batch.replace/status controlavecaction: "stop"puisstatusavecstate: "stopped"et fermeture propre
Messages Client → Serveur
configure (obligatoire)
{
"type": "configure",
"config": {
"language": "fr",
"specialty": "general",
"sample_rate": 16000,
"encoding": "pcm_s16le",
"preset": "balanced",
"audio_duration_threshold": 15.0,
"silence_threshold": 2.0,
"max_buffer_size": 5,
"flush_timeout": 3.0,
"gladia_endpointing": 0.5,
"enable_final_proofreading": true,
"stop_delay": 2.0
}
}Paramètres
language:"fr" | "en" | "es" | "de"(défaut"fr").specialty:"general" | "radiology" | "cardiology" | "legal"(défaut"general").sample_rate: Taux d’échantillonnage audio en Hz (recommandé16000).encoding: Format audio ("pcm_s16le").preset: Configuration prédéfinie ("balanced" | "low_latency" | "high_quality"). Optionnel.audio_duration_threshold: Seuil de durée audio en secondes avant déclenchement (défaut15.0). Optionnel.silence_threshold: Seuil de silence en secondes pour détection de fin de phrase (défaut2.0). Optionnel.max_buffer_size: Taille maximale du buffer de chunks (défaut5). Optionnel.flush_timeout: Timeout en secondes avant flush automatique (défaut3.0). Optionnel.gladia_endpointing: Paramètre d’endpointing pour la détection de fin de phrase (défaut0.5). Optionnel.enable_final_proofreading: Active la relecture finale pour améliorer la qualité (défauttrue). Optionnel.stop_delay: Délai en secondes avant arrêt pour laisser finir les traitements en cours (défaut2.0). Optionnel.
control
Message de contrôle pour gérer l’enregistrement.
{
"type": "control",
"action": "start" | "stop" | "pause" | "resume"
}start: Démarre l’enregistrement (généralement envoyé automatiquement aprèsconfigured).stop: Arrête l’enregistrement et finalise les transcriptions en cours.pause: Met en pause l’enregistrement (le WebSocket reste ouvert).resume: Reprend l’enregistrement après une pause.
Audio binaire → serveur
- Frames PCM 16-bit little-endian.
- Sample rate recommandé : 16000 Hz.
- Channels : 1 (mono).
- Taille de chunk recommandée : ~3200 bytes (100ms à 16kHz, 16-bit, mono).
- Envoyer des chunks réguliers pour un rendu temps réel fluide.
Messages Serveur → Client
configured
Confirmation que la configuration a été acceptée.
{
"type": "configured",
"session_id": "session_abc123"
}transcript
Événements de transcription avec différents statuts.
{
"type": "transcript",
"status": "streaming" | "interim" | "final",
"text": "Scanner cérébral sans injection",
"id": "uuid-123",
"index": 0,
"seq": 1
}Statuts
streaming: Transcription partielle en cours (peut évoluer).interim: Transcription intermédiaire stabilisée (peut être remplacée par une version corrigée).final: Transcription finale confirmée (peut être remplacée parbatch.replace).
Champs
status: Statut de la transcription ("streaming" | "interim" | "final").text: Texte transcrit.id: Identifiant unique du chunk (UUID).index: Index séquentiel pour l’ordre d’affichage.seq: Numéro de séquence monotone pour ignorer les messages retardataires.
Règles d’intégration
- Si
status="streaming", l’énoncé peut évoluer : mettre à jour l’affichage en remplaçant le texte associé àid. - Si
status="interim", considérer comme transcription intermédiaire (peut être remplacée). - Si
status="final", considérer comme confirmé (peut être remplacé parbatch.replace).
batch.replace
Événement de remplacement de segments précédemment envoyés. Remplace un ou plusieurs chunks par un nouveau chunk corrigé.
{
"type": "batch.replace",
"data": {
"target_ids": ["uuid-123", "uuid-124"],
"new_chunk": {
"id": "uuid-125",
"index": 0,
"text": "Scanner cérébral sans injection de produit de contraste.",
"status": "final"
}
},
"seq": 5
}Règles d’intégration
- Supprimer les chunks avec les
target_idsde l’affichage. - Ajouter le
new_chunkà la place. - Le
new_chunkremplace définitivement les chunks précédents.
status
Message de statut pour indiquer l’état de la session.
{
"type": "status",
"state": "stopping" | "stopped",
"message": "Finalisation des transcriptions en cours...",
"metrics": {
"total_chunks": 10,
"session_duration": 120.5
}
}stopping: Le serveur est en train de finaliser les transcriptions en cours.stopped: La session est terminée. Le WebSocket sera fermé peu après.
error
Message d’erreur.
{
"type": "error",
"code": "PROTOCOL_ERROR",
"message": "Invalid message order",
"retry_after_ms": 0
}Codes d’erreur
PROTOCOL_ERROR: Violation du protocole (ex: messageconfiguremanquant).AUTH_ERROR: Erreur d’authentification.CONFIG_ERROR: Erreur de configuration.INIT_ERROR: Erreur d’initialisation.INTERNAL_ERROR: Erreur interne du serveur.
Reconnexion
Si le WebSocket se coupe, une nouvelle connexion peut être établie avec le même token. La session précédente sera nettoyée automatiquement.
Gestion des erreurs
Codes d’erreur WebSocket
| Code | Description | Action recommandée |
|---|---|---|
AUTH_ERROR | Token invalide ou expiré | Vérifier le token, régénérer si nécessaire |
PROTOCOL_ERROR | Violation du protocole | Vérifier l’ordre des messages (configure en premier) |
CONFIG_ERROR | Configuration invalide | Vérifier les paramètres de configuration |
INIT_ERROR | Erreur d’initialisation | Vérifier les prérequis (format audio, etc.) |
RATE_LIMITED | Rate limit dépassé | Attendre retry_after_ms avant de réessayer |
CONCURRENCY_LIMIT_EXCEEDED | Limite de concurrence atteinte | Fermer une session existante ou augmenter le plan |
INTERNAL_ERROR | Erreur interne serveur | Réessayer ou contacter le support |
Format des messages d’erreur
{
"type": "error",
"code": "RATE_LIMITED",
"message": "Rate limit exceeded",
"retry_after_ms": 5000,
"session_id": "session_xyz789"
}Guide de résolution rapide
AUTH_ERROR
Cause probable :
- Token manquant ou invalide
- Token expiré
- Token révoqué
Solution :
- Vérifier que le token est présent dans la requête
- Vérifier le format du token (
epk_live_...) - Régénérer une nouvelle clé API si nécessaire
PROTOCOL_ERROR
Cause probable :
- Message
configuremanquant ou envoyé après l’audio - Ordre des messages incorrect
Solution :
- Toujours envoyer
configureen premier - Attendre
configuredavant d’envoyer l’audio
RATE_LIMITED
Cause probable :
- Trop de requêtes dans la fenêtre de temps
- Limite de rate limit atteinte
Solution :
- Attendre le délai indiqué dans
retry_after_ms - Implémenter un retry avec backoff exponentiel
Exemple de code :
if (error.code === 'RATE_LIMITED') {
const delay = error.retry_after_ms || 5000;
setTimeout(() => {
// Réessayer la requête
}, delay);
}CONCURRENCY_LIMIT_EXCEEDED
Cause probable :
- Trop de sessions WebSocket simultanées
- Limite de concurrence atteinte
Solution :
- Fermer les sessions inactives
- Implémenter un pool de connexions
- Considérer l’augmentation du plan
CONFIG_ERROR
Cause probable :
- Paramètres de configuration invalides
- Valeurs hors limites
Solution :
- Vérifier tous les paramètres de
config - Consulter la documentation des paramètres
- Utiliser les valeurs par défaut recommandées
Bonnes pratiques
- ✅ Toujours vérifier les codes d’erreur
- ✅ Implémenter un retry avec backoff exponentiel
- ✅ Logger les erreurs avec contexte (session_id, timestamp)
- ✅ Afficher des messages d’erreur clairs à l’utilisateur
- ✅ Contacter le support si erreur persistante