> This is a page from the ElevenLabs documentation. For an index of the documentation, fetch https://elevenlabs.io/docs/llms.txt.

# Voximplant

> **Warning**
>
> L’intégration Voximplant est disponible de manière limitée et est activée pour chaque Workspace. Contactez votre
> représentant ElevenLabs avant d’acheminer le trafic client.

## Présentation

L’intégration Voximplant connecte directement un appel dans un scénario VoxEngine à un agent
ElevenAgents via un WebSocket, à l’aide de Voximplant Media Streams. Voximplant gère la téléphonie :
il compose ou répond à l’appel et décide de la suite. ElevenAgents gère la
conversation. Aucun trunk SIP ni middleware n’est requis.

Les appels entrants et sortants fonctionnent de la même manière : une fois l’appel connecté, le scénario ouvre un
WebSocket par appel vers ElevenLabs. Lorsque la conversation se termine, ElevenLabs envoie au scénario un unique
événement de décision indiquant s’il doit transférer l’appelant vers un intervenant humain, raccrocher ou considérer l’appel comme expiré.

## Fonctionnement de l’intégration

1. Votre scénario VoxEngine répond à un appel entrant ou en émet un sortant.
2. Le scénario ouvre un WebSocket vers l’endpoint ElevenLabs de votre agent et s’authentifie avec une
   clé API ElevenLabs comme jeton bearer.
3. Le scénario démarre le flux média avec `call.sendMediaTo()` en transmettant les éventuels `customParameters`.
   ElevenLabs transforme chaque paramètre en variable dynamique et répond avec son propre `start`.
4. Voximplant et ElevenLabs échangent de l’audio PCM linéaire 16 bits à 8 kHz dans des messages `media`.
5. Lorsque la conversation se termine, ElevenLabs envoie le reste de la dernière phrase de l’agent, un
   événement personnalisé `elevenlabs-decision` et un message `stop`. Le scénario ferme ensuite le WebSocket
   et agit selon la décision.

## Prérequis

Avant de commencer, assurez-vous de disposer des éléments suivants :

1. Un compte Voximplant avec une application, un numéro de téléphone ou la possibilité d’émettre des appels, ainsi que l’autorisation de
   modifier des scénarios.
2. Un Workspace ElevenLabs avec l’intégration Voximplant activée.
3. Un agent ElevenLabs et une clé API dédiée.

## Configurer ElevenLabs

#### Créer ou sélectionner un agent

Concevez l’agent dans ElevenAgents. Donnez-lui un premier message s’il doit parler dès que l’appel
se connecte. Les formats audio sont définis par l’intégration, les formats configurés pour l’agent ne sont donc pas utilisés
pour les appels Voximplant.

#### Activer Fin d’appel

Dans **Agent → Tools → System tools**, activez **End call** afin que l’agent puisse terminer la conversation.
La raison donnée par l’agent lorsqu’il termine l’appel est envoyée à votre scénario avec la décision.

#### Ajouter une règle de transfert Voximplant (facultatif)

Pour permettre à l’agent de transférer l’appelant vers un intervenant humain, attribuez-lui l’outil système **Transfer to number** avec une
règle de transfert dont la configuration du fournisseur est `voximplant`. Cette règle n’a pas de destination : la
conversation se termine par une décision `transfer-to-agent` et votre scénario achemine l’appelant. Les règles de transfert
se configurent via l’API. Ajoutez l’outil avec une requête `PATCH` sur l’agent :

