Available Webhooks
This page lists the webhook event types Truedy can send, what each event means, and the identifiers you should extract for safe processing. For end-to-end webhook delivery mechanics (signatures, envelope format, and receiver patterns), see:Webhook request envelope (what you receive)
Truedy delivers an HTTPPOST with this JSON shape:
- The top-level
eventis normalized (for examplecall.completedis normalized tocall.ended). - The
dataobject contains the original Ultravox event payload. Depending on the event, identifiers may live atdata.call.*,data.batch_*,data.voice_*, etc. - There is no guarantee that any single optional field is present. Always validate defensively.
How to dedupe (recommended)
Because webhook delivery can be at-least-once and payloads may repeat, dedupe using one of:- A unique identifier inside the payload (often
data.id/data.eventId) - A stable entity identifier for the event family:
- Call events: prefer
data.call.callId(ordata.call_id/data.callId) - Batch events: prefer
data.batch_id(ordata.batchId) - Voice events: prefer
data.voice_id(ordata.voiceId)
- Call events: prefer
event + top_level_timestamp + url + phone_number), but that may be less reliable.
Event types
| Event | What it means | Primary identifiers to extract | Typical use |
|---|---|---|---|
call.started | A call has started | data.call.callId / data.call.agent.agentId | Update “in progress” UI/CRM |
call.joined | The participant joined the call | data.call.callId | Start “call connected” workflows |
call.ended | The call has ended (final state) | data.call.callId plus duration/cost/summary when present | Mark call complete; store analytics |
call.billed | A billing event for a call | data.call.callId | Reconcile billing / minutes usage |
call.failed | The call failed | data.call.callId | Mark failure; trigger retries or alerts |
batch.status.changed | Batch campaign status changed | data.batch_id / data.batchId | Update campaign progress |
batch.completed | Batch campaign completed | data.batch_id / data.batchId | Final reconciliation |
voice.training.completed | Voice training finished successfully | data.voice_id / data.voiceId | Enable voice for use |
voice.training.failed | Voice training failed | data.voice_id / data.voiceId | Surface error to user; allow re-training |
Call events (payload shapes)
call.started
Use this when you want near-real-time “started” updates.
Example (minimal shape):
uv_call_id = data.call.callIduv_agent_id = data.call.agent.agentId
call.joined
Example:
uv_call_id = data.call.callId
call.ended
This is the final “call summary” event. Truedy normalizes call.completed into call.ended.
Example (fields you may see):
uv_call_id = data.call.callId(ordata.call_id/data.callId)duration_secondsfromdata.call.duration/data.call.ended(when present)summary,shortSummary,costUsd,endReason,billingStatus(when present)
call.billed
Example:
uv_call_id = data.call.callId
call.failed
Example:
uv_call_id = data.call.callId- failure reason fields you see (for example
endReason)
Batch / campaign events (payload shapes)
batch.status.changed
This event is primarily for updating campaign progress. Truedy may reconcile state by fetching the latest batch status internally.
Example (minimal shape):
uv_batch_id = data.batch_id(ordata.batchId)new_status = data.data.status(ordata.status)
batch.completed
Example:
uv_batch_id = data.batch_id(ordata.batchId)
Voice training events (payload shapes)
voice.training.completed
Example:
uv_voice_id = data.voice_id(ordata.voiceId)
voice.training.failed
Example:
uv_voice_id = data.voice_id(ordata.voiceId)error_message/data.error_message/data.data.error_message(wherever it appears)
Defensive parsing checklist
When writing your webhook receiver:- Treat every optional field as optional.
- Support camelCase and snake_case where possible (
callIdvscall_id, etc.). - Always validate that the identifier you use for dedupe exists and is non-empty.
- Store the dedupe key and the raw payload for debugging.
Managing webhook endpoints
Webhook endpoints are managed through the Truedy dashboard under Settings → Webhooks. You can add, edit, and delete endpoints there. When you create an endpoint, you are given a signing secret — store it immediately as it is only shown once.Webhook endpoint management (create, list, delete) is not available via the public API. Use the dashboard at Settings → Webhooks to configure your endpoints.
Next steps
Securing Webhooks
Node.js, Python, and Flask signature verification
Error Handling & Retries
Idempotent receiver with full database example

