Converse Logo
Developers

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:

typescript
// 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'],
  }),
});

The create response contains the signing secret once. Store it securely; you choose event subscriptions, but the platform generates the secret.

Event Types

call.started

A new call session began (inbound or outbound).

call.completed

Call finished. Includes transcript, summary, sentiment, duration, engagement score.

call.escalated

Agent determined human intervention is needed.

call.failed

Call failed (network error, provider issue, timeout).

call.sentiment_negative

A completed call was classified as negative.

transcript.ready

Transcription and post-call analysis finished.

contact.created

A customer contact was created.

contact.updated

A customer contact changed.

contact.lifecycle_changed

A contact moved to another lifecycle stage.

deal.stage_changed

A customer journey moved to another pipeline stage.

campaign.started

Campaign transitioned to running state.

campaign.paused

Campaign was paused (manual or auto-pause due to low health).

campaign.completed

Campaign finished all contacts or reached its goal.

campaign.cancelled

Campaign was cancelled.

campaign.contact.completed

A campaign contact reached a terminal outcome.

campaign.goal_reached

Campaign reached its configured completion goal.

campaign.health_low

Campaign health fell below its warning threshold.

campaign.budget_warning

Campaign usage crossed 80% of its budget.

campaign.budget_exhausted

Campaign reached its budget and dispatch was paused.

score.changed

A customer or journey score changed.

sync.completed

A connected source finished synchronising.

sync.failed

A connected source could not finish synchronising.

Payload Format

All webhook payloads follow the CloudEvents specification:

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

typescript
import { verifyWebhookSignature } from '@converse/sdk/webhook';

app.post('/webhooks/converse', express.raw({type: 'application/json'}), async (req, res) => {
  const isValid = await 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

python
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

Testing

Test your receiver locally with a fixture signed by the same HMAC-SHA256 procedure, then confirm production delivery using your endpoint's delivery history. The public API does not expose a synthetic-event route.