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

# Webhook

## Panoramica

Puoi configurare determinati eventi in ElevenLabs affinché attivino webhook, consentendo ad applicazioni e sistemi esterni di ricevere ed elaborare questi eventi quando si verificano. I tipi di evento attualmente supportati includono:

| Tipo di evento                   | Descrizione                                                              |
| -------------------------------- | ------------------------------------------------------------------------ |
| `post_call_transcription`        | Una chiamata della piattaforma Agents è terminata e l'analisi è completa |
| `voice_removal_notice`           | È prevista la rimozione di una voce condivisa                            |
| `voice_removal_notice_withdrawn` | La rimozione di una voce condivisa non è più prevista                    |
| `voice_removed`                  | Una voce condivisa è stata rimossa e non è più utilizzabile              |

## Configurazione

I webhook possono essere creati, disabilitati ed eliminati dalla pagina delle impostazioni generali. Per gli utenti nei [workspace](/docs/it/overview/administration/workspaces/overview), solo gli amministratori del workspace possono configurare i webhook del workspace.

![Configurazione del webhook HMAC](/docs/_fern-img/9ea298daac1c64eb43c802a12f7824e83accca44ba2edd1d01a39bcd62c0b9d6.webp)

Dopo la creazione, il webhook può essere selezionato per ricevere eventi nelle impostazioni dei prodotti, come [Agents Platform](/docs/it/eleven-agents/workflows/post-call-webhooks).

I webhook possono essere disabilitati in qualsiasi momento dalla pagina delle impostazioni generali. I webhook che falliscono ripetutamente vengono disabilitati automaticamente se si verificano 10 o più errori consecutivi e l'ultima consegna riuscita risale a più di 7 giorni fa, oppure se non è mai stata effettuata una consegna riuscita. I webhook disabilitati automaticamente devono essere riabilitati dalla pagina delle impostazioni. I webhook possono essere eliminati se non sono utilizzati da alcun prodotto.

## Tentativi

I tentativi di nuovo invio dei webhook possono essere abilitati per ciascun webhook per ritentare automaticamente la consegna quando una richiesta non riesce. Per impostazione predefinita, i tentativi sono disabilitati. Abilitali quando crei o aggiorni un webhook tramite l'[API](/docs/it/api-reference/webhooks/create) o nelle impostazioni del webhook.

> **Note**
>
> I tentativi sono supportati per i [webhook post-chiamata](/docs/it/eleven-agents/workflows/post-call-webhooks) di ElevenAgents, inclusi gli eventi di trascrizione
> (`post_call_transcription`), audio (`post_call_audio`) e errore di avvio della chiamata
> (`call_initiation_failure`).

### Pianificazione dei tentativi

Quando un tentativo di consegna non riesce a causa di un errore ritentabile, il sistema ritenta fino a 5 volte con ritardi crescenti tra i tentativi:

| Tentativo | Ritardo    |
| --------- | ---------- |
| 1         | Immediato  |
| 2         | 30 secondi |
| 3         | 2 minuti   |
| 4         | 8 minuti   |
| 5         | 30 minuti  |

A ogni tentativo viene aggiunto un piccolo jitter casuale (fino al 10% del ritardo) per distribuire il carico ed evitare problemi di thundering herd.

### Errori ritentabili

Non tutti gli errori attivano un nuovo tentativo. Sono considerati ritentabili solo i seguenti errori:

* Codici di stato `5xx` (errori del server come 500, 502, 503, 504).
* `429` (Troppe richieste).
* `408` (Timeout della richiesta).
* Errori di connessione e timeout delle richieste.

Gli errori delle richieste nella gamma `4xx` (come 400, 401, 403, 404) **non** vengono ritentati, poiché in genere indicano un problema di configurazione che richiede una correzione manuale.

### Limiti della coda per webhook

Ogni webhook è limitato a 100 job di ritentativo in attesa. Se un webhook accumula più di 100 tentativi in coda, gli ulteriori job vengono scartati finché non vengono elaborati i tentativi esistenti. Ciò impedisce che un singolo webhook configurato in modo errato consumi risorse eccessive.

