Référence APILive WebSocketIndex

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

  1. Connexion WS
  2. configure (obligatoire, premier message)
  3. configured
  4. Audio binaire (frames PCM)
  5. Événements transcript / batch.replace / status
  6. control avec action: "stop" puis status avec state: "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éfaut 15.0). Optionnel.
  • silence_threshold: Seuil de silence en secondes pour détection de fin de phrase (défaut 2.0). Optionnel.
  • max_buffer_size: Taille maximale du buffer de chunks (défaut 5). Optionnel.
  • flush_timeout: Timeout en secondes avant flush automatique (défaut 3.0). Optionnel.
  • gladia_endpointing: Paramètre d’endpointing pour la détection de fin de phrase (défaut 0.5). Optionnel.
  • enable_final_proofreading: Active la relecture finale pour améliorer la qualité (défaut true). Optionnel.
  • stop_delay: Délai en secondes avant arrêt pour laisser finir les traitements en cours (défaut 2.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ès configured).
  • 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 par batch.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é par batch.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_ids de l’affichage.
  • Ajouter le new_chunk à la place.
  • Le new_chunk remplace 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: message configure manquant).
  • 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

CodeDescriptionAction recommandée
AUTH_ERRORToken invalide ou expiréVérifier le token, régénérer si nécessaire
PROTOCOL_ERRORViolation du protocoleVérifier l’ordre des messages (configure en premier)
CONFIG_ERRORConfiguration invalideVérifier les paramètres de configuration
INIT_ERRORErreur d’initialisationVérifier les prérequis (format audio, etc.)
RATE_LIMITEDRate limit dépasséAttendre retry_after_ms avant de réessayer
CONCURRENCY_LIMIT_EXCEEDEDLimite de concurrence atteinteFermer une session existante ou augmenter le plan
INTERNAL_ERRORErreur interne serveurRé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 configure manquant ou envoyé après l’audio
  • Ordre des messages incorrect

Solution :

  • Toujours envoyer configure en premier
  • Attendre configured avant 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