Skip to content

Receive results

Configure one endpoint and the platform pushes the results you subscribe to. Call completion, saved business actions and later analysis are separate events; enable the ones you need with PUT /v1/webhook-endpoint {"url": …, "enabled_events": […]}.

Home → Recent conversations and Activity → Calls show up to three current recorded responses from each call, including qualification status, shift responses, and saved or proposed caller details. These remain available when an AI summary is unavailable. If a call has more responses, the preview shows the total; open the call for every response, its caller evidence and correction history.

Proposed contact changes require review before changing an existing contact. A recorded shift response does not confirm an assignment. Qualification notes describe what was recorded and do not establish a booked appointment or callback.

The call-list API adds recorded_responses and recorded_response_count separately from AI summary and captured_fields. Preview notes and values may be shortened; their note_truncated and value_truncated flags identify shortened values. The full receipt remains in the call detail’s conversation_actions collection.

call.ended - appended in the same transaction that finalizes the call:

{
"call_id": "call_01J9…",
"contact_id": "cont_01J9…",
"agent_version_id": "agv_01J9…",
"direction": "outbound",
"duration_ms": 93000,
"disposition": "completed_no_goal",
"sub_code": "survey_completed",
"recording_available": true,
"transcript_available": true,
"transcript_url": "/v1/calls/call_01J9…/transcript",
"survey_response": {
"survey_response_id": "srv_01J9…",
"completion_status": "complete",
"score": 0.83,
"answers": {
"csat_overall": { "answer": 4, "verbatim_quote": "a four, pretty good" },
"q_delivered": { "answer": true, "verbatim_quote": "yes it did" }
}
},
"analysis_pending": true
}

The completion event carries call metadata and inline survey/appointment results. Saved action receipts and later analysis arrive separately. Transcript text stays out by design - transcript_url points at the authenticated API. analysis_pending: true says the post-call judge hasn’t run yet; its verdict arrives as call.analyzed.

survey.completed - when the call produced a survey response: the ids, completion_status, score, and the same inline answers.

call.analyzed - minutes later, the judge’s verdict: success, score, a bounded summary, extracted_fields, per-dimension results (goal completion, disclosure, opt-out honored, knowledge grounding), and latency percentiles - the same shape GET /v1/calls/{id} serves in analysis.

Answer entries carry the caller’s verbatim_quote, so the events you enable are your consent surface for conversation-derived data reaching your endpoint.

A snow-service company can use one receiver for customer reception, worker support, shoveler outreach and customer qualification. Route each verified event inside your integration; subscribing another workflow does not require replacing the company’s existing webhook endpoint.

Work Events to consider What to save in your system
Customer or worker support message.taken, ticket.opened, ticket.resolved The caller-request ID, call/contact references and the recorded message or ticket state. Use the request ID to correlate resolution.
Availability for several shifts conversation.action_recorded with data.kind = "shift_response" A response for each call and subject_ref (shift), plus its source turns and correction history. Accepted, declined and tentative are separate responses.
Customer fit or candidate screening conversation.action_recorded with data.kind = "qualification" The sales or recruiting subject, recorded status, summary and configured answers in payload. Preserve answered, unknown and refused rather than converting missing answers to “no.”
Call summary call.ended, then call.analyzed Call completion first, then the bounded summary and extracted fields. Analysis can arrive later and does not prove an action succeeded.
Suppression optout.recorded The suppression reference and originating call, routed to your contact/suppression workflow. “Not interested” alone is a qualification response, not this event.

A worker’s accepted response is not a staffing assignment. Your staffing system or dispatcher confirms the assignment. Likewise, captured interest or a next-step note is not a qualified customer, booked callback or hiring decision. Require the corresponding saved action or human decision before promising it.

conversation.action_recorded carries an immutable receipt in data: its id, call_id, nullable contact_id, kind, subject_ref, revision, response, payload, source_turns and created_at, plus confirmation evidence when present. This event is committed with the receipt. The legacy shift.confirmed event is a compatibility projection; use the receipt collection when one call discusses several shifts.

Keep receipt history by data.id. For a current-response view, group by (tenant_id, call_id, kind, subject_ref). Rank receipts by the highest source_turns[].turn_number first (zero when absent), then revision as a tie-breaker. Arrival time and revision alone cannot determine the current answer: a delayed older turn can be saved with a higher database revision.

For example, these are reduced views of four shift-response receipts in one call:

Shift (subject_ref) Response Highest source turn Revision Current response
morning-route accepted 4 1 Replaced by the later caller correction
afternoon-route tentative 6 1 Tentative for this separate shift
morning-route declined 9 2 Declined for the morning shift
morning-route accepted 3 3 Delayed earlier evidence; keep in history

Serialize updates to each current-response record or use a transactional compare and update so concurrent deliveries cannot overwrite newer evidence. Scope records to the verified tenant. Dedupe the envelope’s event.id, save the receipt and update the current view in one transaction, or first persist the whole event in a durable queue and process it idempotently. Return 2xx only after durable acceptance. The signature verifier below does not implement this storage step.

For recovery, GET /v1/calls/{call_id} with calls:read returns the call’s conversation_actions history. Rebuild each subject’s current response using the same ordering. A call’s general disposition or analysis summary does not replace the per-subject receipts.

Read GET /v1/webhook-endpoint before changing subscriptions. Preserve its URL, api_version_pin and existing enabled_events; explicitly add the selected workflow events to that set. PUT /v1/webhook-endpoint replaces the configuration, so sending only the new workflow’s events can stop the existing support feed. Endpoint setup requires webhooks:manage; reading calls requires calls:read. Keep API keys and signing secrets on your server.

Use the portal’s integration setup or your own receiver to forward verified records into a CRM, staffing system or helpdesk. These are API/webhook integration paths; they do not imply a native connector to a particular vendor.

Every delivery is HMAC-signed: Vocapable-Signature: t=<unix>,v1=<hex>. Verify with the snippets in the Webhooks guide - reject skew over 5 minutes, and accept either v1 entry during a secret rotation’s 24-hour overlap.

Terminal window
curl -X POST https://api.vocapable.com/v1/webhook-endpoint/test \
-H "Authorization: Bearer $VOCAPABLE_API_KEY"

Sends one signed sample (data.test: true) with production mechanics - same envelope, same signature, same secrets, same 10-second success rule - and reports {delivered, status_code}. A receiver that verifies the ping verifies real traffic. Recognize data.test: true and acknowledge it without creating customer work.

Deliveries retry on a ladder (1m, 5m, 30m, 2h, 6h, then 6-hourly) for 24 hours, then mark exhausted. If your receiver was down longer than that:

Terminal window
curl https://api.vocapable.com/v1/webhook-deliveries?status=exhausted \
-H "Authorization: Bearer $VOCAPABLE_API_KEY"
curl -X POST https://api.vocapable.com/v1/webhook-deliveries/whd_01J9…/redrive \
-H "Authorization: Bearer $VOCAPABLE_API_KEY"

Each redrive grants exactly one more attempt and is available only for an exhausted delivery. Delivery remains at-least-once, so receivers must dedupe on event.id.

Everything pushed is also pullable: GET /v1/calls/{id}, /transcript, GET /v1/survey-responses?call_id=…, GET /v1/campaigns/{id}/survey-rollup, and bulk POST /v1/exports. Webhooks are the fast path, not the only path.