> 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.

# Traces OpenTelemetry

Les agents ElevenLabs peuvent exporter les conversations sous forme de **traces OpenTelemetry** encodées en **OTLP JSON** (`resourceSpans`). Transférez-les vers Datadog, Grafana Tempo, Honeycomb ou tout backend qui ingère OTLP.

> **Info**
>
> ElevenLabs n'envoie pas directement les traces vers votre collecteur OTLP. Vous recevez du JSON au
> format OTLP depuis un webhook, une API ou un WebSocket de monitoring, puis le transférez vers votre backend.

## Vue d'ensemble

Exportez les traces depuis trois sources. Elles partagent toutes le même **ID de trace par conversation** et la même nomenclature d'attributs `elevenlabs.*`. La structure et le minutage des spans diffèrent entre le post-appel/GET (basé sur la transcription) et le monitoring (basé sur les événements).

### Sources d'exportation

| Source                  | Quand vous recevez les données                         | Idéal pour                                                |
| ----------------------- | ------------------------------------------------------ | --------------------------------------------------------- |
| Webhook post-appel      | Une fois la conversation terminée et l'analyse achevée | Pipelines par lots, facturation, QA, stockage durable     |
| API GET de conversation | À la demande, après la création de la conversation     | Remplissage de données, débogage, retraitement            |
| WebSocket de monitoring | Pendant une conversation en direct                     | Tableaux de bord en direct, alertes, intervention humaine |

### Choisir une source

* **Chaque appel terminé dans votre entrepôt de données** : webhook post-appel
* **Export ou correction ponctuels** : GET de la conversation avec `format=opentelemetry`
* **Interface de supervision en direct ou alertes** : WebSocket de monitoring
* **Chronologie complète a posteriori** : webhook post-appel ou GET de la conversation
* **Événements d'outil, MCP ou de garde-fou au moment où ils surviennent** : WebSocket de monitoring

Utilisez `traceId` ou `elevenlabs.conversation_id` pour relier les données entre les sources. Combinez le monitoring pour les opérations en direct, les webhooks pour les analyses durables et GET pour le remplissage de données.

Vous avez besoin d'un collecteur compatible OTLP ou d'un fournisseur d'observabilité pour chaque source. Les webhooks post-appel nécessitent un endpoint de webhook du Workspace. L'API GET et le WebSocket de monitoring disposent chacun de leurs propres périmètres de clé API et de leur propre configuration, consultez les sections ci-dessous.

## Webhook post-appel

Une fois une conversation terminée, ElevenLabs envoie une requête `POST` lorsqu'un webhook post-appel est configuré, que `events` inclut `transcript` et que `transcript_format` est défini sur `opentelemetry`.

Le `type` du webhook est `post_call_transcription_otel` et non `post_call_transcription`, qui renvoie des transcriptions JSON.

### Charge utile du webhook

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

### Activer les transcriptions OpenTelemetry

#### Configurer via le Dashboard

### Créer un webhook de Workspace

Dans le Dashboard ElevenAgents, créez un webhook de Workspace avec votre URL HTTPS et votre authentification.

### Associer le webhook post-appel

