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

# Tracce OpenTelemetry

Gli agenti ElevenLabs possono esportare le conversazioni come **tracce OpenTelemetry** codificate in **OTLP JSON** (`resourceSpans`). Inoltrale a Datadog, Grafana Tempo, Honeycomb o a qualsiasi backend che acquisisca OTLP.

> **Info**
>
> ElevenLabs non invia le tracce direttamente al tuo collector OTLP. Ricevi JSON in formato OTLP da
> un webhook, un'API o un WebSocket di monitoraggio e lo inoltri al tuo backend.

## Panoramica

Esporta le tracce da tre fonti. Tutte e tre condividono lo stesso **ID traccia per conversazione** e la denominazione degli attributi `elevenlabs.*`. La struttura e la tempistica degli span differiscono tra post-chiamata/GET (basati sulla trascrizione) e monitoraggio (basato sugli eventi).

### Fonti di esportazione

| Fonte                       | Quando ricevi i dati                                             | Ideale per                                                |
| --------------------------- | ---------------------------------------------------------------- | --------------------------------------------------------- |
| Webhook post-chiamata       | Dopo la fine della conversazione e il completamento dell'analisi | Pipeline batch, fatturazione e QA, archiviazione duratura |
| API GET della conversazione | Su richiesta, dopo la creazione della conversazione              | Backfill, debugging, rielaborazione                       |
| WebSocket di monitoraggio   | Durante una conversazione in tempo reale                         | Dashboard in tempo reale, avvisi, supervisione umana      |

### Scegliere una fonte

* **Ogni chiamata completata nel tuo data warehouse**: webhook post-chiamata
* **Esportazione o correzione una tantum**: GET della conversazione con `format=opentelemetry`
* **UI di supervisione o avvisi in tempo reale**: WebSocket di monitoraggio
* **Timeline completa e dettagliata a posteriori**: webhook post-chiamata o GET della conversazione
* **Eventi di tool, MCP o guardrail nel momento in cui si verificano**: WebSocket di monitoraggio

Usa `traceId` o `elevenlabs.conversation_id` per unire i dati tra le fonti. Combina il monitoraggio per le operazioni in tempo reale, i webhook per analisi durature e GET per il backfill.

Per ogni fonte ti serve un collector compatibile con OTLP o un fornitore di osservabilità. I webhook post-chiamata richiedono un endpoint webhook del workspace. L'API GET e il WebSocket di monitoraggio hanno ciascuno i propri scope della chiave API e la propria configurazione; consulta le sezioni seguenti.

## Webhook post-chiamata

Al termine di una conversazione, ElevenLabs invia una richiesta `POST` quando è configurato un webhook post-chiamata, `events` include `transcript` e `transcript_format` è `opentelemetry`.

Il `type` del webhook è `post_call_transcription_otel` (non `post_call_transcription`, che restituisce trascrizioni JSON).

### Payload del webhook

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

### Abilitare le trascrizioni OpenTelemetry

#### Configura dal dashboard

### Crea un webhook del workspace

Nel dashboard di ElevenAgents, crea un webhook del workspace con il tuo URL HTTPS e l'autenticazione.

### Collega il webhook post-chiamata

