Webhook Setup
Webhooks notify your server when events occur in Vocobase, such as a call status changing or a session completing. Instead of polling the API, you receive a POST request with the event payload.What webhooks are for
Vocobase sends two classes of webhook events. Which of your endpoints receive a given event depends on the endpoint’s scope and its event allowlist — see Scoping & Event Filtering:
For outbound telephony calls, use
call.status.updated to know what is happening right now. Use session.completed only when you need final post-call data.
call.status.updated includes:
- Current normalized call status
- Previous status, when available
- Final call disposition and answer classification when available
- Hangup cause/source when the provider supplied them
- Whether the status is terminal
- Whether the call slot/concurrency can be released
- Account-wide concurrency snapshot for queue orchestration
- Provider and raw provider status for debugging
session.completed includes:
- Full conversation transcript with timestamps
- Call duration and credits used
- Recording download URL (if recording was enabled)
- Pre-call variables and post-call extraction results
- Call metadata (phone numbers, provider, direction)
Configure webhook endpoints
Use webhook endpoints to fan events out to one or more destinations, such asprod, staging, or an internal audit receiver. Each endpoint has its own URL, enabled flag, delivery history, and signing secret — plus its own scope (account-wide or bound to one agent) and its own event allowlist, so two endpoints on the same account can receive completely different streams. A new endpoint created as below is account-wide with no allowlist, which means it receives every event type from every agent.
secret that you must save:
agent_id: null means account-wide and events: [] means every event type;
agent_name mirrors the scoped agent’s display name and is null for an
account-wide endpoint. All three are returned on every endpoint object, from
every route that returns one. See
Scoping & Event Filtering to narrow either one.
Manage endpoints
List configured endpoints:{ "endpoints": [...], "available_events": [...] }, where
available_events is the live event catalog. Narrow the list with ?agent_id:
pass an agent id for that agent’s endpoints, or the literal none for
account-wide endpoints only. Omit it to get every endpoint on the account.
Update a label, URL, enabled state, or event allowlist:
Send a test event
Fires a real, signedwebhook.test delivery through the production queue, so it
exercises signing, SSRF validation, and retries, and appears in delivery history
like any other event:
202 means the delivery was enqueued, not that your server accepted it.
Check delivery history for the outcome. A disabled endpoint is refused with
409 ENDPOINT_DISABLED.
Test events ignore the endpoint’s event allowlist by design — a test must
reach the endpoint being tested even when its
events filter would exclude
everything. Handle or ignore webhook.test explicitly in your handler.Delivery history
limit (default 25, max 100), cursor for pagination, and
status to filter by PENDING, DELIVERING, DELIVERED, FAILED, or
EXHAUSTED. Page by passing the previous response’s next_cursor; a null
cursor means there are no more pages.
max_attempts is 5 — the initial delivery plus four retries. See
Error Handling for the schedule.
Labels and limits
- Labels must be lowercase letters, numbers, and hyphens; start with a letter or number; and be 1-31 characters.
- Labels are unique per account, not per scope, so the same label cannot be reused on two agents. The second one is refused with
409 LABEL_TAKEN. - The
defaultlabel is reserved for the legacy single-webhook compatibility route. - Up to 5 endpoints per scope — the account gets its own 5, and so does each agent.
- Only enabled endpoints receive new events.
- Endpoints receive every event type unless you set an
eventsallowlist. See Scoping & Event Filtering. Branch on the top-leveleventfield in your handler either way. - Endpoints are account-wide unless created with an
agent_id, which is set once and cannot be changed afterwards. - Each endpoint signs requests with its own secret.
Existing integrations that use
PUT /api/v2/config/webhook still work. That route now creates or replaces the reserved default endpoint and returns a webhook_secret. New integrations should use /config/webhooks.Requirements
Your webhook endpoint must:- Accept
POSTrequests - Use HTTPS (HTTP URLs are rejected)
- Return a
2xxstatus code within 10 seconds - Be publicly accessible from the internet
Signature verification
Every webhook request includes anX-Webhook-Signature header for verifying authenticity. The signature is computed as an HMAC-SHA256 hash of timestamp.body using your webhook secret.
Header format
Verification steps
- Extract the
X-Webhook-SignatureandX-Webhook-Timestampheaders - Construct the signed payload:
{timestamp}.{raw_request_body} - Compute HMAC-SHA256 using your webhook secret
- Compare the computed signature with the one in the header
Node.js example
Python example
Webhooks vs lifecycle hooks
Webhooks are a one-way, signed, retried event feed: Vocobase tells you something happened, in a fixed payload shape, and keeps retrying until your server accepts it. Lifecycle hooks (PRE_CALL / POST_CALL, configured under an agent’s Actions)
are action runners: they call your API with a body you template, and the
response is used — pre-call output is merged into the prompt’s variables,
post-call output can consume extraction results.
Use a webhook to know something happened. Use a lifecycle hook to fetch or
push data as part of the call. See
Scoping & Event Filtering for a
full comparison.
Next steps
Scoping & Event Filtering
Bind endpoints to one agent and subscribe to specific event types.
Webhook Payloads
See the full payload structure for each event type.
Error Handling
Learn about retry behavior and best practices.