Skip to content

API reference

Webhooks

Webhook subscriptions let TelVox call your endpoints as a call moves through its lifecycle. Each subscription binds one of the nine lifecycle events to a target URL and is delivered over the same signed, SSRF-safe, allow-listed egress that powers TelVox Dial's integrations. Deliveries carry custom headers and an X-TelVox-Signature HMAC so you can verify authenticity. The underlying event delivery is shipped today; self-serve subscription management over this REST surface is in developer preview — today subscriptions are configured through the integration catalog.

Base URL

webhooks
https://api.telvox.dev/v1

Subscription properties

A webhook subscription (the EventSubscription resource) is represented by the following fields.

PropertyTypeDescription
sidstringUnique identifier for the subscription, prefixed WH.
event_typeenumThe lifecycle event this subscription listens for. One subscription targets one event type; see the event enum below.
target_urlstringYour HTTPS endpoint that receives the signed POST. Must resolve to a host on your org's allow-list — egress is SSRF-guarded.
headersobjectOptional custom request headers merged into each delivery (e.g. a routing tag or static bearer for your own gateway).
delivery_modeenumsync (await your 2xx before continuing the call flow, where the event is mid-call) or async (fire-and-forget with retries). Defaults to async.
timeout_msintegerHow long TelVox waits for your response before treating the attempt as failed. Defaults to 5000.
max_retriesintegerRetry attempts on a failed or non-2xx delivery, with exponential backoff. Defaults to 5.
secretstringSigning secret used to compute the X-TelVox-Signature HMAC. Returned once on create; stored AES-256-GCM encrypted thereafter and never echoed back.
payload_templatestringOptional template that reshapes the default JSON body into your own schema before delivery.
statusenumactive or paused. A paused subscription stops receiving deliveries without losing its configuration.
created_atstringISO 8601 timestamp of when the subscription was created.

Event types

TelVox emits nine real call-lifecycle events. One subscription listens for exactly one event_type; create several subscriptions to fan out across events.

event_typeTypeDescription
web-formleadA lead arrived from a web form / inbound injection.
call-startcallA call connected and entered the flow.
hangupcallA call ended; carries final disposition and duration.
no-agentroutingNo agent was available to take a routed call.
dispositioncallAn agent or the flow set a disposition on the call.
callbackscheduleA scheduled callback became due.
queuedacdA call entered an ACD queue.
abandonedacdA queued call abandoned before connecting to an agent.
voicemail-leftcallA voicemail was recorded and left for the campaign or agent.

Create a subscription

POST/v1/webhooks

Subscribe a target URL to a lifecycle event. The signing secret is returned once in the response and never again.

POST/v1/webhooks
curl -X POST https://api.telvox.dev/v1/webhooks \
  -H "Authorization: Bearer $TELVOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event_type": "hangup",
    "target_url": "https://your.app/telvox/hangup",
    "delivery_mode": "async",
    "timeout_ms": 5000,
    "max_retries": 5,
    "headers": { "X-Env": "prod" }
  }'
201 created
ParameterTypeDescription
event_typerequiredenumOne of the nine lifecycle events.
target_urlrequiredstringYour HTTPS endpoint; must be on the org host allow-list.
headersobjectCustom headers to merge into each delivery.
delivery_modeenumsync or async. Defaults to async.
timeout_msintegerPer-attempt timeout in milliseconds. Defaults to 5000.
max_retriesintegerRetry attempts with backoff. Defaults to 5.
payload_templatestringOptional body reshaping template.
Response
{
  "sid": "WH3f9a1c0b2d4e6f80",
  "event_type": "hangup",
  "target_url": "https://your.app/telvox/hangup",
  "delivery_mode": "async",
  "timeout_ms": 5000,
  "max_retries": 5,
  "headers": { "X-Env": "prod" },
  "secret": "whsec_8Kd2...shown_once",
  "status": "active",
  "created_at": "2026-06-21T17:04:11Z"
}
201 created

List subscriptions

GET/v1/webhooks

Return your subscriptions, newest first, with cursor pagination.

GET/v1/webhooks
curl https://api.telvox.dev/v1/webhooks \
  -H "Authorization: Bearer $TELVOX_API_KEY"
200 ok
Response
{
  "data": [
    {
      "sid": "WH3f9a1c0b2d4e6f80",
      "event_type": "hangup",
      "target_url": "https://your.app/telvox/hangup",
      "status": "active"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
200 ok

Fetch a subscription

GET/v1/webhooks/{sid}

Retrieve a single subscription by SID.

GET/v1/webhooks/{sid}
curl https://api.telvox.dev/v1/webhooks/WH3f9a1c0b2d4e6f80 \
  -H "Authorization: Bearer $TELVOX_API_KEY"
200 ok

Update a subscription

POST/v1/webhooks/{sid}

Modify a subscription — pause/resume, change retry/timeout, swap the target URL or headers.

POST/v1/webhooks/{sid}
curl -X POST https://api.telvox.dev/v1/webhooks/WH3f9a1c0b2d4e6f80 \
  -H "Authorization: Bearer $TELVOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "status": "paused", "max_retries": 8 }'
200 ok

Delete a subscription

DELETE/v1/webhooks/{sid}

Permanently remove a subscription. Pending retries for already-emitted events are dropped.

DELETE/v1/webhooks/{sid}
curl -X DELETE https://api.telvox.dev/v1/webhooks/WH3f9a1c0b2d4e6f80 \
  -H "Authorization: Bearer $TELVOX_API_KEY"
204 no content

Delivery payload & signature

TelVox POSTs a JSON body to your target_url and signs it with the subscription secret. Recompute the HMAC over timestamp + "." + body and compare in constant time before acting; reject stale timestamps to guard against replay. A non-2xx response or a timeout is retried with exponential backoff up to max_retries.

Delivery → your endpoint
// POST from TelVox -> your target_url
// Header: X-TelVox-Signature: t=1718989451,v1=hex(hmac_sha256(secret, t + "." + body))
{
  "event_type": "hangup",
  "subscription_sid": "WH3f9a1c0b2d4e6f80",
  "occurred_at": "2026-06-21T17:09:51Z",
  "call_sid": "CA77b1d9e0a4c25f31",
  "data": {
    "from": "+14155550100",
    "to": "+14155550199",
    "duration": 78,
    "disposition": "completed"
  }
}
Your acknowledgement
HTTP/1.1 200 OK

// Respond 2xx within timeout_ms to acknowledge.
// Any non-2xx or a timeout triggers a retry with backoff
// up to max_retries. Verify X-TelVox-Signature before acting.

Security & egress

Every delivery leaves over a signed, SSRF-safe egress path. The target_urlhost must be on your org's allow-list; requests to private/link-local ranges and unresolved hosts are refused. Signing secrets are stored AES-256-GCM encrypted and surfaced only once, at create time.

Inbound lead / event injection

The reverse direction — pushing a lead or event into TelVox — is authenticated by a per-org injection token and an IP allow-list rather than your API key. This inbound surface is shipped in Dial; the public REST shape shown here is preview.

POST/v1/lead-injections
# Inbound lead/event injection — token + IP-allowlisted (roadmap surface)
curl -X POST https://api.telvox.dev/v1/lead-injections \
  -H "X-Injection-Token: $TELVOX_INJECTION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+14155550123",
    "campaign": "renewals-q3",
    "attributes": { "plan": "gold" }
  }'
202 accepted