Apri le [impostazioni degli agenti](https://elevenlabs.io/app/agents/settings), assegna il webhook come webhook post-chiamata, abilita l'evento **Transcript** e attiva **OpenTelemetry transcript payloads**.

![Impostazioni del webhook post-chiamata](/docs/_fern-files/elevenlabs.docs.buildwithfern.com/eb5d768612d6461a21bc3127611f60724be3e1a55005af43faf48f2d7bf23807/assets/images/conversational-ai/postcallwebhooksettings.webp)

#### Configura tramite CLI

> **Note**
>
> I webhook post-chiamata a livello di workspace si configurano nella scheda Dashboard o API. Usa la CLI per
> sovrascrivere le impostazioni del webhook per un agente specifico.

### Scarica la configurazione dell'agente

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

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

Imposta `platform_settings.workspace_overrides.webhooks`:

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

### Invia le modifiche

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

#### Configura tramite 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",
  },
});
```

Per un singolo agente, passa lo stesso oggetto `webhooks` in `platform_settings.workspace_overrides` in [Aggiorna agente](/docs/it/api-reference/agents/update).

> **Warning**
>
> I webhook delle trascrizioni OpenTelemetry non includono l'audio. Usa `post_call_audio` se ti servono
> le registrazioni.
>
> Restituisci **2xx** in caso di successo. I codici **4xx** e **5xx** sono considerati errori.
>
> I tentativi si applicano ai webhook delle trascrizioni (incluso OpenTelemetry) e dell'audio solo quando **Enable
> retries** è attivo per il webhook del workspace. Gli errori temporanei (\*\* 5xx \*\*, \*\*429 \*\*, \*\*408 \*\*) vengono ritentati fino a
> 5 volte; i codici **4xx** no. Errori ripetuti possono disabilitare automaticamente il webhook. Consulta
> [Webhook post-chiamata](/docs/it/eleven-agents/workflows/post-call-webhooks) per dettagli ed eccezioni
> HIPAA.

### Consegna

| Argomento      | Dettaglio                                                                                  |
| -------------- | ------------------------------------------------------------------------------------------ |
| Metodo         | `POST` con body JSON                                                                       |
| Autenticazione | `ElevenLabs-Signature: t={unix},v0={hmac}` su `{timestamp}.{body}`                         |
| Tentativi      | Richiede **Enable retries** sul webhook; consulta l'avviso sopra                           |
| Dimensione     | I parametri e i risultati lunghi dei tool vengono troncati a 4 KB per attributo dello span |

### Struttura della traccia

Ogni consegna è una traccia completa: uno span radice più elementi figlio.

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

Gli span delle risposte dell'agente includono `elevenlabs.reasoning_content` quando la consegna contiene un [riepilogo del ragionamento](/docs/it/eleven-agents/customization/llm#reasoning-summary).

La tempistica deriva da `time_in_call_secs` della trascrizione e dai metadati della chiamata. Lo span radice imposta `elevenlabs.source` = `post_call_webhook` e lo stato `ERROR` quando la chiamata non termina con una normale disconnessione del client.

## GET della conversazione

Richiedi il formato OpenTelemetry in [Ottieni conversazione](/docs/it/api-reference/conversations/get) per ricevere lo stesso oggetto `otlp_traces` del webhook OpenTelemetry post-chiamata, insieme al modello completo della conversazione.

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

Richiede una chiave API con `CONVAI_READ`. Con `format=json` (predefinito), `otlp_traces` viene omesso.

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

| Argomento    | Dettaglio                                                               |
| ------------ | ----------------------------------------------------------------------- |
| Tempistica   | Stesso builder basato sulla trascrizione del webhook post-chiamata      |
| Trascrizione | `transcript` viene comunque restituito; `otlp_traces` è aggiuntivo      |
| URL dei file | Gli URL firmati negli attributi degli span scadono dopo circa 15 minuti |

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

I nomi degli span previsti includono `elevenlabs.conversation`, `elevenlabs.recv.user_transcript` e `elevenlabs.recv.agent_response`.

## WebSocket di monitoraggio

> **Note**
>
> Il monitoraggio in tempo reale richiede un workspace Enterprise o il feature flag `realtime-monitoring`.
> Consulta [Monitoraggio in tempo reale](/docs/it/eleven-agents/guides/realtime-monitoring) per la configurazione,
> i comandi di controllo e i requisiti di accesso.

Trasmetti i dati delle tracce OpenTelemetry come OTLP JSON mentre è in corso una conversazione. Ogni messaggio è un piccolo batch `resourceSpans`, non una singola traccia di fine chiamata.

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

L'autenticazione richiede `CONVAI_WRITE`, `xi-api-key` (o `Authorization`) e accesso **EDITOR** al workspace dell'agente. Connettiti dopo l'avvio della conversazione.

### Abilita il monitoraggio sull'agente

Imposta `monitoring_enabled: true` e configura `monitoring_events` prima della chiamata. Consulta [Monitoraggio in tempo reale](/docs/it/eleven-agents/guides/realtime-monitoring#configuration).

### Connettiti con il formato OpenTelemetry

Aggiungi `events_format=opentelemetry` all'URL del WebSocket di monitoraggio.

> **Warning**
>
> Gli eventi VAD, probabilità di turno e ping non sono disponibili quando vengono configurati `monitoring_events`
> personalizzati. Il flusso include solo testo e metadati, non audio non elaborato.

### Protocollo di sessione

1. Connettiti con gli header di autenticazione.
2. Ricevi `{"type": "connected"}`.
3. Ricevi un batch di span radice (`elevenlabs.conversation`, `elevenlabs.source` = `monitoring`).
4. Ricevi la cronologia in cache (circa gli ultimi 100 eventi), quindi `{"type": "history_complete"}`.
5. Ricevi batch di span in tempo reale man mano che si verificano gli eventi.

Con `events_format=json` (predefinito), il WebSocket restituisce eventi client non elaborati anziché `resourceSpans`. I comandi di controllo corrispondono a [Monitoraggio in tempo reale](/docs/it/eleven-agents/guides/realtime-monitoring#control-commands).

### Struttura della traccia

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

| Aspetto                  | Post-chiamata e GET                      | Monitoraggio                                                      |
| ------------------------ | ---------------------------------------- | ----------------------------------------------------------------- |
| Granularità              | Una traccia per webhook o richiesta      | Molti messaggi per conversazione                                  |
| Span degli eventi        | Turni della trascrizione                 | `elevenlabs.event.{type}`                                         |
| Raggruppamento dei turni | Implicito nell'ordine della trascrizione | `elevenlabs.turn.N` esplicito                                     |
| Ordine                   | Ordine stabile della trascrizione        | Gli eventi possono arrivare fuori dal rigoroso ordine cronologico |

Gli eventi strutturati vengono mappati ad attributi dedicati (ad esempio `elevenlabs.user.text`, `elevenlabs.agent.text`). Gli eventi sconosciuti usano `elevenlabs.event.data` con JSON troncato.

> **Info**
>
> Non presumere che l'ordine degli eventi corrisponda all'ordine in cui si parla. Correla gli span in tempo reale con i dati post-chiamata usando
> lo stesso `traceId`.

### Esempio di connessione

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

## Struttura JSON OTLP

Le tracce OpenTelemetry di tutte le fonti condividono lo stesso layout batch 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 }
            }
          ]
        }
      ]
    }
  ]
}
```

## Limitazioni

* Nessun invio diretto al tuo endpoint OTLP gRPC.
* I payload sono JSON con la struttura dell'esportazione OTLP, non protobuf non elaborato trasmesso via rete.

## Documentazione correlata

* [Webhook post-chiamata](/docs/it/eleven-agents/workflows/post-call-webhooks)
* [Monitoraggio in tempo reale](/docs/it/eleven-agents/guides/realtime-monitoring)