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

# Webhooks

## Visão geral

Determinados eventos na ElevenLabs podem ser configurados para acionar webhooks, permitindo que aplicações e sistemas externos recebam e processem esses eventos à medida que ocorrem. Os tipos de evento aceitos atualmente incluem:

| Tipo de evento                   | Descrição                                                                                                                     |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `post_call_transcription`        | Uma chamada da Agents Platform terminou e a análise foi concluída                                                             |
| `voice_removal_notice`           | Uma voz compartilhada está programada para remoção                                                                            |
| `voice_removal_notice_withdrawn` | Uma voz compartilhada não está mais programada para remoção                                                                   |
| `voice_removed`                  | Uma voz compartilhada foi removida e não pode mais ser usada                                                                  |
| `flows_generation`               | Uma [geração de Imagem e Vídeo](/docs/pt/eleven-api/guides/how-to/image-and-video/webhooks) foi concluída ou falhou           |
| `flows_template_run`             | Uma [execução de template](/docs/pt/eleven-api/guides/how-to/templates/run-a-template#get-the-result) foi concluída ou falhou |

## Configuração

Os webhooks podem ser criados, desativados e excluídos na página de configurações gerais. Para usuários em [Workspaces](/docs/pt/overview/administration/workspaces/overview), somente os administradores do workspace podem configurar os webhooks dele.

![Configuração de webhook HMAC](/docs/_fern-img/9ea298daac1c64eb43c802a12f7824e83accca44ba2edd1d01a39bcd62c0b9d6.webp)

Após a criação, o webhook pode ser selecionado para receber eventos nas configurações de produtos, como a [Agents Platform](/docs/pt/eleven-agents/workflows/post-call-webhooks).

Os eventos `flows_generation` e `flows_template_run` são habilitados por uma única inscrição: em **Select events to listen to**, marque **Image & Video API generation or template run completed**, ou envie o evento `flows` para [Atualizar webhook do workspace](/docs/pt/api-reference/webhooks/update). Uma geração ou execução só envia seu evento quando a solicitação de criação inclui um campo `webhook`.

Os webhooks podem ser desativados a qualquer momento na página de configurações gerais. Webhooks que falham repetidamente são desativados automaticamente se houver 10 ou mais falhas consecutivas e a última entrega bem-sucedida tiver ocorrido há mais de 7 dias, ou se nunca tiver havido uma entrega bem-sucedida. Webhooks desativados automaticamente precisam ser reativados na página de configurações. Eles podem ser excluídos se não estiverem em uso por nenhum produto.

## Tentativas

As tentativas de webhook podem ser habilitadas por webhook para tentar novamente a entrega automaticamente quando uma solicitação falha. Elas ficam desativadas por padrão. Habilite as tentativas ao criar ou atualizar um webhook pela [API](/docs/pt/api-reference/webhooks/create) ou nas configurações do webhook.

> **Note**
>
> Tentativas são aceitas para os [webhooks pós-chamada](/docs/pt/eleven-agents/workflows/post-call-webhooks) do ElevenAgents,
> incluindo eventos de transcrição (`post_call_transcription`), áudio (`post_call_audio`) e falha na
> inicialização da chamada (`call_initiation_failure`).

### Programação de tentativas

Quando uma tentativa de entrega falha com um erro que permite nova tentativa, o sistema tenta novamente até 5 vezes, com intervalos crescentes entre as tentativas:

| Tentativa | Intervalo   |
| --------- | ----------- |
| 1         | Imediato    |
| 2         | 30 segundos |
| 3         | 2 minutos   |
| 4         | 8 minutos   |
| 5         | 30 minutos  |

Uma pequena variação aleatória (de até 10% do intervalo) é adicionada a cada nova tentativa para distribuir a carga e evitar problemas de excesso simultâneo de solicitações.

### Erros que permitem nova tentativa

Nem todas as falhas acionam uma nova tentativa. Apenas as seguintes falhas são consideradas recuperáveis:

* Códigos de status `5xx` (erros de servidor, como 500, 502, 503 e 504).
* `429` (Muitas solicitações).
* `408` (Tempo limite da solicitação).
* Erros de conexão e tempos limite de solicitação.

Erros de solicitação na faixa `4xx` (como 400, 401, 403 e 404) **não** recebem novas tentativas, pois geralmente indicam um problema de configuração que exige correção manual.

### Limites de fila por webhook

Cada webhook é limitado a 100 tarefas de nova tentativa pendentes. Se um webhook acumular mais de 100 tentativas na fila, as tarefas adicionais serão descartadas até que as tentativas existentes sejam processadas. Isso evita que um único webhook mal configurado consuma recursos excessivos.

Webhooks de áudio têm dois limites adicionais. Uma carga de áudio maior que 50 MiB é entregue uma vez e não recebe novas tentativas, e o total de tentativas de áudio em fila para um único webhook não pode exceder 400 MiB.

### Comportamento de desativação automática

O sistema rastreia falhas consecutivas de entrega para cada webhook. Um webhook é desativado automaticamente quando as duas condições a seguir são atendidas:

* Ocorreram 10 ou mais falhas consecutivas de entrega.
* O webhook nunca foi entregue com sucesso ou a última entrega bem-sucedida ocorreu há mais de 7 dias.

Quando um webhook é desativado automaticamente, os administradores do workspace recebem uma notificação por e-mail. O webhook deve ser reativado manualmente na página de configurações antes de voltar a entregar eventos.

## Integração

Para integrar com webhooks, crie um manipulador de endpoint para receber os dados de eventos de webhook como solicitações POST. Depois de validar a assinatura, o manipulador deve retornar HTTP 200 rapidamente para indicar o recebimento bem-sucedido. Falhas repetidas em retornar uma resposta de sucesso podem fazer com que o webhook seja desativado automaticamente.

A carga de uma nova tentativa é idêntica à da tentativa de entrega original. Os consumidores de webhooks não podem distinguir uma entrega inicial de uma nova tentativa apenas pela carga, então crie seu manipulador para ser **idempotente** — processar o mesmo evento várias vezes deve produzir o mesmo resultado. Use `event_timestamp` e identificadores específicos do evento (como `conversation_id`) para eliminar eventos duplicados, se necessário.

### Campos de nível superior

| Campo             | Tipo   | Descrição                  |
| ----------------- | ------ | -------------------------- |
| `type`            | string | Tipo de evento             |
| `data`            | object | Dados do evento            |
| `event_timestamp` | string | Quando este evento ocorreu |

## Exemplo de carga de 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"
      }
    }
  }
}
```

## Autenticação

É importante que o listener valide todos os webhooks recebidos. Atualmente, os webhooks oferecem suporte à autenticação por assinaturas HMAC. Configure a autenticação HMAC:

* Armazenando com segurança o segredo compartilhado gerado na criação do webhook
* Verificando o cabeçalho ElevenLabs-Signature no seu endpoint usando o SDK

O SDK JavaScript disponibiliza `constructEvent`; o SDK Python disponibiliza `construct_event` com **`rawBody`**, **`sig_header`** e **`secret`** (em Python, eles não se chamam `payload` / `signature`). Ambos verificam a assinatura, validam o carimbo de data e hora e analisam o payload JSON.

#### Python

Exemplo de manipulador de webhook usando 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

Exemplo de manipulador de webhook usando 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

Exemplo de manipulador de webhook usando uma rota de API do 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 });
}
```