Ouvrez les [paramètres des agents](https://elevenlabs.io/app/agents/settings), attribuez le webhook comme webhook post-appel, activez l'événement **Transcript**, puis activez les **charges utiles de transcription OpenTelemetry**.

![Paramètres du webhook post-appel](/docs/_fern-img/eb5d768612d6461a21bc3127611f60724be3e1a55005af43faf48f2d7bf23807.webp)

#### Configurer via la CLI

> **Note**
>
> Les webhooks post-appel à l'échelle du Workspace se configurent dans le Dashboard ou via l'onglet API. Utilisez la CLI pour
> remplacer les paramètres de webhook d'un agent spécifique.

### Récupérer la configuration de l'agent

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

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

Définissez `platform_settings.workspace_overrides.webhooks` :

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

### Envoyer vos modifications

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

#### Configurer via l'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",
  },
});
```

Pour un seul agent, transmettez le même objet `webhooks` sous `platform_settings.workspace_overrides` dans [Mettre à jour un agent](/docs/fr/api-reference/agents/update).

> **Warning**
>
> Les webhooks de transcription OpenTelemetry n'incluent pas l'audio. Utilisez `post_call_audio` si vous avez besoin
> d'enregistrements.
>
> Renvoyez **2xx** en cas de réussite. Les réponses **4xx** et **5xx** sont considérées comme des échecs.
>
> Les nouvelles tentatives s'appliquent aux webhooks de transcription, y compris OpenTelemetry, uniquement lorsque **Activer les nouvelles tentatives** est activé
> pour le webhook du Workspace. Les erreurs transitoires (**5xx**, **429**, **408**) font l'objet de jusqu'à 5 nouvelles tentatives ; les erreurs **4xx**
> n'en font pas l'objet. Les webhooks audio ne font jamais l'objet de nouvelles tentatives. Des échecs répétés peuvent désactiver automatiquement le webhook. Consultez
> [Webhooks post-appel](/docs/fr/eleven-agents/workflows/post-call-webhooks) pour les détails et les exceptions
> HIPAA.

### Livraison

| Sujet                | Détail                                                                                                                                     |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| Méthode              | `POST` avec corps JSON                                                                                                                     |
| Auth                 | `ElevenLabs-Signature: t={unix},v0={hmac}` sur `{timestamp}.{body}`                                                                        |
| Nouvelles tentatives | Webhooks de transcription uniquement ; nécessite **Activer les nouvelles tentatives** sur le webhook ; consultez l'avertissement ci-dessus |
| Taille               | Les longs paramètres et résultats d'outil sont tronqués à 4 KB par attribut de span                                                        |

### Structure de la trace

Chaque livraison correspond à une trace complète : un span racine et des spans enfants.

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

Les spans de réponse de l'agent incluent `elevenlabs.reasoning_content` lorsque la livraison contient un [résumé du raisonnement](/docs/fr/eleven-agents/customization/llm#reasoning-summary).

Le minutage provient de `time_in_call_secs` de la transcription et des métadonnées de l'appel. Le span racine définit `elevenlabs.source` = `post_call_webhook` et le statut `ERROR` lorsque l'appel ne s'est pas terminé par une déconnexion normale du client.

## GET de la conversation

Demandez le format OpenTelemetry avec [Obtenir une conversation](/docs/fr/api-reference/conversations/get) pour recevoir le même objet `otlp_traces` que le webhook OpenTelemetry post-appel, ainsi que le modèle complet de la conversation.

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

Nécessite une clé API avec `CONVAI_READ`. Avec `format=json` (par défaut), `otlp_traces` est omis.

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

| Sujet           | Détail                                                                       |
| --------------- | ---------------------------------------------------------------------------- |
| Minutage        | Même générateur basé sur la transcription que le webhook post-appel          |
| Transcription   | `transcript` est toujours renvoyé ; `otlp_traces` s'y ajoute                 |
| URL de fichiers | Les URL signées dans les attributs de span expirent après environ 15 minutes |

**`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'
```

Les noms de span attendus incluent `elevenlabs.conversation`, `elevenlabs.recv.user_transcript` et `elevenlabs.recv.agent_response`.

## WebSocket de monitoring

> **Note**
>
> Le monitoring en temps réel nécessite un Workspace Enterprise ou le feature flag `realtime-monitoring`.
> Consultez [Monitoring en temps réel](/docs/fr/eleven-agents/guides/realtime-monitoring) pour la configuration,
> les commandes de contrôle et les exigences d'accès.

Diffusez les données de trace OpenTelemetry en OTLP JSON pendant qu'une conversation est en cours. Chaque message est un petit lot `resourceSpans`, et non une trace unique de fin d'appel.

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

L'authentification nécessite `CONVAI_WRITE`, `xi-api-key` (ou `Authorization`) et un accès **EDITOR** au Workspace de l'agent. Connectez-vous après le début de la conversation.

### Activer le monitoring sur l'agent

Définissez `monitoring_enabled: true` et configurez `monitoring_events` avant l'appel. Consultez [Monitoring en temps réel](/docs/fr/eleven-agents/guides/realtime-monitoring#configuration).

### Se connecter avec le format OpenTelemetry

Ajoutez `events_format=opentelemetry` à l'URL du WebSocket de monitoring.

> **Warning**
>
> Les événements VAD, de probabilité de tour et de ping ne sont pas disponibles lorsque des `monitoring_events` personnalisés sont
> configurés. Le flux inclut uniquement le texte et les métadonnées, pas l'audio brut.

### Protocole de session

1. Connectez-vous avec des en-têtes d'authentification.
2. Recevez `{"type": "connected"}`.
3. Recevez un lot de span racine (`elevenlabs.conversation`, `elevenlabs.source` = `monitoring`).
4. Recevez l'historique mis en cache, environ les 100 derniers événements, puis `{"type": "history_complete"}`.
5. Recevez des lots de spans en direct à mesure que les événements surviennent.

Avec `events_format=json` (par défaut), le WebSocket renvoie les événements clients bruts au lieu de `resourceSpans`. Les commandes de contrôle correspondent à [Monitoring en temps réel](/docs/fr/eleven-agents/guides/realtime-monitoring#control-commands).

### Structure de la trace

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

| Aspect                 | Post-appel et GET                       | Monitoring                                                                           |
| ---------------------- | --------------------------------------- | ------------------------------------------------------------------------------------ |
| Granularité            | Une trace par webhook ou requête        | De nombreux messages par conversation                                                |
| Spans d'événements     | Tours de transcription                  | `elevenlabs.event.{type}`                                                            |
| Regroupement des tours | Implicite dans l'ordre de transcription | Explicite : `elevenlabs.turn.N`                                                      |
| Ordre                  | Ordre stable de la transcription        | Les événements peuvent arriver dans un ordre qui n'est pas strictement chronologique |

Les événements structurés sont associés à des attributs dédiés, par exemple `elevenlabs.user.text`, `elevenlabs.agent.text`. Les événements inconnus utilisent `elevenlabs.event.data` avec du JSON tronqué.

> **Info**
>
> Ne supposez pas que l'ordre des événements correspond à l'ordre de prise de parole. Corrélez les spans en direct aux données post-appel à l'aide
> du même `traceId`.

### Exemple de connexion

**`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())
```

## Structure JSON OTLP

Les traces OpenTelemetry de toutes les sources partagent la même structure de lot JSON OTLP :

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

## Limites

* Aucun envoi direct vers votre endpoint OTLP gRPC.
* Les charges utiles sont du JSON au format d'export OTLP, et non du protobuf brut transmis sur le réseau.

## Documentation associée

* [Webhooks post-appel](/docs/fr/eleven-agents/workflows/post-call-webhooks)
* [Monitoring en temps réel](/docs/fr/eleven-agents/guides/realtime-monitoring)