Webhooks

Enable external integrations by receiving webhook events.

Overview

Certain events within ElevenLabs can be configured to trigger webhooks, allowing external applications and systems to receive and process these events as they occur. Currently supported event types include:

Event typeDescription
post_call_transcriptionA conversational AI call has finished and analysis is complete
voice_removal_noticeA shared voice is scheduled to be removed
voice_removal_notice_withdrawnA shared voice is no longer scheduled for removal
voice_removedA shared voice has been removed and is no longer useable

Configuration

Webhooks can be created, disabled and deleted from the general settings page. For users within Workspaces, only the workspace admins can configure the webhooks for the workspace.

HMAC webhook configuration

After creation, the webhook can be selected to listen for events within product settings such as Conversational AI.

Webhooks can be disabled from the general settings page at any time. Webhooks that repeatedly fail are auto disabled if there are 10 or more consecutive failures and the last successful delivery was more than 7 days ago or has never been successfully delivered. Auto-disabled webhooks require re-enabling from the settings page. Webhooks can be deleted if not in use by any products.

Integration

To integrate with webhooks, the listener should create an endpoint handler to receive the webhook event data POST requests. After validating the signature, the handler should quickly return HTTP 200 to indicate successful receipt of the webhook event, repeat failure to correctly return may result in the webhook becoming automatically disabled. Each webhook event is dispatched only once, refer to the API for methods to poll and get product specific data.

Top-level fields

FieldTypeDescription
typestringType of event
dataobjectData for the event
event_timestampstringWhen this event occurred

Example webhook payload

1{
2 "type": "post_call_transcription",
3 "event_timestamp": 1739537297,
4 "data": {
5 "agent_id": "xyz",
6 "conversation_id": "abc",
7 "status": "done",
8 "transcript": [
9 {
10 "role": "agent",
11 "message": "Hey there angelo. How are you?",
12 "tool_calls": null,
13 "tool_results": null,
14 "feedback": null,
15 "time_in_call_secs": 0,
16 "conversation_turn_metrics": null
17 },
18 {
19 "role": "user",
20 "message": "Hey, can you tell me, like, a fun fact about 11 Labs?",
21 "tool_calls": null,
22 "tool_results": null,
23 "feedback": null,
24 "time_in_call_secs": 2,
25 "conversation_turn_metrics": null
26 },
27 {
28 "role": "agent",
29 "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...",
30 "tool_calls": null,
31 "tool_results": null,
32 "feedback": null,
33 "time_in_call_secs": 9,
34 "conversation_turn_metrics": {
35 "convai_llm_service_ttfb": {
36 "elapsed_time": 0.3704247010173276
37 },
38 "convai_llm_service_ttf_sentence": {
39 "elapsed_time": 0.5551181449554861
40 }
41 }
42 }
43 ],
44 "metadata": {
45 "start_time_unix_secs": 1739537297,
46 "call_duration_secs": 22,
47 "cost": 296,
48 "deletion_settings": {
49 "deletion_time_unix_secs": 1802609320,
50 "deleted_logs_at_time_unix_secs": null,
51 "deleted_audio_at_time_unix_secs": null,
52 "deleted_transcript_at_time_unix_secs": null,
53 "delete_transcript_and_pii": true,
54 "delete_audio": true
55 },
56 "feedback": {
57 "overall_score": null,
58 "likes": 0,
59 "dislikes": 0
60 },
61 "authorization_method": "authorization_header",
62 "charging": {
63 "dev_discount": true
64 },
65 "termination_reason": ""
66 },
67 "analysis": {
68 "evaluation_criteria_results": {},
69 "data_collection_results": {},
70 "call_successful": "success",
71 "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."
72 },
73 "conversation_initiation_client_data": {
74 "conversation_config_override": {
75 "agent": {
76 "prompt": null,
77 "first_message": null,
78 "language": "en"
79 },
80 "tts": {
81 "voice_id": null
82 }
83 },
84 "custom_llm_extra_body": {},
85 "dynamic_variables": {
86 "user_name": "angelo"
87 }
88 }
89 }
90}

Authentication

It is important for the listener to validate all incoming webhooks. Webhooks currently support authentication via HMAC signatures. Set up HMAC authentication by:

  • Securely storing the shared secret generated upon creation of the webhook
  • Verifying the ElevenLabs-Signature header in your endpoint using the shared secret

The ElevenLabs-Signature takes the following format:

1t=timestamp,v0=hash

The hash is equivalent to the hex encoded sha256 HMAC signature of timestamp.request_body. Both the hash and timestamp should be validated, an example is shown here:

Example python webhook handler using FastAPI:

1from fastapi import FastAPI, Request
2import time
3import hmac
4from hashlib import sha256
5
6app = FastAPI()
7
8# Example webhook handler
9@app.post("/webhook")
10async def receive_message(request: Request):
11 payload = await request.body()
12 headers = request.headers.get("elevenlabs-signature")
13 if headers is None:
14 return
15 timestamp = headers.split(",")[0][2:]
16 hmac_signature = headers.split(",")[1]
17
18 # Validate timestamp
19 tolerance = int(time.time()) - 30 * 60
20 if int(timestamp) < tolerance
21 return
22
23 # Validate signature
24 full_payload_to_sign = f"{timestamp}.{payload.decode('utf-8')}"
25 mac = hmac.new(
26 key=secret.encode("utf-8"),
27 msg=full_payload_to_sign.encode("utf-8"),
28 digestmod=sha256,
29 )
30 digest = 'v0=' + mac.hexdigest()
31 if hmac_signature != digest:
32 return
33
34 # Continue processing
35
36 return {"status": "received"}