Handle webhook
Updated
Use webhooks to collect agent lifecycle, error, history, and metrics events on your backend.
A webhook is a user-defined HTTPS callback that lets your backend receive notifications when Conversational AI events occur. Agora sends POST requests to your webhook endpoint so your system can react to agent lifecycle changes, history delivery, errors, and performance metrics in real time.
For the combined entry point that compares client toolkit and webhook delivery, see Get runtime events.
Use this page when you need durable backend records for monitoring, alerting, or analytics. If you need live UI state inside the app, use Client-side events.
Understand the tech
Using Agora Console, you subscribe to specific events for your project and configure the URL of the webhook endpoint that receives them. Agora sends event notifications to that endpoint whenever the subscribed events occur. Your server verifies the request signature, processes the JSON payload, and returns 200 OK to confirm receipt.
Common uses
Webhooks are typically used to:
- Track when an agent joins or leaves a channel
- Receive short-term memory history after an agent session ends
- Capture module-level errors for monitoring and debugging
- Collect performance metrics such as LLM and TTS latency
Prerequisites
Before you begin, make sure you have:
- An Agora account
- An active Agora project with Conversational AI enabled
- A public HTTPS endpoint that can receive webhook callbacks
- Server-side access to store and validate the secret used for signature verification
Enable notifications
To enable Agora notifications for Conversational AI:
- Sign in to the Agora Console.
- Open Projects and locate the target project.
- Open the Notifications configuration area for the project.
- Select the Conversational AI event types you want to subscribe to.
- Enter the HTTPS callback URL of your receiving server.
- Save the generated Secret. You need it for signature verification.
- Run the console-side health check and confirm your server responds with
200 OK.
Recommended webhook endpoint settings
- Use HTTPS only.
- Enable HTTP keep-alive if possible.
- Make sure your server responds within 10 seconds.
Request header
The header of notification callbacks contains the following fields:
| Field name | Value |
|---|---|
Content-Type | application/json |
Agora-Signature | Signature generated with the secret using HMAC/SHA1 |
Agora-Signature-V2 | Signature generated with the secret using HMAC/SHA256 |
Request body
The request body of notification callbacks contains the following fields:
| Field name | Type | Description |
|---|---|---|
noticeId | String | Notification ID that uniquely identifies this callback |
productId | Number | Product ID of the notification source |
eventType | Number | Type of event being notified |
notifyMs | Number | Unix timestamp in milliseconds when Agora sends the callback |
payload | JSON object | Event-specific data |
The following example shows a sample request body:
{
"noticeId": "2000001428:4330:107",
"productId": 1,
"eventType": 101,
"notifyMs": 1611566412672,
"payload": {}
}Conversational AI event types
Agora can notify your server of the following Conversational AI events:
| eventType | Description |
|---|---|
101 | Agent joined a channel |
102 | Agent left a channel |
103 | Dialogue history notification |
110 | Agent error |
111 | Agent performance metrics |
201 | Incoming call status change |
202 | Outgoing call status change |
For payload details, see Notification event types.
Signature verification
To communicate securely between Agora and your webhook, Agora uses signatures for identity verification:
- When you configure notifications in Agora Console, Agora generates a secret for your project.
- When sending a notification, Agora generates
Agora-SignatureandAgora-Signature-V2values using HMAC/SHA1 and HMAC/SHA256. - When your server receives the callback, verify one of those signatures against the raw request body.
The following Go example calculates a signature and compares it with the received value:
import (
"crypto/hmac"
"crypto/sha1"
"encoding/hex"
"net/http"
)
const secret = "<replace-with-your-secret>"
func calcSignatureV1(secret, payload string) string {
mac := hmac.New(sha1.New, []byte(secret))
mac.Write([]byte(payload))
return hex.EncodeToString(mac.Sum(nil))
}
func verify(requestBody, signature string) bool {
calculatedSignature := calcSignatureV1(secret, requestBody)
return calculatedSignature == signature
}After reading the request body in your handler, verify the signature:
if !verify(string(body), agoraSignature) {
http.Error(w, "Invalid signature", http.StatusUnauthorized)
return
}Best practices
- Keep the webhook secret on the server side only.
- Store raw payloads for troubleshooting when useful.
- Design webhook processing to be idempotent, because retries can happen.
- Return
200 OKquickly and move heavier processing to async workers if needed.
