Skip to main content

Webhook Events Reference

Payload shape for every event the platform emits. The names and samples on this page mirror what the dispatcher actually sends — generated from WEBHOOK_EVENT_TYPES in packages/shared/src/constants.ts and the dispatchTenantWebhook / buildWebhookJobs call sites. For the full catalog with one-liner descriptions, see Webhook Events.

Event Envelope

Every webhook delivery wraps the event in a standard envelope:
{
  "id": "evt_abc123",
  "type": "message.delivered",
  "created_at": "2026-03-08T12:00:00Z",
  "data": { "...": "event-specific payload" }
}
FieldTypeDescription
idstringUnique event ID (idempotency key)
typestringEvent type identifier (one of the values in this reference)
created_atstringISO 8601 timestamp
dataobjectEvent-specific payload
truncatedboolean (optional)true only when the original data exceeded 256 KB and was replaced with a pointer-style envelope. Subscribers fetch the full resource via the API.
When truncated: true, data carries _truncated: true, _original_bytes, and a small set of identifier fields (id, message_id, conversation_id, contact_id, campaign_id, channel) so consumers can locate the resource.

Catalog Index

Every webhook event Orbit emits — 185 in total — grouped by surface. Each row links to its long-form payload section below; combined headings (e.g. campaign create / update / delete share one section) point to the first member.

Message Events

EventDescription
message.createdPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
message.sentPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
message.deliveredPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
message.failedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
message.readPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
message.receivedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
message.recipient_deactivatedCarrier number deactivation sweep (R16FIX 2026-05-30) — fires once per deactivated MSISDN the nightly carrier-feed sweep flips to DNC.
message.repliedMESSAGE_REPLIED — fires when an INBOUND message is received in response to an OUTBOUND message (i.e. there is at least one prior outbound message in the same conversation).

Contact Events

EventDescription
contact.createdPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
contact.updatedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
contact.deletedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
contact.trait_changedComputed-trait value transition for a single contact (DECISION — CDPAAS_REAL_TIME_TRAIT_RECOMPUTE_2026_05_28).
contact.bulk_importedFired once per bulk CSV import after all rows are processed.
contact.mergedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
contact.opted_outPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
contact.opted_inPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
contact.recertification_dueReassigned Number Database (RMD) annual recertification due.
contact.segment_changedPredictive-scoring events (migration 077).

Campaign Events

EventDescription
campaign.startedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
campaign.completedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
campaign.pausedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
campaign.resumedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
campaign.drip_step.sentPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
campaign.drip_step.completedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
campaign.drip.completedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
campaign.createdPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
campaign.updatedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
campaign.deletedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.

Voice Events

