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

# Voximplant

> **Warning**
>
> Voximplant-integrationen är tillgänglig i begränsad omfattning och aktiveras per arbetsyta. Kontakta din
> representant på ElevenLabs innan du dirigerar kundtrafik.

## Översikt

Voximplant-integrationen kopplar ett samtal i ett VoxEngine-scenario direkt till en agent i
ElevenAgents via en WebSocket med Voximplant Media Streams. Voximplant ansvarar för telefonin:
det ringer upp eller besvarar samtalet och avgör vad som händer efteråt. ElevenAgents ansvarar för
samtalet. Ingen SIP-trunk eller mellanprogramvara krävs.

Inkommande och utgående samtal fungerar på samma sätt: när samtalet har kopplats upp öppnar scenariot en
WebSocket per samtal till ElevenLabs. När samtalet avslutas skickar ElevenLabs en enda
beslutshändelse till scenariot som anger om uppringaren ska kopplas till en människa, samtalet ska avslutas eller samtalet ska
hanteras som en timeout.

## Så fungerar integrationen

1. Ditt VoxEngine-scenario besvarar ett inkommande samtal eller ringer upp ett utgående.
2. Scenariot öppnar en WebSocket till ElevenLabs-slutpunkten för din agent och autentiserar med en
   ElevenLabs API-nyckel som bearer-token.
3. Scenariot startar medieströmmen med `call.sendMediaTo()` och skickar med eventuella `customParameters`.
   ElevenLabs omvandlar varje parameter till en dynamisk variabel och svarar med ett eget `start`.
4. Voximplant och ElevenLabs utbyter 16-bitars linjärt PCM-ljud vid 8 kHz i `media`-meddelanden.
5. När samtalet avslutas skickar ElevenLabs resten av agentens sista fras, en
   `elevenlabs-decision`-anpassad händelse och ett `stop`-meddelande. Scenariot stänger sedan WebSocket-anslutningen
   och agerar utifrån beslutet.

## Krav

Innan du börjar behöver du ha:

1. Ett Voximplant-konto med en applikation, ett telefonnummer eller utgående samtal samt behörighet att
   redigera scenarier.
2. En ElevenLabs-arbetsyta där Voximplant-integrationen är aktiverad.
3. En ElevenLabs-agent och en dedikerad API-nyckel.

## Konfigurera ElevenLabs

#### Skapa eller välj en agent

Skapa agenten i ElevenAgents. Ge den ett första meddelande om den ska tala så snart samtalet
kopplas upp. Ljudformat ställs in av integrationen, så agentens konfigurerade format används inte
för Voximplant-samtal.

#### Aktivera Avsluta samtal

Under **Agent → Tools → System tools** aktiverar du **End call** så att agenten kan avsluta samtalet.
Skälet som agenten anger när den avslutar samtalet skickas till ditt scenario med beslutet.

#### Lägg till en Voximplant-överföringsregel (valfritt)

För att låta agenten koppla uppringaren till en människa ger du den systemverktyget **Transfer to number** med en
överföringsregel vars leverantörskonfiguration är `voximplant`. Regeln har ingen destination: samtalet
avslutas med beslutet `transfer-to-agent` och ditt scenario dirigerar uppringaren. Överföringsregler
konfigureras via API:t. Lägg till verktyget med en `PATCH` på agenten:

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

Skicka agentens fullständiga `built_in_tools`-objekt, inklusive verktyg som den redan har, till exempel `end_call`.
Alternativet som agenten skickar tillbaka är den fasta token `voximplant`, så en Voximplant-regel per verktyg
räcker. Telefonnummer och SIP-URI:er som konfigurerats för andra leverantörer erbjuds inte i Voximplant-
samtal.

> **Note**
>
> Överföringsregler är en API-hanterad inställning. Konfigurera och uppdatera verktyget **Transfer to number** för
> en agent som använder dem via API:t enligt ovan; instrumentpanelens verktygsredigerare fungerar med
> överföringslistan per nummer.