```bash
curl -X PATCH "https://api.elevenlabs.io/v1/convai/agents/agent_7101k5zvyjhmfg983brhmhkd98n6" \
  -H "xi-api-key: $ELEVENLABS_API_KEY" -H "Content-Type: application/json" \
  -d '{
    "conversation_config": {"agent": {"prompt": {"built_in_tools": {
      "end_call": {"type": "system", "name": "end_call", "description": "",
                   "params": {"system_tool_type": "end_call"}},
      "transfer_to_number": {
        "type": "system", "name": "transfer_to_number", "description": "",
        "params": {
          "system_tool_type": "transfer_to_number",
          "transfers": [],
          "transfer_rules": [{
            "condition": "the caller asks to speak with a human",
            "provider_configs": [
              {"type": "voximplant", "config": {"type": "voximplant_handoff"}}
            ]
          }]
        }
      }
    }}}}
  }'
```

Envoyez l’objet `built_in_tools` complet de l’agent, y compris les outils dont il dispose déjà, tels que `end_call`.
L’option renvoyée par l’agent est le jeton fixe `voximplant`, une règle Voximplant par outil
suffit donc. Les numéros de téléphone et URI SIP configurés pour d’autres fournisseurs ne sont pas proposés lors des appels Voximplant.

> **Note**
>
> Les règles de transfert sont gérées via l’API. Configurez et mettez à jour via l’API l’outil **Transfer to number** d’un
> agent qui les utilise, comme ci-dessus ; l’éditeur d’outils du Dashboard fonctionne avec la
> liste de transferts par numéro.

#### Créer une clé API dédiée

Créez une clé API dans le même Workspace que l’agent et limitez-la à ElevenAgents. Pour n’accepter que les
connexions provenant de Voximplant, restreignez les adresses IP autorisées de la clé aux serveurs média de Voximplant,
que Voximplant répertorie à l’adresse
`https://api.voximplant.com/getMediaResources?with_mediaservers`.

#### Noter l’URL WebSocket

Le scénario se connecte à une URL contenant l’identifiant de votre agent :

| Environnement         | URL                                                                                                               |
| --------------------- | ----------------------------------------------------------------------------------------------------------------- |
| Par défaut            | `wss://api.elevenlabs.io/v1/convai/conversation/voximplant/agent_7101k5zvyjhmfg983brhmhkd98n6`                    |
| Résidence des données | `wss://api.<region>.residency.elevenlabs.io/v1/convai/conversation/voximplant/agent_7101k5zvyjhmfg983brhmhkd98n6` |

Pour épingler une branche de l’agent, ajoutez `?branch_id=<branch_id>`.

> **Info**
>
> Si votre compte ElevenLabs se trouve dans un environnement de résidence isolé, remplacez `<region>` par le
> code de votre région. Consultez la page sur la [résidence des données](/docs/fr/overview/administration/data-residency) pour connaître les
> régions disponibles.

## Configurer Voximplant

#### Créer une application

