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

# Voximplant

> **Warning**
>
> La integración con Voximplant tiene disponibilidad limitada y se habilita por espacio de trabajo. Contacta con tu
> representante de ElevenLabs antes de enrutar tráfico de clientes.

## Resumen

La integración con Voximplant conecta una llamada en un escenario de VoxEngine directamente con un agente de
ElevenAgents a través de un WebSocket, mediante Voximplant Media Streams. Voximplant se encarga de la telefonía:
marca o responde la llamada y decide qué sucede después. ElevenAgents se encarga de la
conversación. No se necesita ningún troncal SIP ni middleware.

Las llamadas entrantes y salientes funcionan del mismo modo: cuando se conecta la llamada, el escenario abre un
WebSocket por llamada a ElevenLabs. Cuando termina la conversación, ElevenLabs envía al escenario un único
evento de decisión que indica si debe transferir a quien llama a una persona, colgar o tratar la llamada como un
tiempo de espera agotado.

## Cómo funciona la integración

1. Tu escenario de VoxEngine responde una llamada entrante o realiza una saliente.
2. El escenario abre un WebSocket al endpoint de ElevenLabs de tu agente y se autentica con una
   clave de API de ElevenLabs como token bearer.
3. El escenario inicia el flujo de medios con `call.sendMediaTo()` y pasa los `customParameters`.
   ElevenLabs convierte cada parámetro en una variable dinámica y responde con su propio `start`.
4. Voximplant y ElevenLabs intercambian audio PCM lineal de 16 bits a 8 kHz en mensajes `media`.
5. Cuando termina la conversación, ElevenLabs envía el resto de la última frase del agente, un
   evento personalizado `elevenlabs-decision` y un mensaje `stop`. A continuación, el escenario cierra el WebSocket
   y actúa según la decisión.

## Requisitos

Antes de empezar, asegúrate de tener:

1. Una cuenta de Voximplant con una aplicación, un número de teléfono o llamadas salientes, y permisos para
   editar escenarios.
2. Un espacio de trabajo de ElevenLabs con la integración de Voximplant habilitada.
3. Un agente de ElevenLabs y una clave de API específica.

## Configura ElevenLabs

#### Crea o selecciona un agente

Crea el agente en ElevenAgents. Dale un primer mensaje si debe hablar en cuanto se conecte la llamada.
Los formatos de audio los establece la integración, por lo que los formatos configurados del agente no se usan
para las llamadas de Voximplant.

#### Activa Finalizar llamada

En **Agente → Herramientas → Herramientas del sistema**, activa **Finalizar llamada** para que el agente pueda terminar la conversación.
El motivo que indique el agente al finalizar la llamada se envía a tu escenario junto con la decisión.

#### Añade una regla de transferencia de Voximplant (opcional)

Para que el agente pueda transferir a quien llama a una persona, asígnale la herramienta del sistema **Transferir a número** con una
regla de transferencia cuya configuración de proveedor sea `voximplant`. La regla no tiene destino: la
conversación termina con una decisión `transfer-to-agent` y tu escenario enruta a quien llama. Las reglas de transferencia
se configuran mediante la API. Añade la herramienta mediante un `PATCH` en el agente:

```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"}}
            ]
          }]
        }
      }
    }}}}
  }'
```

Envía el objeto `built_in_tools` completo del agente, incluidas las herramientas que ya tenga, como `end_call`.
La opción que el agente devuelve es el token fijo `voximplant`, por lo que basta con una regla de Voximplant por herramienta.
Los números de teléfono y URI SIP configurados para otros proveedores no se ofrecen en llamadas de Voximplant.

> **Note**
>
> Las reglas de transferencia son una configuración gestionada mediante API. Configura y actualiza mediante la API la herramienta
> **Transferir a número** de un agente que las use, como se indicó antes; el editor de herramientas del panel funciona con la
> lista de transferencias por número.

#### Crea una clave de API específica

