Webhooks

Habilite integrações externas recebendo eventos de webhook.

Visão geral

Determinados eventos no ElevenLabs podem ser configurados para acionar webhooks, permitindo que aplicações e sistemas externos recebam e processem esses eventos conforme ocorrem. Os tipos de evento compatíveis atualmente incluem:

Tipo de eventoDescrição
post_call_transcriptionUma chamada da Agents Platform foi concluída e a análise está completa
voice_removal_noticeUma voz compartilhada está programada para ser removida
voice_removal_notice_withdrawnUma voz compartilhada não está mais programada para remoção
voice_removedUma voz compartilhada foi removida e não pode mais ser usada

Configuração

Os webhooks podem ser criados, desativados e excluídos na página de configurações gerais. Para usuários em Workspaces, apenas os administradores do workspace podem configurar os webhooks do workspace.

Configuração de webhook HMAC

Após a criação, o webhook pode ser selecionado para monitorar eventos nas configurações de produtos, como a Agents Platform.

Os webhooks podem ser desativados na página de configurações gerais a qualquer momento. 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 tiverem sido entregues com sucesso. Webhooks desativados automaticamente precisam ser reativados na página de configurações. Os webhooks podem ser excluídos se não estiverem em uso por nenhum produto.

Tentativas

As novas tentativas de webhook podem ser ativadas para cada webhook, para tentar novamente a entrega automaticamente quando uma solicitação falhar. As novas tentativas vêm desativadas por padrão. Ative-as ao criar ou atualizar um webhook pela API ou nas configurações do webhook.

Atualmente, as novas tentativas são compatíveis apenas com webhooks post_call_transcription.

Cronograma de novas 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:

TentativaIntervalo
1Imediato
230 segundos
32 minutos
48 minutos
530 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 sobrecarga simultânea.

Erros que permitem nova tentativa

Nem todas as falhas acionam uma nova tentativa. Apenas os seguintes códigos de status HTTP são considerados elegíveis:

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

Erros de solicitação na faixa 4xx (como 400, 401, 403, 404) não são tentados novamente, 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 novas tentativas na fila, tarefas adicionais serão descartadas até que as tentativas existentes sejam processadas. Isso evita que um único webhook configurado incorretamente consuma recursos excessivos.

Comportamento de desativação automática

O sistema acompanha falhas consecutivas de entrega para cada webhook. Um webhook é desativado automaticamente quando ambas as 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 retomar as entregas.

Integração

Para integrar com webhooks, crie um manipulador de endpoint para receber dados de eventos de webhook como solicitações POST. Após validar a assinatura, o manipulador deve retornar HTTP 200 imediatamente para indicar o recebimento bem-sucedido. A falha recorrente em retornar uma resposta de sucesso pode fazer com que o webhook seja desativado automaticamente.

A carga útil da nova tentativa é idêntica à da tentativa de entrega original. Os consumidores de webhook não conseguem distinguir uma entrega inicial de uma nova tentativa apenas pela carga útil, portanto, projete 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

CampoTipoDescrição
typestringTipo de evento
dataobjectDados do evento
event_timestampstringQuando este evento ocorreu

Exemplo de carga útil de webhook

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

Exemplo de manipulador de webhook usando FastAPI:

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"}