Dans le [panneau de contrôle Voximplant](https://manage.voximplant.com/applications), ouvrez **Applications**
et cliquez sur **Create application**. Donnez-lui un nom, par exemple `elevenlabs-agent`, puis cliquez sur
**Create**.

![Voximplant : créer une application](/docs/_fern-files/_img/29af341fa0a32eaaab444ade8305208121487413c5868597386a973b14fe4fe7.webp)

#### Enregistrer la clé API comme secret

Dans l’application, ouvrez **Secrets** et cliquez sur **Add secret**. Nommez-le `ELEVENLABS_API_KEY`, collez
la clé API créée pour le Workspace de l’agent dans **Value**, puis cliquez sur **Add secret**. Le
scénario la lit avec `VoxEngine.getSecretValue()`, la clé n’apparaît donc jamais dans le code du scénario.

![Voximplant : ajouter un secret](/docs/_fern-files/_img/ecf8be823bbc15b263e3f4838684a78de3a3594704be0055b443d15ab93e1485.webp)

#### Créer le scénario

Ouvrez **Scenarios**, cliquez sur **Create scenario**, nommez-le `elevenlabs_agent`, collez le code ci-dessous,
remplacez l’identifiant de l’agent dans `ELEVENLABS_URL`, puis cliquez sur **Save**. Il répond à un appel entrant, le transmet
à l’agent et agit selon la décision lorsque la conversation se termine. Pour un appel sortant, ouvrez
le WebSocket dans le gestionnaire `CallEvents.Connected` de l’appel que vous avez émis.

```javascript maxLines=0
const ELEVENLABS_URL =
  "wss://api.elevenlabs.io/v1/convai/conversation/voximplant/agent_7101k5zvyjhmfg983brhmhkd98n6";

VoxEngine.addEventListener(AppEvents.CallAlerting, ({ call }) => {
  call.answer();
  let decision = null;

  const ws = VoxEngine.createWebSocket(ELEVENLABS_URL, {
    headers: [
      {
        name: "Authorization",
        value: `Bearer ${VoxEngine.getSecretValue("ELEVENLABS_API_KEY")}`,
      },
    ],
  });

  ws.addEventListener(WebSocketEvents.OPEN, () => {
    call.sendMediaTo(ws, {
      encoding: WebSocketAudioEncoding.PCM16_8KHZ,
      customParameters: { customer_name: "Ana", task_id: "task-7" },
    });
    ws.sendMediaTo(call);
  });

  ws.addEventListener(WebSocketEvents.MESSAGE, ({ text }) => {
    const message = JSON.parse(text);
    if (message.customEvent === "elevenlabs-decision") {
      decision = message.payload;
      Logger.write(`ElevenLabs decision: ${JSON.stringify(decision)}`);
    }
  });

  ws.addEventListener(WebSocketEvents.CLOSE, (e) => {
    Logger.write(`ElevenLabs socket closed: code=${e.code} reason=${e.reason}`);
    if (decision?.action === "transfer-to-agent") {
      // Route the caller to a human here, for example with VoxEngine.callPSTN().
      call.say("Connecting you to an agent.", { language: VoiceList.Amazon.en_US_Joanna });
      call.addEventListener(CallEvents.PlaybackFinished, () => call.hangup());
      return;
    }
    call.hangup();
  });

  call.addEventListener(CallEvents.Disconnected, () => {
    ws.close();
    VoxEngine.terminate();
  });
});
```

![Voximplant : le scénario dans l’éditeur](/docs/_fern-files/_img/d2e26165f57cae40fc01e8de28052fef09b2f98bd90c0e1a8779423715f61e2e.webp)

#### Acheminer les appels vers le scénario

Ouvrez **Routing**, cliquez sur **Create rule**, donnez-lui un nom et attribuez-lui le scénario
`elevenlabs_agent`. Le modèle par défaut `.*` envoie chaque appel vers l’application par le scénario ;
restreignez-le à un numéro de téléphone si l’application traite également d’autres appels. Pour acheminer un numéro de téléphone,
associez-le à l’application sous **Numbers**.

![Voximplant : créer une règle](/docs/_fern-files/_img/bc6830b7dcd66dc0b59595456b1197bdcbb9174f15778da7ba9655ba4b93936e.webp)

#### Effectuer un appel de test

Vous pouvez appeler l’application depuis le navigateur sans numéro de téléphone :

1. Ouvrez **Users**, cliquez sur **Create user** et créez un utilisateur avec un mot de passe.

   ![Voximplant : nouvel utilisateur](/docs/_fern-files/_img/4754c9234588fd0caa336e1168e207b265557dc4e6a12b1cf8bced1275b8bae6.webp)

2. Dans **Routing**, cliquez sur **Test tools**, puis sur **Softphone**. Connectez-vous avec cet utilisateur, autorisez
   l’accès au microphone, saisissez n’importe quelle destination et appelez. L’agent répond avec son premier message.

3. À la fin de l’appel, ouvrez **Call history**. Chaque appel répertorie une connexion WebSocket à côté de l’appel
   lui-même. Cliquez sur **View log** pour afficher la session.

   ![Voximplant : historique des appels](/docs/_fern-files/_img/4e2416ad3587bb320300173cf679f7c5d7a5e545550b0a647062a79866dac40c.webp)

   Le journal affiche la décision envoyée par ElevenLabs, la fermeture du WebSocket et l’action effectuée ensuite par le scénario.
   Dans cet exemple, l’appelant a demandé à parler à une personne, la décision est donc `transfer-to-agent`
   avec la raison fournie par l’agent.

   ![Voximplant : journal de session avec l’événement
   elevenlabs-decision](/docs/_fern-files/_img/f8b4602fa02cfd3c417557377aaa5dd66e2e88a67e7adf4cb037ccae1840f45c.webp)

> **Warning**
>
> Agissez sur l’événement `elevenlabs-decision`, et non sur `MEDIA_ENDED`. Voximplant déclenche `MEDIA_ENDED` après
> environ une seconde sans audio provenant d’ElevenLabs, ce qui peut se produire au milieu d’une conversation.

## Variables dynamiques

Chaque clé de `customParameters` devient une variable dynamique du même nom. Les valeurs qui ne sont pas des
chaînes sont converties en texte, par exemple `true` devient `"true"`. `customParameters` peut être un
objet ou une chaîne encodée en JSON. Les clés commençant par `system__` ou `integration__` sont réservées et
sont ignorées.

## Événements de décision

Lorsque la conversation se termine, ElevenLabs envoie exactement une décision avant son message `stop` :

```json
{ "customEvent": "elevenlabs-decision", "payload": { "action": "terminate", "reason": "under_18" } }
```

| `action`            | Quand elle est envoyée                                                                                                                                                                                               | `reason`                                                        |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| `transfer-to-agent` | L’agent a appelé **Transfer to number** avec une règle de transfert Voximplant.                                                                                                                                      | La raison donnée par l’agent pour le transfert.                 |
| `timeout`           | La conversation a expiré en raison du silence ou après le dernier message de l’agent, ou l’agent a terminé l’appel après 15 secondes de silence de l’appelant, sans compter le temps pendant lequel l’agent parlait. | Le message d’expiration ou la raison donnée par l’agent.        |
| `terminate`         | L’agent a terminé l’appel avec **End call**, ou la conversation s’est terminée normalement.                                                                                                                          | La raison donnée par l’agent avec **End call**, le cas échéant. |
| `unexpected`        | La conversation s’est terminée à cause d’une erreur.                                                                                                                                                                 | Une description de l’erreur.                                    |

Si le scénario envoie `stop` ou ferme d’abord le WebSocket, par exemple parce que l’appelant a raccroché,
ElevenLabs n’envoie aucune décision.

## Audio

Voximplant et ElevenLabs échangent de l’audio PCM linéaire mono 16 bits à 8 kHz dans les deux sens. ElevenLabs
cadence l’audio de l’agent presque en temps réel, de sorte que lorsque l’appelant interrompt l’agent, au maximum environ
0,4 seconde de la réponse interrompue est encore diffusée.

## Erreurs d’authentification

ElevenLabs ferme le WebSocket avec le code `1008` et la raison `bad auth token` lorsque l’en-tête
`Authorization` est absent ou mal formé, que la clé API est invalide ou non autorisée depuis l’adresse IP de
connexion, que la clé appartient à un autre Workspace ou que l’utilisateur de la clé ne peut pas accéder à un
agent dont l’authentification est activée.

## Limites et fonctionnalités non prises en charge

* Les outils client et l’outil système **Play keypad touch tone** ne sont pas pris en charge. **Transfer to
  number** fonctionne uniquement via une règle de transfert Voximplant ; le scénario décide où est dirigé l’appelant.
* Les substitutions de configuration, comme un premier message différent, ne peuvent pas être transmises depuis le scénario ;
  seules les variables dynamiques le peuvent.
* Les résultats de collecte de données ne sont pas envoyés au scénario. Utilisez le
  [webhook post-appel](/docs/fr/eleven-agents/workflows/post-call-webhooks) pour les récupérer.