#### Skapa en dedikerad API-nyckel

Skapa en API-nyckel i samma arbetsyta som agenten och begränsa den till ElevenAgents. För att endast acceptera
anslutningar från Voximplant begränsar du nyckelns tillåtna IP-adresser till Voximplants medieservrar,
som Voximplant listar på
`https://api.voximplant.com/getMediaResources?with_mediaservers`.

#### Notera WebSocket-URL:en

Scenariot ansluter till en URL som innehåller ditt agent-ID:

| Miljö        | URL                                                                                                               |
| ------------ | ----------------------------------------------------------------------------------------------------------------- |
| Standard     | `wss://api.elevenlabs.io/v1/convai/conversation/voximplant/agent_7101k5zvyjhmfg983brhmhkd98n6`                    |
| Dataresidens | `wss://api.<region>.residency.elevenlabs.io/v1/convai/conversation/voximplant/agent_7101k5zvyjhmfg983brhmhkd98n6` |

För att låsa en gren av agenten lägger du till `?branch_id=<branch_id>`.

> **Info**
>
> Om ditt ElevenLabs-konto finns i en isolerad dataresidensmiljö ersätter du `<region>` med din
> regionskod. Se [dataresidens](/docs/sv/overview/administration/data-residency) för tillgängliga
> regioner.

## Konfigurera Voximplant

#### Skapa en applikation

