Webhooks
Get notified in real-time when events happen — calls complete, agents escalate, campaigns finish.
Setup
Configure webhooks in Settings → Webhooks or via the API:
// Register a webhook endpoint
await fetch('https://api.converse.axllabs.in/v2/webhooks', {
method: 'POST',
headers: { 'Authorization': 'Bearer sk_live_...', 'Content-Type': 'application/json' },
body: JSON.stringify({
url: 'https://your-app.com/webhooks/converse',
events: ['call.completed', 'call.escalated', 'campaign.completed'],
secret: 'whsec_your_signing_secret',
}),
});Event Types
call.startedA new call session began (inbound or outbound).
call.completedCall finished. Includes transcript, summary, sentiment, duration, engagement score.
call.escalatedAgent determined human intervention is needed.
call.answeredOutbound call was answered by the contact.
call.no_answerOutbound call was not answered.
call.voicemailVoicemail detected (if AMD enabled).
call.failedCall failed (network error, provider issue, timeout).
transcript.finalFinal transcript segment available (real-time).
tool.calledAgent invoked a tool during the call.
campaign.startedCampaign transitioned to running state.
campaign.pausedCampaign was paused (manual or auto-pause due to low health).
campaign.completedCampaign finished all contacts or reached its goal.
campaign.cancelledCampaign was cancelled.
contact.interestedContact scored 70+ (high engagement). Includes score and summary.
contact.not_interestedContact scored below 40. Marked as not interested.
contact.callback_requestedContact asked to be called back later.
contact.dncContact requested Do Not Call. Auto-added to DNC list.
score.updatedEngagement score changed for a contact. Includes new score and factors.
goal.reachedCampaign reached its configured goal target.
health.lowCampaign health score dropped below threshold.
budget.warningCampaign has used 80%+ of its budget cap.
budget.exhaustedCampaign budget exhausted. Auto-paused.
agent.publishedAn agent was published (configuration changed).
channel.connectedA phone number or WhatsApp was successfully connected.
Payload Format
All webhook payloads follow the CloudEvents specification:
{
"id": "evt_abc123",
"type": "call.completed",
"created_at": "2026-07-01T10:30:00.000Z",
"data": {
"call_id": "call_xyz",
"agent_id": "agent_abc",
"channel": "voice",
"direction": "inbound",
"duration_ms": 45000,
"from_number": "+919876543210",
"summary": "Customer inquired about order #4521 delivery status. Resolved.",
"sentiment_score": 0.8,
"sentiment_label": "positive",
"resolution": "resolved",
"transcript": [
{"role": "assistant", "content": "Hello! How can I help?"},
{"role": "user", "content": "Where is my order?"},
{"role": "assistant", "content": "Order #4521 is out for delivery..."}
]
}
}Security — Signature Verification
Every webhook includes an X-Converse-Signature header containing an HMAC-SHA256 signature. Always verify this to ensure the request came from Converse.
Node.js / Express
import { verifyWebhookSignature } from '@converse/sdk/webhook';
app.post('/webhooks/converse', express.raw({type: 'application/json'}), (req, res) => {
const isValid = verifyWebhookSignature(
req.body,
req.headers['x-converse-signature'],
process.env.WEBHOOK_SECRET!,
);
if (!isValid) return res.status(401).send('Invalid');
// Process event...
res.status(200).send('ok');
});Python / FastAPI
import hmac, hashlib
from fastapi import FastAPI, Request, HTTPException
app = FastAPI()
WEBHOOK_SECRET = "whsec_..."
@app.post("/webhooks/converse")
async def handle_webhook(request: Request):
body = await request.body()
signature = request.headers.get("x-converse-signature", "")
expected = "sha256=" + hmac.new(
WEBHOOK_SECRET.encode(), body, hashlib.sha256
).hexdigest()
if not hmac.compare_digest(signature, expected):
raise HTTPException(status_code=401)
event = await request.json()
print(f"Event: {event['type']}", event['data'])
return {"status": "ok"}Retry Policy
- Webhooks are retried up to 5 times with exponential backoff.
- Schedule: immediately, 30s, 2min, 10min, 1hr.
- Your endpoint must return
2xxwithin 10 seconds. - After 5 failures, the webhook is disabled and you are notified via email.
- You can replay any event from the Webhook Logs in your dashboard.
Testing
Use the webhook test button in your dashboard, or the CLI:
# Send a test event to your endpoint
curl -X POST https://api.converse.axllabs.in/v2/webhooks/test \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"webhook_id": "wh_abc", "event_type": "call.completed"}'