I webhook audio hanno due limiti aggiuntivi. Un payload audio superiore a 50 MiB viene consegnato una volta e non viene ritentato, e i tentativi audio in coda per un singolo webhook non possono superare complessivamente 400 MiB.

### Comportamento di disabilitazione automatica

Il sistema monitora gli errori consecutivi di consegna per ogni webhook. Un webhook viene disabilitato automaticamente quando sono soddisfatte entrambe le seguenti condizioni:

* Si sono verificati 10 o più errori consecutivi di consegna.
* Il webhook non è mai stato consegnato correttamente, oppure l'ultima consegna riuscita risale a più di 7 giorni fa.

Quando un webhook viene disabilitato automaticamente, gli amministratori del workspace ricevono una notifica via email. Il webhook deve essere riabilitato manualmente dalla pagina delle impostazioni prima di riprendere la consegna.

## Integrazione

Per integrarti con i webhook, crea un handler dell'endpoint per ricevere i dati degli eventi webhook come richieste POST. Dopo aver convalidato la firma, l'handler deve restituire tempestivamente HTTP 200 per indicare la ricezione riuscita. La mancata restituzione ripetuta di una risposta di successo può comportare la disabilitazione automatica del webhook.

Il payload del tentativo è identico a quello del tentativo di consegna originale. I consumer del webhook non possono distinguere tra una consegna iniziale e un tentativo dal solo payload, quindi progetta il tuo handler in modo che sia **idempotente**: elaborare lo stesso evento più volte dovrebbe produrre lo stesso risultato. Se necessario, usa `event_timestamp` e identificatori specifici dell'evento (come `conversation_id`) per deduplicare gli eventi.

### Campi di primo livello

| Campo             | Tipo   | Descrizione                     |
| ----------------- | ------ | ------------------------------- |
| `type`            | string | Tipo di evento                  |
| `data`            | object | Dati dell'evento                |
| `event_timestamp` | string | Quando si è verificato l'evento |

## Esempio di payload webhook

```json
{
  "type": "post_call_transcription",
  "event_timestamp": 1739537297,
  "data": {
    "agent_id": "xyz",
    "conversation_id": "abc",
    "status": "done",
    "transcript": [
      {
        "role": "agent",
        "message": "Hey there angelo. How are you?",
        "tool_calls": null,
        "tool_results": null,
        "feedback": null,
        "time_in_call_secs": 0,
        "conversation_turn_metrics": null
      },
      {
        "role": "user",
        "message": "Hey, can you tell me, like, a fun fact about 11 Labs?",
        "tool_calls": null,
        "tool_results": null,
        "feedback": null,
        "time_in_call_secs": 2,
        "conversation_turn_metrics": null
      },
      {
        "role": "agent",
        "message": "I do not have access to fun facts about Eleven Labs. However, I can share some general information about the company. Eleven Labs is an AI voice technology platform that specializes in voice cloning and text-to-speech...",
        "tool_calls": null,
        "tool_results": null,
        "feedback": null,
        "time_in_call_secs": 9,
        "conversation_turn_metrics": {
          "convai_llm_service_ttfb": {
            "elapsed_time": 0.3704247010173276
          },
          "convai_llm_service_ttf_sentence": {
            "elapsed_time": 0.5551181449554861
          }
        }
      }
    ],
    "metadata": {
      "start_time_unix_secs": 1739537297,
      "call_duration_secs": 22,
      "cost": 296,
      "deletion_settings": {
        "deletion_time_unix_secs": 1802609320,
        "deleted_logs_at_time_unix_secs": null,
        "deleted_audio_at_time_unix_secs": null,
        "deleted_transcript_at_time_unix_secs": null,
        "delete_transcript_and_pii": true,
        "delete_audio": true
      },
      "feedback": {
        "overall_score": null,
        "likes": 0,
        "dislikes": 0
      },
      "authorization_method": "authorization_header",
      "charging": {
        "dev_discount": true
      },
      "termination_reason": ""
    },
    "analysis": {
      "evaluation_criteria_results": {},
      "data_collection_results": {},
      "call_successful": "success",
      "transcript_summary": "The conversation begins with the agent asking how Angelo is, but Angelo redirects the conversation by requesting a fun fact about 11 Labs. The agent acknowledges they don't have specific fun facts about Eleven Labs but offers to provide general information about the company. They briefly describe Eleven Labs as an AI voice technology platform specializing in voice cloning and text-to-speech technology. The conversation is brief and informational, with the agent adapting to the user's request despite not having the exact information asked for."
    },
    "conversation_initiation_client_data": {
      "conversation_config_override": {
        "agent": {
          "prompt": null,
          "first_message": null,
          "language": "en"
        },
        "tts": {
          "voice_id": null
        }
      },
      "custom_llm_extra_body": {},
      "dynamic_variables": {
        "user_name": "angelo"
      }
    }
  }
}
```