Crea una clave de API en el mismo espacio de trabajo que el agente y limita su alcance a ElevenAgents. Para aceptar
conexiones solo de Voximplant, restringe las direcciones IP permitidas de la clave a los servidores de medios de Voximplant,
que Voximplant enumera en
`https://api.voximplant.com/getMediaResources?with_mediaservers`.

#### Anota la URL de WebSocket

El escenario se conecta a una URL que contiene el ID de tu agente:

| Entorno             | URL                                                                                                               |
| ------------------- | ----------------------------------------------------------------------------------------------------------------- |
| Predeterminado      | `wss://api.elevenlabs.io/v1/convai/conversation/voximplant/agent_7101k5zvyjhmfg983brhmhkd98n6`                    |
| Residencia de datos | `wss://api.<region>.residency.elevenlabs.io/v1/convai/conversation/voximplant/agent_7101k5zvyjhmfg983brhmhkd98n6` |

Para fijar una rama del agente, añade `?branch_id=<branch_id>`.

> **Info**
>
> Si tu cuenta de ElevenLabs está en un entorno de residencia aislado, sustituye `<region>` por el
> código de tu región. Consulta [residencia de datos](/docs/es/overview/administration/data-residency) para ver las regiones
> disponibles.

## Configura Voximplant

#### Crea una aplicación