I [Voximplant-kontrollpanelen](https://manage.voximplant.com/applications) öppnar du **Applications**
och klickar på **Create application**. Ge den ett namn, till exempel `elevenlabs-agent`, och klicka på
**Create**.

![Voximplant: Skapa applikation](/docs/_fern-files/_img/29af341fa0a32eaaab444ade8305208121487413c5868597386a973b14fe4fe7.webp)

#### Spara API-nyckeln som en hemlighet

I applikationen öppnar du **Secrets** och klickar på **Add secret**. Ge den namnet `ELEVENLABS_API_KEY`, klistra in
API-nyckeln som du skapade för agentens arbetsyta i **Value** och klicka på **Add secret**.
Scenariot läser den med `VoxEngine.getSecretValue()`, så nyckeln visas aldrig i scenariokoden.

![Voximplant: Lägg till hemlighet](/docs/_fern-files/_img/ecf8be823bbc15b263e3f4838684a78de3a3594704be0055b443d15ab93e1485.webp)

#### Skapa scenariot

Öppna **Scenarios**, klicka på **Create scenario**, ge det namnet `elevenlabs_agent`, klistra in koden nedan,
ersätt agent-ID:t i `ELEVENLABS_URL` och klicka på **Save**. Det besvarar ett inkommande samtal, strömmar
samtalet till agenten och agerar på beslutet när samtalet avslutas. För ett utgående samtal öppnar du
WebSocket-anslutningen i hanteraren `CallEvents.Connected` för samtalet du ringde upp.

```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: scenariot i redigeraren](/docs/_fern-files/_img/d2e26165f57cae40fc01e8de28052fef09b2f98bd90c0e1a8779423715f61e2e.webp)

#### Dirigera samtal till scenariot

Öppna **Routing**, klicka på **Create rule**, ge regeln ett namn och tilldela scenariot `elevenlabs_agent`.
Standardmönstret `.*` skickar varje samtal till applikationen via scenariot; begränsa det till ett telefonnummer
om applikationen även hanterar andra samtal. För att dirigera ett telefonnummer kopplar du det till applikationen
under **Numbers**.

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

#### Ring ett testsamtal

Du kan ringa applikationen från webbläsaren utan ett telefonnummer:

1. Öppna **Users**, klicka på **Create user** och skapa en användare med ett lösenord.

   ![Voximplant: Ny användare](/docs/_fern-files/_img/4754c9234588fd0caa336e1168e207b265557dc4e6a12b1cf8bced1275b8bae6.webp)

2. I **Routing** klickar du på **Test tools** och sedan på **Softphone**. Logga in som den användaren, tillåt
   åtkomst till mikrofonen, ange valfri destination och ring. Agenten svarar med sitt första meddelande.

3. När samtalet avslutas öppnar du **Call history**. Varje samtal visar en WebSocket-koppling bredvid själva
   samtalet. Klicka på **View log** för att se sessionen.

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

   Loggen visar beslutet som ElevenLabs skickade, när WebSocket-anslutningen stängdes och vad scenariot gjorde
   sedan. I det här exemplet bad uppringaren om en person, så beslutet är `transfer-to-agent`
   med skälet som agenten angav.

   ![Voximplant: Sessionslogg med händelsen elevenlabs-decision
   ](/docs/_fern-files/_img/f8b4602fa02cfd3c417557377aaa5dd66e2e88a67e7adf4cb037ccae1840f45c.webp)

> **Warning**
>
> Agera på händelsen `elevenlabs-decision`, inte på `MEDIA_ENDED`. Voximplant utlöser `MEDIA_ENDED` efter
> ungefär en sekund utan ljud från ElevenLabs, vilket kan hända mitt i ett samtal.

## Dynamiska variabler

Varje nyckel i `customParameters` blir en dynamisk variabel med samma namn. Värden som inte är
strängar omvandlas till text, till exempel blir `true` till `"true"`. `customParameters` kan vara ett
objekt eller en JSON-kodad sträng. Nycklar som börjar med `system__` eller `integration__` är reserverade och
utelämnas.

## Beslutshändelser

När samtalet avslutas skickar ElevenLabs exakt ett beslut före sitt `stop`-meddelande:

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

| `action`            | När det skickas                                                                                                                                                                             | `reason`                                                     |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
| `transfer-to-agent` | Agenten anropade **Transfer to number** med en Voximplant-överföringsregel.                                                                                                                 | Skälet som agenten angav för överföringen.                   |
| `timeout`           | Samtalet fick timeout vid tystnad eller efter agentens sista meddelande, eller agenten avslutade samtalet efter 15 sekunders tystnad från uppringaren, utan att räkna tiden agenten talade. | Timeout-meddelandet eller skälet som agenten angav.          |
| `terminate`         | Agenten avslutade samtalet med **End call**, eller samtalet avslutades normalt.                                                                                                             | Skälet som agenten angav med **End call**, om det finns ett. |
| `unexpected`        | Samtalet avslutades på grund av ett fel.                                                                                                                                                    | En beskrivning av felet.                                     |

Om scenariot skickar `stop` eller stänger WebSocket-anslutningen först, till exempel eftersom uppringaren lade på,
skickar ElevenLabs inget beslut.

## Ljud

Voximplant och ElevenLabs utbyter 16-bitars mono linjärt PCM vid 8 kHz i båda riktningarna. ElevenLabs
synkroniserar agentens ljud nära realtid, så när uppringaren avbryter agenten spelas högst ungefär
0,4 sekunder av det avbrutna svaret fortfarande upp.

## Autentiseringsfel

ElevenLabs stänger WebSocket-anslutningen med kod `1008` och anledningen `bad auth token` när
`Authorization`-huvudet saknas eller är felaktigt, API-nyckeln är ogiltig eller inte tillåts från den
anslutande IP-adressen, nyckeln tillhör en annan arbetsyta eller nyckelns användare inte kan komma åt en
agent som har autentisering aktiverad.

## Begränsningar och funktioner som inte stöds

* Klientverktyg och systemverktyget **Play keypad touch tone** stöds inte. **Transfer to
  number** fungerar endast via en Voximplant-överföringsregel; scenariot avgör vart uppringaren
  går.
* Konfigurationsåsidosättningar, som ett annat första meddelande, kan inte skickas från scenariot;
  endast dynamiska variabler kan det.
* Resultat från datainsamling skickas inte till scenariot. Använd
  [webhook efter samtal](/docs/sv/eleven-agents/workflows/post-call-webhooks) för dem.