> This is a page from the ElevenLabs documentation. For a complete page index, fetch https://elevenlabs.io/docs/llms.txt. For the full documentation in a single file, fetch https://elevenlabs.io/docs/llms-full.txt.

# OpenTelemetry-traces

ElevenLabs Agents kan gesprekken exporteren als **OpenTelemetry-traces**, gecodeerd als **OTLP JSON** (`resourceSpans`). Stuur ze door naar Datadog, Grafana Tempo, Honeycomb of een andere backend die OTLP verwerkt.

> **Info**
>
> ElevenLabs stuurt traces niet rechtstreeks naar je OTLP-collector. Je ontvangt JSON in OTLP-indeling via
> een webhook, API of monitoring-WebSocket en stuurt die door naar je backend.

## Overzicht

Exporteer traces via drie manieren. Alle drie gebruiken dezelfde **trace-ID per gesprek** en de naamgeving voor attributen `elevenlabs.*`. De vorm en timing van spans verschillen tussen na het gesprek/GET (op basis van het transcript) en monitoring (op basis van gebeurtenissen).

### Exportmethoden

| Methode              | Wanneer je gegevens ontvangt                          | Het beste voor                                     |
| -------------------- | ----------------------------------------------------- | -------------------------------------------------- |
| Webhook na gesprek   | Nadat het gesprek is beëindigd en de analyse klaar is | Batchpipelines, facturering en QA, duurzame opslag |
| GET conversation API | Op aanvraag, nadat het gesprek bestaat                | Backfill, debugging, opnieuw verwerken             |
| Monitoring-WebSocket | Tijdens een live gesprek                              | Live dashboards, waarschuwingen, human-in-the-loop |

### Een methode kiezen

* **Elk voltooid gesprek in je datawarehouse**: webhook na gesprek
* **Eenmalige export of herstel**: GET conversation met `format=opentelemetry`
* **Live supervisor-UI of waarschuwingen**: monitoring-WebSocket
* **Tijdlijn met volledige details achteraf**: webhook na gesprek of GET conversation
* **Tool-, MCP- of guardrail-gebeurtenissen op het moment dat ze plaatsvinden**: monitoring-WebSocket

Gebruik `traceId` of `elevenlabs.conversation_id` om gegevens van verschillende methoden te koppelen. Combineer monitoring voor live activiteiten, webhooks voor duurzame analyses en GET voor backfill.

Voor elke methode heb je een OTLP-compatibele collector of observability-provider nodig. Webhooks na gesprekken vereisen een webhookendpoint voor de workspace. De GET API en monitoring-WebSocket hebben elk hun eigen API-keyscopes en configuratie; zie de onderstaande secties.

## Webhook na gesprek

Nadat een gesprek is afgerond, verstuurt ElevenLabs een `POST`-request wanneer een webhook na het gesprek is geconfigureerd, `events` `transcript` bevat en `transcript_format` is ingesteld op `opentelemetry`.

Het webhook-`type` is `post_call_transcription_otel` (niet `post_call_transcription`, dat JSON-transcripten retourneert).

### Webhookpayload

```json
{
  "type": "post_call_transcription_otel",
  "event_timestamp": 1700000000,
  "data": {
    "conversation_id": "conv_9001k1zph3fkeh5s8xg9z90swaqa",
    "agent_id": "agent_7101k5zvyjhmfg983brhmhkd98n6",
    "otlp_traces": {
      "resourceSpans": []
    }
  }
}
```

### OpenTelemetry-transcripten inschakelen

#### Configureren via het dashboard

### Een workspace-webhook maken

Maak in het ElevenAgents Dashboard een workspace-webhook met je HTTPS-URL en authenticatie.

### De webhook na het gesprek koppelen