En el [panel de control de Voximplant](https://manage.voximplant.com/applications), abre **Applications**
y haz clic en **Create application**. Ponle un nombre, por ejemplo `elevenlabs-agent`, y haz clic en
**Create**.

![Voximplant: Crear aplicación](/docs/_fern-files/_img/29af341fa0a32eaaab444ade8305208121487413c5868597386a973b14fe4fe7.webp)

#### Guarda la clave de API como secreto

En la aplicación, abre **Secrets** y haz clic en **Add secret**. Llámalo `ELEVENLABS_API_KEY`, pega
la clave de API que creaste para el espacio de trabajo del agente en **Value** y haz clic en **Add secret**. El
escenario la lee con `VoxEngine.getSecretValue()`, por lo que la clave nunca aparece en el código del escenario.

![Voximplant: Añadir secreto](/docs/_fern-files/_img/ecf8be823bbc15b263e3f4838684a78de3a3594704be0055b443d15ab93e1485.webp)

#### Crea el escenario

Abre **Scenarios**, haz clic en **Create scenario**, llámalo `elevenlabs_agent`, pega el código siguiente,
sustituye el ID del agente en `ELEVENLABS_URL` y haz clic en **Save**. Responde una llamada entrante, la transmite
al agente y actúa según la decisión cuando termina la conversación. Para una llamada saliente, abre
el WebSocket en el controlador `CallEvents.Connected` de la llamada que realizaste.

```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: el escenario en el editor](/docs/_fern-files/_img/d2e26165f57cae40fc01e8de28052fef09b2f98bd90c0e1a8779423715f61e2e.webp)

#### Enruta llamadas al escenario

Abre **Routing**, haz clic en **Create rule**, ponle un nombre y asigna el escenario
`elevenlabs_agent`. El patrón predeterminado `.*` envía todas las llamadas a la aplicación a través del escenario;
limítalo a un número de teléfono si la aplicación también gestiona otras llamadas. Para enrutar un número de teléfono,
asócialo a la aplicación en **Numbers**.

![Voximplant: Crear regla](/docs/_fern-files/_img/bc6830b7dcd66dc0b59595456b1197bdcbb9174f15778da7ba9655ba4b93936e.webp)

#### Haz una llamada de prueba

Puedes llamar a la aplicación desde el navegador sin un número de teléfono:

1. Abre **Users**, haz clic en **Create user** y crea un usuario con contraseña.

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

2. En **Routing**, haz clic en **Test tools** y luego en **Softphone**. Inicia sesión como ese usuario, permite
   el acceso al micrófono, introduce cualquier destino y llama. El agente responde con su primer mensaje.

3. Cuando termine la llamada, abre **Call history**. Cada llamada muestra una conexión WebSocket junto a la llamada
   propiamente dicha. Haz clic en **View log** para ver la sesión.

   ![Voximplant: Historial de llamadas](/docs/_fern-files/_img/4e2416ad3587bb320300173cf679f7c5d7a5e545550b0a647062a79866dac40c.webp)

   El registro muestra la decisión que envió ElevenLabs, el cierre del WebSocket y lo que hizo el escenario
   después. En este ejemplo, quien llamó pidió hablar con una persona, por lo que la decisión es `transfer-to-agent`
   con el motivo indicado por el agente.

   ![Voximplant: Registro de sesión con el evento
   elevenlabs-decision](/docs/_fern-files/_img/f8b4602fa02cfd3c417557377aaa5dd66e2e88a67e7adf4cb037ccae1840f45c.webp)

> **Warning**
>
> Actúa según el evento `elevenlabs-decision`, no según `MEDIA_ENDED`. Voximplant activa `MEDIA_ENDED` tras
> aproximadamente un segundo sin audio de ElevenLabs, lo que puede ocurrir en mitad de una conversación.

## Variables dinámicas

Cada clave de `customParameters` se convierte en una variable dinámica con el mismo nombre. Los valores que no son
cadenas se convierten en texto; por ejemplo, `true` se convierte en `"true"`. `customParameters` puede ser un
objeto o una cadena codificada en JSON. Las claves que empiezan por `system__` o `integration__` están reservadas y
se descartan.

## Eventos de decisión

Cuando termina la conversación, ElevenLabs envía exactamente una decisión antes de su mensaje `stop`:

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

| `action`            | Cuándo se envía                                                                                                                                                                                                         | `reason`                                                                   |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| `transfer-to-agent` | El agente llamó a **Transferir a número** con una regla de transferencia de Voximplant.                                                                                                                                 | El motivo que dio el agente para la transferencia.                         |
| `timeout`           | La conversación agotó el tiempo de espera por silencio o después del último mensaje del agente, o el agente terminó la llamada tras 15 segundos de silencio de quien llamó, sin contar el tiempo que hablaba el agente. | El mensaje de tiempo de espera agotado o el motivo indicado por el agente. |
| `terminate`         | El agente terminó la llamada con **Finalizar llamada** o la conversación terminó con normalidad.                                                                                                                        | El motivo indicado por el agente con **Finalizar llamada**, si lo hay.     |
| `unexpected`        | La conversación terminó debido a un error.                                                                                                                                                                              | Una descripción del error.                                                 |

Si el escenario envía `stop` o cierra primero el WebSocket, por ejemplo porque quien llamó colgó,
ElevenLabs no envía ninguna decisión.

## Audio

Voximplant y ElevenLabs intercambian PCM lineal mono de 16 bits a 8 kHz en ambas direcciones. ElevenLabs
reproduce el audio del agente casi en tiempo real, por lo que, cuando quien llama interrumpe al agente, se reproduce como mucho
unos 0,4 segundos de la respuesta interrumpida.

## Errores de autenticación

ElevenLabs cierra el WebSocket con el código `1008` y el motivo `bad auth token` cuando falta el encabezado
`Authorization` o tiene un formato incorrecto, la clave de API no es válida o no está permitida desde la dirección IP
que se conecta, la clave pertenece a otro espacio de trabajo o el usuario de la clave no puede acceder a un
agente que tiene la autenticación habilitada.

## Limitaciones y funciones no compatibles

* Las herramientas de cliente y la herramienta del sistema **Reproducir tono de teclado** no son compatibles. **Transferir a
  número** solo funciona mediante una regla de transferencia de Voximplant; el escenario decide adónde
  va quien llama.
* No se pueden pasar anulaciones de configuración desde el escenario, como un primer mensaje diferente;
  solo variables dinámicas.
* Los resultados de recopilación de datos no se envían al escenario. Usa el
  [webhook posterior a la llamada](/docs/es/eleven-agents/workflows/post-call-webhooks) para obtenerlos.