## Autenticazione

È importante che il listener convalidi tutti i webhook in arrivo. I webhook supportano attualmente l'autenticazione tramite firme HMAC. Configura l'autenticazione HMAC:

* Archiviando in modo sicuro il segreto condiviso generato alla creazione del webhook
* Verificando l'header ElevenLabs-Signature nel tuo endpoint tramite l'SDK

L'SDK JavaScript espone `constructEvent`; l'SDK Python espone `construct_event` con **`rawBody`**, **`sig_header`** e **`secret`** (in Python non si chiamano `payload` / `signature`). Entrambi verificano la firma, convalidano il timestamp e analizzano il payload JSON.

#### Python

Esempio di gestore webhook con FastAPI:

```python
from dotenv import load_dotenv
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from elevenlabs.client import ElevenLabs
from elevenlabs.errors import BadRequestError
import os

load_dotenv()

app = FastAPI()
elevenlabs = ElevenLabs(
    api_key=os.getenv("ELEVENLABS_API_KEY"),
)

WEBHOOK_SECRET = os.getenv("WEBHOOK_SECRET")

@app.post("/webhook")
async def receive_message(request: Request):
    payload = await request.body()
    signature = request.headers.get("elevenlabs-signature")

    try:
        event = elevenlabs.webhooks.construct_event(
            rawBody=payload.decode("utf-8"),
            sig_header=signature,
            secret=WEBHOOK_SECRET,
        )
    except BadRequestError as e:
        return JSONResponse(content={"error": "Invalid signature"}, status_code=401)

    # construct_event returns a dict (parsed JSON), not an object with attributes
    if event.get("type") == "post_call_transcription":
        print(f"Received transcription: {event.get('data')}")

    return {"status": "received"}
```

#### JavaScript

#### Express

Esempio di gestore webhook con Express:

```javascript
import { ElevenLabsClient } from '@elevenlabs/elevenlabs-js';
import express from 'express';

const app = express();

const elevenlabs = new ElevenLabsClient();
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;

// Use express.text() to preserve raw body for signature verification
app.post('/webhook', express.text({ type: 'application/json' }), async (req, res) => {
  const signature = req.headers['elevenlabs-signature'];
  const payload = req.body; // Raw string body

  let event;
  try {
    event = await elevenlabs.webhooks.constructEvent(payload, signature, WEBHOOK_SECRET);
  } catch (error) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  // Process the webhook event
  if (event.type === 'post_call_transcription') {
    console.log('Received transcription:', event.data);
  }

  res.status(200).json({ received: true });
});
```

#### Next.js

Esempio di gestore webhook con una route API di Next.js:

**`app/api/webhook/route.ts`**

```typescript app/api/webhook/route.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { ElevenLabsClient } from '@elevenlabs/elevenlabs-js';

const elevenlabs = new ElevenLabsClient();
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;

export async function POST(req: NextRequest) {
  const body = await req.text();
  const signature = req.headers.get('elevenlabs-signature');

  let event;
  try {
    event = await elevenlabs.webhooks.constructEvent(body, signature, WEBHOOK_SECRET);
  } catch (error) {
    return NextResponse.json({ error: 'Invalid signature' }, { status: 401 });
  }

  // Process the webhook event
  if (event.type === 'post_call_transcription') {
    console.log('Received transcription:', event.data);
  }

  return NextResponse.json({ received: true }, { status: 200 });
}
```