Open [Agents-instellingen](https://elevenlabs.io/app/agents/settings), wijs de webhook toe als webhook na het gesprek, schakel de gebeurtenis **Transcript** in en zet **OpenTelemetry-transcriptpayloads** aan.

![Instellingen voor webhook na gesprek](/docs/_fern-img/eb5d768612d6461a21bc3127611f60724be3e1a55005af43faf48f2d7bf23807.webp)

#### Configureren via de CLI

> **Note**
>
> Workspacebrede webhooks na gesprekken configureer je via het Dashboard of de API-tab. Gebruik de CLI om
> webhookinstellingen voor een specifieke agent te overschrijven.

### De agentconfiguratie ophalen

```bash
elevenlabs agents pull --agent "<agent-name>"
```

### `agent_configs/<agent-name>.json` bewerken

Stel `platform_settings.workspace_overrides.webhooks` in:

```json
{
  "platform_settings": {
    "workspace_overrides": {
      "webhooks": {
        "post_call_webhook_id": "wh_01jqz7x8y9z0a1b2c3d4e5f6",
        "events": ["transcript"],
        "transcript_format": "opentelemetry"
      }
    }
  }
}
```

### Je wijzigingen pushen

```bash
elevenlabs agents push --agent "<agent-name>"
```

#### Configureren via de API

**`Python`**

```python title="Python"
import os

from dotenv import load_dotenv
from elevenlabs import ElevenLabs

load_dotenv()
elevenlabs = ElevenLabs(api_key=os.getenv("ELEVENLABS_API_KEY"))

elevenlabs.conversational_ai.settings.update(
    webhooks={
        "post_call_webhook_id": "wh_01jqz7x8y9z0a1b2c3d4e5f6",
        "events": ["transcript"],
        "transcript_format": "opentelemetry",
    },
)
```

**`TypeScript`**

```typescript title="TypeScript"
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";

const elevenlabs = new ElevenLabsClient({
  apiKey: process.env.ELEVENLABS_API_KEY,
});

await elevenlabs.conversationalAi.settings.update({
  webhooks: {
    postCallWebhookId: "wh_01jqz7x8y9z0a1b2c3d4e5f6",
    events: ["transcript"],
    transcriptFormat: "opentelemetry",
  },
});
```

Geef voor één agent hetzelfde `webhooks`-object door onder `platform_settings.workspace_overrides` in [Agent bijwerken](/docs/nl/api-reference/agents/update).

> **Warning**
>
> OpenTelemetry-transcriptwebhooks bevatten geen audio. Gebruik `post_call_audio` als je
> opnamen nodig hebt.
>
> Retourneer **2xx** bij succes. **4xx** en **5xx** gelden als fouten.
>
> Opnieuw proberen geldt alleen voor transcriptwebhooks (inclusief OpenTelemetry) en audiowebhooks wanneer **Opnieuw
> proberen inschakelen** is ingeschakeld voor de workspace-webhook. Bij tijdelijke fouten (\*\* 5xx \*\*, \*\*429 \*\*, \*\*408 \*\*) wordt maximaal
> 5 keer opnieuw geprobeerd; bij **4xx** niet. Herhaalde fouten kunnen de webhook automatisch uitschakelen. Zie
> [Webhooks na gesprekken](/docs/nl/eleven-agents/workflows/post-call-webhooks) voor details en HIPAA-
> uitzonderingen.

### Bezorgen

| Onderwerp        | Details                                                                                 |
| ---------------- | --------------------------------------------------------------------------------------- |
| Methode          | `POST` met JSON-body                                                                    |
| Auth             | `ElevenLabs-Signature: t={unix},v0={hmac}` over `{timestamp}.{body}`                    |
| Opnieuw proberen | Vereist **Opnieuw proberen inschakelen** voor de webhook; zie bovenstaande waarschuwing |
| Grootte          | Lange toolparameters en resultaten worden afgekapt op 4 KB per spanattribuut            |

### Tracevorm

Elke levering is één volledige trace: een root span met onderliggende spans.

```text
elevenlabs.conversation
├── elevenlabs.recv.user_transcript
├── elevenlabs.recv.agent_response
│   └── elevenlabs.tool.{name}
└── ...
```

Spans voor agentreacties bevatten `elevenlabs.reasoning_content` wanneer de levering een [redeneersamenvatting](/docs/nl/eleven-agents/customization/llm#reasoning-summary) bevat.

De timing is gebaseerd op `time_in_call_secs` van het transcript en gespreksmetadata. De root span stelt `elevenlabs.source` in op `post_call_webhook` en de status op `ERROR` wanneer het gesprek niet eindigde met een normale clientverbinding die werd verbroken.

## GET conversation

Vraag OpenTelemetry-indeling aan via [Get conversation](/docs/nl/api-reference/conversations/get) om hetzelfde `otlp_traces`-object te ontvangen als via de OpenTelemetry-webhook na het gesprek, plus het volledige gespreksmodel.

```http
GET /v1/convai/conversations/{conversation_id}?format=opentelemetry
```

Hiervoor heb je een API-sleutel met `CONVAI_READ` nodig. Met `format=json` (standaard) wordt `otlp_traces` weggelaten.

```json
{
  "conversation_id": "conv_9001k1zph3fkeh5s8xg9z90swaqa",
  "agent_id": "agent_7101k5zvyjhmfg983brhmhkd98n6",
  "status": "done",
  "transcript": [],
  "otlp_traces": {
    "resourceSpans": []
  }
}
```

| Onderwerp      | Details                                                                  |
| -------------- | ------------------------------------------------------------------------ |
| Timing         | Dezelfde builder op basis van transcript als de webhook na het gesprek   |
| Transcript     | `transcript` wordt nog steeds geretourneerd; `otlp_traces` is aanvullend |
| Bestands-URL's | Ondertekende URL's in spanattributen verlopen na ongeveer 15 minuten     |

**`Python`**

```python title="Python"
import os

from dotenv import load_dotenv
from elevenlabs import ElevenLabs

load_dotenv()
elevenlabs = ElevenLabs(api_key=os.getenv("ELEVENLABS_API_KEY"))

conversation = elevenlabs.conversational_ai.conversations.get(
    conversation_id="conv_9001k1zph3fkeh5s8xg9z90swaqa",
    format="opentelemetry",
)

otlp_traces = conversation.otlp_traces
```

**`TypeScript`**

```typescript title="TypeScript"
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";

const elevenlabs = new ElevenLabsClient({
  apiKey: process.env.ELEVENLABS_API_KEY,
});

const conversation = await elevenlabs.conversationalAi.conversations.get({
  conversationId: "conv_9001k1zph3fkeh5s8xg9z90swaqa",
  format: "opentelemetry",
});

const otlpTraces = conversation.otlpTraces;
```

**`cURL`**

```bash title="cURL"
curl -s "https://api.elevenlabs.io/v1/convai/conversations/conv_9001k1zph3fkeh5s8xg9z90swaqa?format=opentelemetry" \
  -H "xi-api-key: $ELEVENLABS_API_KEY" \
  | jq '.otlp_traces.resourceSpans[0].scopeSpans[0].spans[].name'
```

Verwachte spannamen zijn onder meer `elevenlabs.conversation`, `elevenlabs.recv.user_transcript` en `elevenlabs.recv.agent_response`.

## Monitoring-WebSocket

> **Note**
>
> Realtime monitoring vereist een Enterprise-workspace of de featureflag `realtime-monitoring`.
> Zie [Realtime monitoring](/docs/nl/eleven-agents/guides/realtime-monitoring) voor configuratie,
> besturingscommando's en toegangsvereisten.

Stream OpenTelemetry-tracegegevens als OTLP JSON terwijl een gesprek bezig is. Elk bericht is een kleine batch `resourceSpans`, geen enkele trace aan het einde van een gesprek.

```
wss://api.elevenlabs.io/v1/convai/conversations/{conversation_id}/monitor?events_format=opentelemetry
```

Authenticatie vereist `CONVAI_WRITE`, `xi-api-key` (of `Authorization`) en **EDITOR**-toegang tot de workspace van de agent. Maak verbinding nadat het gesprek is gestart.

### Monitoring inschakelen voor de agent

Stel `monitoring_enabled: true` in en configureer `monitoring_events` vóór het gesprek. Zie [Realtime monitoring](/docs/nl/eleven-agents/guides/realtime-monitoring#configuration).

### Verbinden met OpenTelemetry-indeling

Voeg `events_format=opentelemetry` toe aan de URL van de monitoring-WebSocket.

> **Warning**
>
> VAD-, beurtwaarschijnlijkheids- en pinggebeurtenissen zijn niet beschikbaar wanneer aangepaste `monitoring_events` zijn
> geconfigureerd. De stream bevat alleen tekst en metadata, geen ruwe audio.

### Sessieprotocol

1. Maak verbinding met authenticatieheaders.
2. Ontvang `{"type": "connected"}`.
3. Ontvang een root-spanbatch (`elevenlabs.conversation`, `elevenlabs.source` = `monitoring`).
4. Ontvang de gecachte geschiedenis (ongeveer de laatste 100 gebeurtenissen), gevolgd door `{"type": "history_complete"}`.
5. Ontvang live spanbatches wanneer gebeurtenissen plaatsvinden.

Met `events_format=json` (standaard) retourneert de WebSocket onbewerkte clientgebeurtenissen in plaats van `resourceSpans`. Besturingscommando's komen overeen met [Realtime monitoring](/docs/nl/eleven-agents/guides/realtime-monitoring#control-commands).

### Tracevorm

```text
elevenlabs.conversation
├── elevenlabs.turn.0
│   ├── elevenlabs.event.user_transcript
│   └── elevenlabs.tool.{name}
└── elevenlabs.turn.1
```

| Aspect           | Na gesprek en GET                | Monitoring                                                           |
| ---------------- | -------------------------------- | -------------------------------------------------------------------- |
| Detailniveau     | Eén trace per webhook of request | Veel berichten per gesprek                                           |
| Gebeurtenisspans | Transcriptbeurten                | `elevenlabs.event.{type}`                                            |
| Beurtgroepering  | Impliciet in transcriptvolgorde  | Expliciet `elevenlabs.turn.N`                                        |
| Volgorde         | Stabiele transcriptvolgorde      | Gebeurtenissen kunnen buiten strikt chronologische volgorde aankomen |

Gestructureerde gebeurtenissen worden gekoppeld aan specifieke attributen (bijvoorbeeld `elevenlabs.user.text`, `elevenlabs.agent.text`). Onbekende gebeurtenissen gebruiken `elevenlabs.event.data` met afgekapt JSON.

> **Info**
>
> Ga er niet van uit dat de volgorde van gebeurtenissen overeenkomt met de spreekvolgorde. Koppel live spans aan gegevens na het gesprek met
> dezelfde `traceId`.

### Voorbeeldverbinding

**`TypeScript`**

```typescript title="TypeScript"
import WebSocket from "ws";

const ws = new WebSocket(
  "wss://api.elevenlabs.io/v1/convai/conversations/conv_9001k1zph3fkeh5s8xg9z90swaqa/monitor?events_format=opentelemetry",
  {
    headers: {
      "xi-api-key": process.env.ELEVENLABS_API_KEY!,
    },
  }
);

ws.on("message", (raw) => {
  const msg = JSON.parse(raw.toString());
  if (msg.type === "connected" || msg.type === "history_complete") return;

  if (msg.resourceSpans) {
    forwardToCollector({ resourceSpans: msg.resourceSpans });
  }
});
```

**`Python`**

```python title="Python"
import asyncio
import json
import os

import websockets
from dotenv import load_dotenv

load_dotenv()

async def monitor_opentelemetry():
    uri = (
        "wss://api.elevenlabs.io/v1/convai/conversations/conv_9001k1zph3fkeh5s8xg9z90swaqa/monitor"
        "?events_format=opentelemetry"
    )
    headers = {"xi-api-key": os.getenv("ELEVENLABS_API_KEY")}

    async with websockets.connect(uri, extra_headers=headers) as ws:
        async for raw in ws:
            msg = json.loads(raw)
            if msg.get("type") in ("connected", "history_complete"):
                continue
            if msg.get("resourceSpans"):
                forward_to_collector({"resourceSpans": msg["resourceSpans"]})

asyncio.run(monitor_opentelemetry())
```

## OTLP JSON-structuur

OpenTelemetry-traces van alle methoden gebruiken dezelfde OTLP JSON-batchindeling:

```json
{
  "resourceSpans": [
    {
      "resource": {
        "attributes": [
          { "key": "service.name", "value": { "stringValue": "elevenlabs-convai" } },
          {
            "key": "elevenlabs.conversation_id",
            "value": { "stringValue": "conv_9001k1zph3fkeh5s8xg9z90swaqa" }
          }
        ]
      },
      "scopeSpans": [
        {
          "scope": { "name": "elevenlabs.convai", "version": "1.0.0" },
          "spans": [
            {
              "traceId": "32_hex_chars",
              "spanId": "16_hex_chars",
              "name": "elevenlabs.recv.agent_response",
              "startTimeUnixNano": "1700000000000000000",
              "endTimeUnixNano": "1700000001000000000",
              "status": { "code": 1 }
            }
          ]
        }
      ]
    }
  ]
}
```

## Beperkingen

* Geen rechtstreekse verzending naar je OTLP gRPC-endpoint.
* Payloads zijn JSON in de vorm van OTLP-export, niet onbewerkte protobuf via de verbinding.

## Gerelateerde documentatie

* [Webhooks na gesprekken](/docs/nl/eleven-agents/workflows/post-call-webhooks)
* [Realtime monitoring](/docs/nl/eleven-agents/guides/realtime-monitoring)