EventDescription
call.initiatedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
call.answeredPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
call.completedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
call.failedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
call.transferredPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
call.dtmf_sentMid-call DTMF inject (B-237).
call.recording.pausedMid-call recording pause (B-242).
call.recording.resumedMid-call recording resume (B-242).
call.hit_voicemailOutbound call hit a voicemail / fax (Telnyx AMD result = machine|fax).
call.ringingInbound INVITE seen at the SIP edge but call not yet answered.
conference.createdConference lifecycle events (audit #BUG-R65).
conference.participant_joinedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
conference.participant_leftPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
conference.endedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
recording.startedRecording lifecycle events (audit #BUG-R65).
recording.completedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
recording.failedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
recording.qc_failedPost-finalize QC failure (RTC-PaaS competitor-parity gap, 2026-05-29).
voicemail.receivedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
voicemail.transcript_updatedLate-arriving transcript: fires when a voicemail’s transcript was NULL at receipt (Deepgram inline failure) and a subsequent retry recovered it.
call.transcript_readyTelephony-aware CDP — CDP-016 parity wedge (2026-05-29).
call.recording.readyPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
call.transcription.readyPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
call.synthesis.readyAI summary / action-items / sentiment extracted from the transcript (opt-in).
call.synthesizedPhase 4.4 — Post-call synthesis pipeline (scheduler-driven).
recording.retention_deletedFired ahead of a retention-driven GCS purge so tenants can mirror the recording/attachment to their own archive before it is deleted.
recording.chapters.readyRTC-PaaS auto-chaptering (2026-05-28).
voice_eval.run_startedVoice eval regression suite (migration 282, 2026-05-22).
voice_eval.run_completedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
voice_eval.regression_detectedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.

Agent Events

EventDescription
agent.conversation.startedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
agent.conversation.endedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
agent.createdPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
agent.updatedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
agent.deletedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
agent.deployedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
agent.handoff.requestedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
agent.handoff_occurredPhase 4.2 — Fired by agent-runtime the moment one agent delegates a conversation to another specialist agent via the enhanced transfer_to_agent tool.
agent.responsePlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
agent.calendar_event.createdPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
agent.dnc.markedAIaaS-P0-BUG fix (2026-05-30): fired by POST /agents/dnc when an AI voice / text agent invokes the mark_dnc MCP tool and the platform persists the suppression to suppression_list (+ dnc_list mirror for voice/S…
agent.handed_offPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
agent.state.changedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.

Flow Events

EventDescription
flow.execution.startedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
flow.execution.completedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
flow.createdPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
flow.updatedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
flow.deletedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
flow.publishedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
flow.executedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
flow.execution.failedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.

Verification Events

EventDescription
verification.sentPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
verification.approvedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
verification.failedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
verification.checkedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
verification.fallback_triggeredFired by the scheduler-verify-fallback tick each time the async fallback engine advances to a new channel.
verification.fallback_exhaustedFired when the async fallback engine has tried every channel in the fallbackConfig.channels array without obtaining a verified status.

Number / Porting Events

EventDescription
number.purchasedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
number.releasedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
number.portedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
number.inventory.lowLow DID inventory alert (NaaS gap, anchor: PROTOCOL — NAAS_TN_LOW_STOCK_ALERT_2026_05_31).
number.updatedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
porting.request.cancelledNumber porting customer-cancellation event.
porting.request.manual_review_requiredPort-IN fell back into manual-review mode (GAP2_NaaS_115, 2026-05-29).
porting.request.loa_signedPort-IN LOA signed in-platform (cpaasparity2-porting-loa-workflow, 2026-05-29).
number.port_out.requestedNumber port-OUT lifecycle events (NaaS-005 capability-gap fix, 2026-05-29).
number.port_out.cancelledPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.

Conversation Events

EventDescription
conversation.createdPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
conversation.disposedFired by the auto-disposition service when a conversation is automatically closed/resolved by an AI or rule-based disposition engine.
conversation.scoredFired by the QM-scoring service when a conversation receives a quality-management score.
conversation.csat_detractorCSPaaS LOW_CSAT_AUTOMATION_HOOK_2026_05_30 — fired when a customer-facing CSAT (1..5, < 3) or NPS (0..10, 0..6) submission lands and qualifies as a detractor.
conversation.deflectedCSPaaS Intercom Fin / Zendesk parity gap (2026-05-30) — CRM/CDP needs to distinguish AI-resolved volume from human-resolved volume.
conversation.startedConversation lifecycle — fired by the inbox/handoff pipeline.
conversation.closedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.

List / Segment Events

EventDescription
list.createdPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
list.deletedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
segment.createdPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
segment.deletedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.

Webhook Endpoint Events

EventDescription
webhook_endpoint.createdPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
webhook_endpoint.updatedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
webhook_endpoint.deletedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.

Billing Events

EventDescription
subscription.updatedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
balance.topped_upPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
credits.purchasedUse BALANCE_TOPPED_UP instead Deprecated.
balance.lowPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
credits.lowUse BALANCE_LOW instead Deprecated.
invoice.createdPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
payment.failedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.

Channel Failover Events

EventDescription
channel.failoverPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.

Push Events

EventDescription
push.deliveredPush notification SDK ack events.
push.openedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.

Number Masking (Proxy) Events

EventDescription
proxy.session.createdPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
proxy.session.closedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
proxy.message.forwardedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.

WhatsApp Events

EventDescription
whatsapp.account.updatePlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
whatsapp.account.bannedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
whatsapp.account.restrictedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
whatsapp.phone.quality_updatePlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
whatsapp.phone.name_updatePlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
whatsapp.capability.updatePlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
whatsapp.security.alertPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
whatsapp.flow.status_changePlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
whatsapp.template.approvedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
whatsapp.template.rejectedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
whatsapp.template.quality_updatePlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
whatsapp.template.category_updatePlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
whatsapp.template.components_updateMeta auto-edits a template’s components for compliance (e.g. inserts the standard opt-out hint into a MARKETING body).
whatsapp.quality.changedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
whatsapp.call.receivedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
whatsapp.call.connectedWhatsApp Business Calling lifecycle events (Phase 2 — 2026-05-09).
whatsapp.call.acceptedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
whatsapp.call.terminatedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
whatsapp.call.permission_grantedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
whatsapp.call.permission_revokedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
whatsapp.account.alertMeta-issued operational alert about the WABA (e.g. policy violation, pricing change effective date, payment method failed).
whatsapp.account.review_updateWABA went through a Meta-side review that updated its compliance status (e.g. moved to RESTRICTED / FLAGGED).
whatsapp.business.status_updateBusiness profile status changed at Meta (verification badge, official business account flag, business status).
whatsapp.user.preferencesUser-level marketing preference signal.
whatsapp.data.export_requestGDPR Article 15 (data subject access request) — user invoked “Request my data” inside the conversation.
whatsapp.data.delete_requestGDPR Article 17 (right to erasure) — user invoked “Delete my data”.
whatsapp.account.settings_updateWABA-level settings changed (commerce/profile/etc.).
whatsapp.automatic_eventsMeta’s auto-detected business events (cart abandoned, etc.).
whatsapp.group.lifecycle_updateWA Group lifecycle (created/deleted).
whatsapp.group.participants_updateWA Group participants joined/left.
whatsapp.group.settings_updateWA Group renamed/description changed.
whatsapp.group.status_updateWA Group activated/archived.
whatsapp.historyInitial-connection backfill of historical messages.
whatsapp.partner_solutionsPartner integration events.
whatsapp.payment_configuration_updatePayment setup state changed (WA Pay).
whatsapp.smb.app_state_syncSMB app state sync events.
whatsapp.smb.message_echoesEchoes of messages sent from the SMB app (hybrid setups).
whatsapp.template.correct_category_detectionMeta detected the template’s category was wrong vs. its actual intent.
whatsapp.tracking_eventsPer-message tracking events (link clicks, etc.).

Supervisor Events

EventDescription
supervisor.takeover_requestedFired when a supervisor initiates a warm-handoff takeover of a live call.
supervisor.takeover_failedFired when a supervisor takeover attempt fails (e.g. Jambonz REST error during the leg-swap).
supervisor.takeover_completedFired when the supervisor successfully takes over the call and becomes the active party.
supervisor.takeover_cancelledFired when a takeover is cancelled (call ended before handoff completed, or supervisor explicitly aborted).

SIP Trunk Events

EventDescription
sip_trunk.status_changedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.

CDP Events

EventDescription
cdp.event.ingestedCDP inbound — fired after a Segment-shaped /cdp/track or /cdp/identify payload is verified, persisted to tenant_*.cdp_events, and identity- resolved against tenant_*.contacts.
cdp.identity.resolvedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.

Other

EventDescription
email.openedEmail engagement events (Resend webhook surface).
email.clickedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
video.recording.degradedPARITY-RTC-R1 (2026-05-29) — video room recording QC verdict.
video.room.startedGAP-RTC-R2 (2026-05-29) — video room + participant + recording lifecycle webhook fan-out.
video.room.endedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
video.participant.joinedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
video.participant.leftPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
video.recording.completedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
video.recording.failedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
ticket.deflectedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
wallboard.sla_warningVoice-queue wallboard SLA early-warning (CCaaS).
wfm.adherence_breachWFM intraday adherence breach (CCaaS / WFM pillar, 2026-05-30).
survey.csat.response_recordedPost-call IVR survey response recorded (CCaaS, 2026-05-30).
survey.nps.response_recordedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
queue.call.queuedCCaaS queue-routing lifecycle webhooks (Five9 / Genesys parity — Interaction.Routed / Interaction.Abandoned).
queue.call.abandonedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.
queue.call.assignedPlatform-defined webhook event. See source comment in packages/shared/src/constants.ts for context.

Message Events

message.created

Fired when an outbound message is accepted and queued for delivery.
{
  "id": "evt_abc",
  "type": "message.created",
  "created_at": "2026-03-08T12:00:00Z",
  "data": {
    "message_id": "msg_abc123",
    "channel": "sms",
    "to": "+14155552671",
    "from": "+18005551234",
    "status": "queued",
    "created_at": "2026-03-08T12:00:00Z"
  }
}

message.sent

Fired when the message is handed off to the carrier / provider.
{
  "type": "message.sent",
  "data": {
    "message_id": "msg_abc123",
    "channel": "sms",
    "to": "+14155552671",
    "status": "sent",
    "external_id": "carrier-side-id"
  }
}

message.delivered

{
  "type": "message.delivered",
  "data": {
    "message_id": "msg_abc123",
    "status": "delivered",
    "channel": "sms",
    "timestamp": "2026-03-08T12:00:03Z"
  }
}

message.failed

Terminal failure reported by the carrier (or a synthesised failure covering undelivered / rejected).
{
  "type": "message.failed",
  "data": {
    "message_id": "msg_abc123",
    "status": "failed",
    "channel": "sms",
    "timestamp": "2026-03-08T12:00:05Z"
  }
}

message.read

{
  "type": "message.read",
  "data": {
    "message_id": "msg_abc123",
    "status": "read",
    "channel": "whatsapp",
    "timestamp": "2026-03-08T12:00:10Z"
  }
}

message.received

Inbound message from a recipient.
{
  "type": "message.received",
  "data": {
    "message_id": "msg_inb_456",
    "channel": "sms",
    "from": "+14155552671",
    "to": "+18005551234",
    "body": "What is my order status?",
    "metadata": { "raw_provider_id": "..." }
  }
}

Contact Events

contact.created

{ "type": "contact.created", "data": { "contact_id": "con_abc123" } }

contact.updated

{ "type": "contact.updated", "data": { "contact_id": "con_abc123" } }

contact.deleted

{ "type": "contact.deleted", "data": { "contact_id": "con_abc123" } }

contact.merged

{ "type": "contact.merged", "data": { "contact_id": "con_abc123" } }

contact.bulk_imported

Fired once per bulk import batch (CSV upload or POST /v1/contacts/bulk), not once per row. The payload summarises the whole batch.
{
  "id": "evt_abc",
  "type": "contact.bulk_imported",
  "created_at": "2026-03-08T12:00:00Z",
  "data": {
    "imported": 480,
    "updated": 12,
    "failed": 8,
    "total": 500,
    "import_batch_id": "imb_abc123"
  }
}
FieldTypeDescription
importedintegerNew contact rows created on this batch
updatedintegerExisting contact rows merged on this batch (upsert toggle on)
failedintegerRows rejected by validation / dedup / DB constraint
totalintegerimported + updated + failed
import_batch_idstring | nullStable identifier for this batch — present when the API was able to persist the import-jobs row; null only on legacy in-line imports without a job row
Delivery semantics: at-least-once. This event rides the standard webhook delivery queue (BullMQ with attempts: 10 and exponential backoff starting at 30s — see apps/api/src/lib/webhook-queue.ts WEBHOOK_DELIVERY_DEFAULT_JOB_OPTIONS). Transient receiver errors (5xx, timeouts) trigger automatic retries, so the same contact.bulk_imported payload can be delivered more than once. Orbit does not guarantee exactly-once delivery on any webhook.Your consumer must be idempotent. Recommended dedupe key, in order of preference:
  1. Envelope id — the top-level event id is unique per delivery attempt’s logical event and is the canonical idempotency key for every Orbit webhook (id is stable across retries of the same event). Persist seen id values for at least 7 days (the longest the queue can hold a retry window: 10 attempts × 30s exponential ≈ 8.5h plus the dead-letter replay window).
  2. data.import_batch_id — when non-null, import_batch_id is the natural key for the underlying batch. If you write summary counters into your own DB, key them on import_batch_id so a replay does not double-add the totals.
If neither key is available (import_batch_id: null and a malformed envelope), treat the delivery as a no-op observability signal and fetch authoritative state via GET /v1/contacts/import-jobs.

contact.opted_in / contact.opted_out

Fired when a recipient sends a START / STOP keyword on a registered channel.
{
  "type": "contact.opted_out",
  "data": {
    "channel": "sms",
    "phone": "+14155552671",
    "keyword": "STOP",
    "timestamp": "2026-03-08T12:05:00Z"
  }
}

contact.recertification_due

FCC RMD annual consent recertification window opened on a contact.
{
  "type": "contact.recertification_due",
  "data": {
    "contact_id": "con_abc123",
    "consent_id": "consent_xyz",
    "channel": "sms",
    "granted_at": "2025-05-09T00:00:00Z",
    "age_days": 365,
    "phone_number": "+14155552671",
    "email": null,
    "timestamp": "2026-05-09T00:00:00Z"
  }
}

contact.segment_changed

Predictive scorer flipped a contact’s segment label (e.g. champion → at_risk, passive → engaged). Useful for triggering re-engagement plays from a CRM.
{
  "type": "contact.segment_changed",
  "data": {
    "contact_id": "con_abc123",
    "previous_label": "champion",
    "new_label": "at_risk",
    "churn_risk": 0.71,
    "intent_score": 0.32,
    "propensity_score": 0.18,
    "ltv_estimate_cents": 12400,
    "signals": ["sms_open_drop", "click_drop"],
    "computed_at": "2026-03-08T12:00:00Z"
  }
}

Campaign Events

campaign.created / campaign.updated / campaign.deleted

{ "type": "campaign.created", "data": { "campaign_id": "camp_abc123" } }

campaign.started

{
  "type": "campaign.started",
  "data": { "campaign_id": "camp_abc123", "status": "running" }
}

campaign.completed

{
  "type": "campaign.completed",
  "data": { "campaign_id": "camp_abc123", "status": "completed" }
}

campaign.paused / campaign.resumed

{ "type": "campaign.paused", "data": { "campaign_id": "camp_abc123" } }

campaign.drip_step.completed

Single drip step finished sending to its slice.
{
  "type": "campaign.drip_step.completed",
  "data": {
    "campaign_id": "camp_abc123",
    "step_index": 2,
    "sent": 480,
    "failed": 12
  }
}

campaign.drip.completed

Entire drip campaign finished its full schedule.
{
  "type": "campaign.drip.completed",
  "data": {
    "campaign_id": "camp_abc123",
    "status": "completed",
    "summary": { "steps": 5, "sent": 2400, "failed": 60 }
  }
}

Voice Events

call.initiated

{ "type": "call.initiated", "data": { "call_id": "call_abc123" } }
When the call is bridged through Jambonz, the payload also carries provider and direction context:
{
  "type": "call.initiated",
  "data": {
    "call_id": "call_abc123",
    "provider": "jambonz",
    "provider_call_sid": "CA-…",
    "direction": "inbound",
    "from": "+14155552671",
    "to": "+18005551234",
    "status": "ringing",
    "timestamp": "2026-03-08T12:00:00Z"
  }
}

call.answered

{
  "type": "call.answered",
  "data": {
    "call_id": "call_abc123",
    "provider": "jambonz",
    "provider_call_sid": "CA-…",
    "direction": "inbound",
    "from": "+14155552671",
    "to": "+18005551234",
    "status": "in-progress",
    "timestamp": "2026-03-08T12:00:08Z"
  }
}

call.completed

{
  "type": "call.completed",
  "data": {
    "call_id": "call_abc123",
    "provider": "jambonz",
    "provider_call_sid": "CA-…",
    "direction": "inbound",
    "from": "+14155552671",
    "to": "+18005551234",
    "status": "completed",
    "duration_seconds": 142,
    "hangup_reason": "normal_clearing",
    "sip_response_code": 200,
    "sip_reason": "OK",
    "timestamp": "2026-03-08T12:02:22Z"
  }
}

call.failed

{
  "type": "call.failed",
  "data": {
    "call_id": "call_abc123",
    "provider": "jambonz",
    "provider_call_sid": "CA-…",
    "direction": "outbound",
    "from": "+18005551234",
    "to": "+14155559999",
    "status": "no-answer",
    "duration_seconds": 0,
    "hangup_reason": "no_user_response",
    "sip_response_code": 480,
    "sip_reason": "Temporarily Unavailable",
    "timestamp": "2026-03-08T12:00:30Z"
  }
}

call.transferred

{
  "type": "call.transferred",
  "data": {
    "call_id": "call_abc123",
    "transferred_to": "+14155558888"
  }
}

call.dtmf_sent

Mid-call DTMF inject through the API.
{
  "type": "call.dtmf_sent",
  "data": {
    "call_id": "call_abc123",
    "digits": "1234",
    "duration_ms": 100,
    "gap_ms": 80,
    "timestamp": "2026-03-08T12:01:30Z"
  }
}

call.recording.paused / call.recording.resumed

SIPREC fork toggled mid-call.
{
  "type": "call.recording.paused",
  "data": {
    "call_id": "call_abc123",
    "recording": false,
    "timestamp": "2026-03-08T12:01:00Z"
  }
}

call.recording.ready

{
  "type": "call.recording.ready",
  "data": {
    "call_id": "call_abc123",
    "recording_url": "gs://devotel-recordings/...",
    "duration_seconds": 142,
    "timestamp": "2026-03-08T12:06:00Z"
  }
}

call.transcription.ready

{
  "type": "call.transcription.ready",
  "data": {
    "call_id": "call_abc123",
    "transcript_length": 4820,
    "timestamp": "2026-03-08T12:06:30Z"
  }
}

call.synthesis.ready (legacy inline pipeline)

{
  "type": "call.synthesis.ready",
  "data": {
    "call_id": "call_abc123",
    "summary": "Customer asked about order ORD-12345…",
    "action_items": ["Send tracking link"],
    "sentiment": "neutral",
    "topics": ["order_status"],
    "timestamp": "2026-03-08T12:07:00Z"
  }
}

call.synthesized (post-call synthesis pipeline)

Richer payload from the async synthesis scheduler. Gated on tenant opt-in.
{
  "type": "call.synthesized",
  "data": {
    "call_id": "call_abc123",
    "direction": "inbound",
    "from": "+14155552671",
    "to": "+18005551234",
    "duration_seconds": 142,
    "ended_at": "2026-03-08T12:02:22Z",
    "synthesis": {
      "summary": "...",
      "sentiment": "neutral",
      "key_points": ["..."],
      "follow_up_actions": ["..."],
      "facts_learned": ["..."],
      "customer_intent": "order_status",
      "resolution": "resolved"
    },
    "synthesised_at": "2026-03-08T12:08:00Z"
  }
}

call.ringing

Fires when an inbound call is detected by the SIP edge but before it is answered. Useful for “live caller is dialing in” UI updates without waiting for the post-answer call.answered event.
{
  "type": "call.ringing",
  "data": {
    "call_id": "call_abc123",
    "provider": "jambonz",
    "provider_call_sid": "CA-…",
    "direction": "inbound",
    "from": "+14155552671",
    "to": "+18005551234",
    "status": "ringing",
    "timestamp": "2026-03-08T12:00:01Z"
  }
}
Trigger condition: carrier sends INVITE to the SIP edge. Retry behaviour: standard webhook retry (exponential 1m → 5m → 15m → 1h → 6h, 5 attempts max). Idempotent — multiple ring callbacks during a single call can fire if the call is being routed via multiple ring-group legs. Note (current implementation): ringing is currently bundled with the call.initiated event for inbound calls. The standalone call.ringing event is emitted by the underlying carrier webhook but only forwarded to tenant subscribers when the org explicitly subscribes. If call.ringing is missing from your delivery, fall back to listening for call.initiated with status: "ringing".

call.early_media

Fires when the carrier begins streaming pre-answer audio — a SIP 180 Ringing response carrying SDP. This is the moment ringback tone, IVR prompts, voicemail greetings, or answering-machine-detection (AMD) audio start playing into the bridge BEFORE the destination has formally answered (200 OK). Useful for IVR routing decisions, AMD branching, and accurate “Ringing…” → “Audio streaming” UX transitions on softphone clients.
{
  "type": "call.early_media",
  "data": {
    "call_id": "call_abc123",
    "call_sid": "CA-…",
    "provider": "jambonz",
    "direction": "outbound",
    "from": "+18005551234",
    "to": "+14155552671",
    "status": "early_media",
    "timestamp": "2026-03-08T12:00:02Z"
  }
}
Trigger condition: carrier sends a 180 Ringing with an application/sdp body, OR a 183 Session Progress with SDP. Distinct from call.ringing (which fires on 180 Ringing WITHOUT SDP, i.e. headers-only ringback). Retry behaviour: standard webhook retry (exponential 1m → 5m → 15m → 1h → 6h, 5 attempts max). The event is fire-and-forget — a subsequent call.answered event always follows on the same call_id once the destination picks up. Note (current implementation): the event is published both on the tenant SSE channel (events:tenant_<id>) for live dashboard updates AND via signed webhooks for subscribers who opt in. The SSE channel is what powers the browser softphone’s “Audio streaming” label and the <audio> element’s autoplay-unblock call; the webhook is the durable delivery path for backend systems.

Conference Events

Conference lifecycle events fire from the conference service in apps/api/src/routes/voice/. The events ride the same delivery + retry semantics as call events.

conference.created

Fires when POST /api/v1/voice/conferences succeeds.
{
  "type": "conference.created",
  "data": {
    "conference_id": "conf_abc123",
    "name": "Q1 Planning Call",
    "max_participants": 25,
    "record": true,
    "created_by_user_id": "usr_xxx",
    "timestamp": "2026-03-08T12:00:00Z"
  }
}

conference.participant_joined

Fires when a new participant successfully joins (after 200 OK to the SIP INVITE for that leg).
{
  "type": "conference.participant_joined",
  "data": {
    "conference_id": "conf_abc123",
    "participant_id": "cpart_def456",
    "call_id": "call_xyz789",
    "phone_number": "+14155552671",
    "muted": false,
    "joined_at": "2026-03-08T12:01:14Z"
  }
}

conference.participant_left

Fires when a participant disconnects — either via DELETE API call, BYE from the carrier, or the conference moderator’s end-conference action.
{
  "type": "conference.participant_left",
  "data": {
    "conference_id": "conf_abc123",
    "participant_id": "cpart_def456",
    "call_id": "call_xyz789",
    "duration_seconds": 312,
    "reason": "normal_disconnect",
    "timestamp": "2026-03-08T12:06:26Z"
  }
}
reason values: normal_disconnect (BYE from participant), kicked (DELETE via API), conference_ended (moderator ended), network_failure (RTP timeout).

conference.ended

Fires when the conference’s active participant count drops to zero, or moderator hits end-conference. Always the LAST event for a conference id.
{
  "type": "conference.ended",
  "data": {
    "conference_id": "conf_abc123",
    "duration_seconds": 1840,
    "participant_count": 7,
    "ended_reason": "moderator_ended",
    "recording_url": "https://storage.devotel.io/conf/conf_abc123.mp3",
    "timestamp": "2026-03-08T12:30:40Z"
  }
}
ended_reason values: moderator_ended, last_participant_left, max_duration_reached.

Recording Events

recording.started

Fires when POST /api/v1/voice/calls/{id}/recording/start (or the per-call record:true flag) starts a fresh recording.
{
  "type": "recording.started",
  "data": {
    "recording_id": "rec_abc123",
    "call_id": "call_abc123",
    "dual_channel": true,
    "started_at": "2026-03-08T12:00:08Z"
  }
}

recording.completed

Alias for call.recording.ready (same payload + same recording_url). Documented separately because the call-id may not be available for conference recordings — those carry conference_id instead.
{
  "type": "recording.completed",
  "data": {
    "recording_id": "rec_abc123",
    "call_id": "call_abc123",
    "duration_seconds": 142,
    "format": "mp3",
    "size_bytes": 4980000,
    "recording_url": "https://storage.devotel.io/recordings/rec_abc123.mp3",
    "url_expires_at": "2026-03-09T12:06:00Z",
    "timestamp": "2026-03-08T12:06:00Z"
  }
}

recording.failed

Fires when an upstream recording attempt fails (storage write failure, codec mismatch, AMD aborted the recording before any audio was captured).
{
  "type": "recording.failed",
  "data": {
    "recording_id": "rec_abc123",
    "call_id": "call_abc123",
    "reason": "storage_write_failed",
    "details": "GCS 503 — Service Unavailable",
    "timestamp": "2026-03-08T12:06:02Z"
  }
}

voicemail.received

{
  "type": "voicemail.received",
  "data": {
    "voicemail_id": "vm_abc123",
    "call_id": "call_abc123",
    "from": "+14155552671",
    "transcript": "Hi, please call me back at noon — I had a question about…",
    "timestamp": "2026-03-08T12:05:00Z"
  }
}

voicemail.transcript_updated

Fires when an originally-missing voicemail transcript is recovered by the retry pipeline.
{
  "type": "voicemail.transcript_updated",
  "data": {
    "voicemail_id": "vm_abc123",
    "transcript": "Recovered transcript text…"
  }
}

recording.retention_deleted

Fires 24h before a retention-driven GCS purge so tenants can mirror the asset to their own archive. Payload carries a signed download URL valid until purge_scheduled_at.
{
  "type": "recording.retention_deleted",
  "data": {
    "source": "call",
    "source_id": "call_abc123",
    "channel": "voice",
    "created_at": "2025-05-08T00:00:00Z",
    "gcs_uri": "gs://...",
    "download_url": "https://storage.googleapis.com/...?X-Goog-Signature=...",
    "download_url_expires_at": "2026-05-10T00:00:00Z",
    "purge_scheduled_at": "2026-05-10T00:00:00Z",
    "retention_policy": {
      "voice_days": 365,
      "sms_days": 365,
      "email_days": 365,
      "whatsapp_days": 365,
      "rcs_days": 365,
      "viber_days": 365,
      "apply_hard_delete": true
    },
    "timestamp": "2026-05-09T00:00:00Z"
  }
}

Agent Events

agent.created / agent.updated / agent.deleted / agent.deployed

{
  "type": "agent.created",
  "data": {
    "agent_id": "agt_abc123",
    "name": "Support Bot",
    "type": "voice"
  }
}

agent.conversation.started

{
  "type": "agent.conversation.started",
  "data": {
    "conversation_id": "conv_001",
    "agent_id": "agt_abc123",
    "model": "claude-sonnet-4-6",
    "timestamp": "2026-03-08T12:00:00Z"
  }
}

agent.conversation.ended

{
  "type": "agent.conversation.ended",
  "data": {
    "conversation_id": "conv_001",
    "agent_id": "agt_abc123",
    "reason": "Escalated to human agent",
    "end_status": "escalated",
    "timestamp": "2026-03-08T12:15:00Z"
  }
}

agent.handoff.requested

Agent escalated to a human operator.
{
  "type": "agent.handoff.requested",
  "data": {
    "conversation_id": "conv_001",
    "agent_id": "agt_abc123",
    "reason": "Customer requested human agent",
    "status": "escalated"
  }
}

agent.handoff_occurred

Agent delegated to another specialist agent through the transfer_to_agent tool.
{
  "type": "agent.handoff_occurred",
  "data": {
    "handoff_id": "ho_001",
    "source_agent_id": "agt_general",
    "target_agent_id": "agt_billing",
    "conversation_id": "conv_001",
    "reason": "Billing question",
    "summary": "User asked about invoice INV-2026-…"
  }
}

agent.calendar_event.created

Fires from the agent’s create_calendar_event MCP tool.
{
  "type": "agent.calendar_event.created",
  "data": {
    "event_id": "cal_evt_001",
    "title": "Meeting with Jane Doe",
    "description": "Discuss enterprise plan",
    "start_time": "2026-03-09T10:00:00Z",
    "end_time": "2026-03-09T10:30:00Z",
    "attendee_email": "jane@example.com",
    "conversation_id": "conv_001"
  }
}

Flow Events

flow.created / flow.updated / flow.published / flow.deleted

{ "type": "flow.created", "data": { "flow_id": "flow_abc123" } }

flow.executed

Coarse terminal signal. status is completed, failed, or timeout.
{
  "type": "flow.executed",
  "data": {
    "flow_id": "flow_abc123",
    "execution_id": "exec_001",
    "status": "completed",
    "step_count": 8
  }
}

flow.execution.started

{
  "type": "flow.execution.started",
  "data": {
    "flow_id": "flow_abc123",
    "execution_id": "exec_001",
    "node_count": 12,
    "timestamp": "2026-03-08T12:00:00Z"
  }
}

flow.execution.completed

{
  "type": "flow.execution.completed",
  "data": {
    "flow_id": "flow_abc123",
    "execution_id": "exec_001",
    "step_count": 8,
    "duration_ms": 5200,
    "timestamp": "2026-03-08T12:00:05Z"
  }
}

flow.execution.failed

{
  "type": "flow.execution.failed",
  "data": {
    "flow_id": "flow_abc123",
    "execution_id": "exec_001",
    "error": "node http_request failed: 502",
    "step_count": 3,
    "duration_ms": 1300,
    "timestamp": "2026-03-08T12:00:01Z"
  }
}

Verification Events

The platform uses the verification.* prefix (not verify.*).

verification.sent

{
  "type": "verification.sent",
  "data": {
    "verification_id": "ver_abc123",
    "channel": "sms",
    "to": "+14155552671"
  }
}
When a SIM-swap soft warning is detected, sim_swap_warning: true is included alongside the payload above.

verification.approved

{
  "type": "verification.approved",
  "data": {
    "verification_id": "ver_abc123",
    "channel": "sms",
    "to": "+14155552671"
  }
}
For Silent Verification (SIM-card-network-binding flow), channel is "silent".

verification.failed

{
  "type": "verification.failed",
  "data": {
    "verification_id": "ver_abc123",
    "channel": "sms",
    "to": "+14155552671",
    "reason": "max_attempts_exceeded"
  }
}
When the failure is a SIM-swap block, reason: "sim_swap_detected" plus last_swap_date are included.

Number / Porting Events

number.purchased

{
  "type": "number.purchased",
  "data": {
    "number_id": "num_abc123",
    "phone_number": "+14155550100"
  }
}
reclaimed: true is included when the number was re-claimed from the parking pool.

number.released

{ "type": "number.released", "data": { "number_id": "num_abc123" } }

number.ported

{
  "type": "number.ported",
  "data": {
    "porting_id": "port_001",
    "numbers": ["+14155550100", "+14155550101"],
    "carrier": "Verizon",
    "provider": "telnyx",
    "status": "submitted"
  }
}

porting.request.cancelled

Customer aborted an in-flight port.
{
  "type": "porting.request.cancelled",
  "data": {
    "porting_request_id": "port_001",
    "numbers": ["+14155550100"],
    "cancelled_from_status": "submitted"
  }
}

Conversation Events

conversation.created

{
  "type": "conversation.created",
  "data": {
    "conversation_id": "conv_001",
    "campaign_id": "camp_abc123",
    "agent_id": "agt_abc123",
    "contact_id": "con_xyz789",
    "recipient": "+14155552671",
    "source": "journey"
  }
}

List / Segment Events

{ "type": "list.created", "data": { "list_id": "list_abc" } }
{ "type": "list.deleted", "data": { "list_id": "list_abc" } }
{ "type": "segment.created", "data": { "segment_id": "seg_abc" } }
{ "type": "segment.deleted", "data": { "segment_id": "seg_abc" } }

Webhook Endpoint Events

{ "type": "webhook_endpoint.created", "data": { "endpoint_id": "wh_abc" } }
{ "type": "webhook_endpoint.updated", "data": { "endpoint_id": "wh_abc" } }
{ "type": "webhook_endpoint.deleted", "data": { "endpoint_id": "wh_abc" } }

Billing Events

balance.low

{
  "type": "balance.low",
  "data": {
    "remaining_cents": 75,
    "remaining_usd": "0.75",
    "threshold_cents": 100,
    "triggered_by": "message:msg_abc123",
    "timestamp": "2026-03-08T12:00:00Z"
  }
}

balance.topped_up

{
  "type": "balance.topped_up",
  "data": {
    "organization_id": "org_abc",
    "amount_cents": 5000,
    "currency": "usd"
  }
}

credits.purchased (deprecated alias of balance.topped_up)

Same data plus a legacy credits field. Prefer balance.topped_up for new integrations.

Channel Failover Events

channel.failover

Fired when a messaging channel’s primary provider failed and Orbit automatically switched to a backup.
{
  "type": "channel.failover",
  "data": {
    "channel": "sms",
    "failed_provider": "telnyx",
    "active_provider": "jasmin",
    "error_message": "HTTP 502 from carrier",
    "message_id": "msg_abc123",
    "attempt_index": 1,
    "timestamp": "2026-03-08T12:00:00Z"
  }
}

Push Events

push.delivered

Mobile / web SDK acknowledged a push was rendered on-device.
{
  "type": "push.delivered",
  "data": {
    "id": "push_abc123",
    "device_token_id": "dt_abc",
    "at": "2026-03-08T12:00:01Z"
  }
}

push.opened

User tapped the push and the SDK reported the open.
{
  "type": "push.opened",
  "data": {
    "id": "push_abc123",
    "device_token_id": "dt_abc",
    "at": "2026-03-08T12:01:30Z"
  }
}

Number Masking (Proxy) Events

proxy.session.created

{
  "type": "proxy.session.created",
  "data": {
    "session_id": "psess_abc",
    "proxy_number": "+14155550100",
    "participant_a": "+14155552671",
    "participant_b": "+14155558888",
    "expires_at": "2026-03-08T13:00:00Z"
  }
}

proxy.session.closed

{
  "type": "proxy.session.closed",
  "data": {
    "session_id": "psess_abc",
    "proxy_number": "+14155550100",
    "closed_at": "2026-03-08T12:45:00Z"
  }
}

proxy.message.forwarded

{
  "type": "proxy.message.forwarded",
  "data": {
    "session_id": "psess_abc",
    "proxy_number": "+14155550100",
    "from_participant": "+14155552671",
    "to_participant": "+14155558888",
    "channel": "sms"
  }
}

WhatsApp Events

WhatsApp events mirror Meta WABA webhook fields. Each fires after Orbit ingests the corresponding Meta callback and persists the upstream change. Payloads carry the relevant waba_id / phone_number_id so consumers can correlate to their own Meta tooling.

WhatsApp Calling

The lifecycle events (whatsapp.call.connected, _accepted, _terminated) share the same payload shape; the legacy whatsapp.call.received is also dispatched on every transition for backward-compatible consumers.
{
  "type": "whatsapp.call.connected",
  "data": {
    "waba_id": "1234567890",
    "phone_number_id": "0987654321",
    "meta_call_id": "wacid_…",
    "wa_call_log_id": "wacall_…",
    "direction": "inbound",
    "from": "+14155552671",
    "to": "+18005551234",
    "phase": "connect",
    "meta_event": "connect",
    "meta_status": null,
    "duration_seconds": null,
    "biz_opaque_callback_data": null
  }
}
whatsapp.call.permission_granted:
{
  "type": "whatsapp.call.permission_granted",
  "data": {
    "contact_id": "con_abc",
    "waba_id": "1234567890",
    "phone_number_id": "0987654321",
    "source": "inbound_call",
    "ttl_seconds": 86400,
    "meta_call_id": "wacid_…"
  }
}
whatsapp.call.permission_revoked:
{
  "type": "whatsapp.call.permission_revoked",
  "data": {
    "contact_id": "con_abc",
    "waba_id": "1234567890",
    "phone_number_id": "0987654321",
    "meta_call_id": "wacid_…"
  }
}

WhatsApp Templates

Sample for whatsapp.template.approved (others share the same shape with the relevant Meta payload echoed under details):
{
  "type": "whatsapp.template.approved",
  "data": {
    "waba_id": "1234567890",
    "template_id": "tpl_abc",
    "template_name": "appointment_reminder_v1",
    "language": "en_US",
    "details": { "...": "Meta event payload" }
  }
}
whatsapp.template.rejected includes details.reason with Meta’s rejection text.

WhatsApp Account / Business / Phone

whatsapp.account.update, whatsapp.account.banned, whatsapp.account.restricted, whatsapp.account.alert, whatsapp.account.review_update, whatsapp.account.settings_update, whatsapp.business.status_update, whatsapp.phone.quality_update, whatsapp.phone.name_update, whatsapp.capability.update, whatsapp.security.alert, whatsapp.flow.status_change, whatsapp.quality.changed — all share the shape:
{
  "type": "whatsapp.account.banned",
  "data": {
    "waba_id": "1234567890",
    "details": { "...": "Meta event payload" }
  }
}

WhatsApp Data Subject Requests

{
  "type": "whatsapp.data.export_request",
  "data": {
    "waba_id": "1234567890",
    "user": "+14155552671",
    "details": { "...": "Meta payload" }
  }
}
whatsapp.data.delete_request follows the same shape.

WhatsApp v25 fields

whatsapp.automatic_events, whatsapp.history, whatsapp.partner_solutions, whatsapp.payment_configuration_update, whatsapp.smb.app_state_sync, whatsapp.smb.message_echoes, whatsapp.tracking_events, whatsapp.user.preferences, whatsapp.group.lifecycle_update, whatsapp.group.participants_update, whatsapp.group.settings_update, whatsapp.group.status_update — each carries the original Meta event payload under details:
{
  "type": "whatsapp.tracking_events",
  "data": {
    "waba_id": "1234567890",
    "details": { "...": "Meta event payload" }
  }
}

Subscribing to Events

Register a webhook and specify which events to receive:
curl -X POST https://orbit-api.devotel.io/api/v1/webhooks \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourapp.com/webhooks/orbit",
    "events": ["message.delivered", "message.failed", "call.completed"],
    "secret": "whsec_your_secret"
  }'
Use "events": ["*"] to subscribe to all event types. Subscribing to a name not listed on this page returns a 422.

See also