Developer
⌘K
Dashboard
Call Logs POST

Webhooks

Receive real-time call data when a call ends.

Webhooks

Tabbly sends a real-time webhook to your endpoint whenever a call concludes — both answered and not answered. The payload includes transcript, summary, sentiment, QA pairs, recording URL, and cost details so you can sync call data into your CRM or backend without polling Get Call Logs.

Setup

  1. Log in to the Tabbly dashboard.
  2. Open Developer API from the sidebar.
  3. Scroll to the Webhook URL field at the bottom of the page.
  4. Paste your publicly reachable HTTPS endpoint (for example https://your-app.com/webhooks/tabbly).
  5. Click Update to store the URL for your organization.

After updating, Tabbly will POST JSON to that URL as soon as each call ends. Leave the field empty to disable webhooks.

Endpoint requirements

  • Accept HTTP POST with Content-Type: application/json.
  • Return HTTP 2xx quickly to acknowledge receipt (ideally within a few seconds).
  • Tabbly does not retry failed deliveries — process or queue the payload before responding if your work is slow.

Delivery

http
POST https://your-webhook-url.com

Tabbly calls the URL you configured in Developer API. There is no Tabbly-hosted webhook path to call yourself.

Headers

Header Value
Content-Type application/json

Example request

What Tabbly sends to your endpoint after a completed answered call:

http
POST /webhooks/tabbly HTTP/1.1
Host: your-app.com
Content-Type: application/json
json
{
  "participant_identity": "user-a0dfacddba6e58ff0ccc223239f919",
  "use_agent_id": "854",
  "called_to": "Web Call",
  "called_time": "2025-05-30 05:37:09",
  "custom_identifiers": "",
  "call_status": "Call Answered",
  "call_duration": "137",
  "start_time": "2025-05-30 05:37:12",
  "end_time": "2025-05-30 05:39:29",
  "call_transcript": "[0 - 6] Agent: Hello, this is rohan from tabbly.\n[6 - 13] User: Yes?\n...",
  "call_summary": "The call was a screening interview for a PHP Developer role. The candidate expressed positive interest and provided solid answers about their experience with PHP and willingness to work on-site.",
  "call_sentiment": 8,
  "call_json_output": "{\"summary\":\"The call was a screening interview for a PHP Developer role.\",\"sentiment\":8,\"timestamps\":{\"questions\":{\"1\":[\"0:26\",\"0:48\"]},\"answers\":{\"1\":[\"0:48\",\"0:55\"]},\"qa_pairs\":[{\"question_1\":\"Do you have experience working with PHP in a professional setting?\",\"answer_1\":\"Yes, I worked for 5 years. In PHD.\"}],\"output_status\":\"Review\"}",
  "call_recording_url": null,
  "total_call_cost": "0.1783",
  "telco_pricing": "0.0092",
  "agent_cost": 0.1507,
  "organization_id": "234",
  "call_direction": "outbound"
}

Not answered calls

Not answered calls use the same field set. Transcript, summary, sentiment, JSON output, and recording are typically null, and call_duration is 0:

json
{
  "participant_identity": "camp-2904-4199969-c31493bea9",
  "use_agent_id": "6355",
  "called_to": "+912269858803",
  "called_time": "2026-07-09 03:41:11",
  "custom_identifiers": "",
  "campaign_id": "2904",
  "call_status": "Not Answered",
  "call_duration": 0,
  "start_time": "2026-07-09 03:41:11",
  "end_time": "2026-07-09 03:41:41",
  "call_transcript": null,
  "call_summary": null,
  "call_sentiment": null,
  "call_json_output": null,
  "call_recording_url": null,
  "total_call_cost": 0,
  "telco_pricing": "0.0092",
  "agent_cost": 0,
  "organization_id": "3282",
  "call_direction": "outbound"
}

Payload fields

Field Type Description
participant_identity string Unique call / participant ID
use_agent_id string Voice agent ID that handled the call
called_to string Destination number, or Web Call for browser calls
called_time string When the call was placed (YYYY-MM-DD HH:MM:SS)
custom_identifiers string Optional contact tag from Add Contacts; may be empty
campaign_id string Campaign ID when the call belongs to a campaign; may be empty
call_status string e.g. Call Answered, Not Answered
call_duration string | number Duration in seconds
start_time string Call start timestamp
end_time string Call end timestamp
call_transcript string | null Full timed conversation transcript
call_summary string | null AI-generated summary of the call
call_sentiment integer | null Sentiment score from 1–10
call_json_output string | null JSON string with structured data (summary, sentiment, QA pairs, timestamps, output_status)
call_recording_url string | null URL to the call recording when available
total_call_cost string | number Total cost of the call
telco_pricing string Telco / carrier cost component
agent_cost number Agent / AI cost component
organization_id string Your organization ID
call_direction string outbound or inbound

call_json_output (parsed)

When present, parse the string as JSON. Typical shape:

Field Type Description
summary string Call summary
sentiment integer Sentiment score (1–10)
timestamps object Question/answer time ranges
qa_pairs array Extracted question and answer pairs
output_status string Processing status (e.g. Review)

Expected response

Return any 2xx status as soon as you have accepted the payload:

http
HTTP/1.1 200 OK
Content-Type: application/json

{"ok": true}

The response body is ignored. Non-2xx responses are treated as delivery failures and are not retried.

Notes

  • Webhooks fire for both answered and not answered calls after the call concludes.
  • Configure one webhook URL per organization in Developer API; it applies to all agents and campaigns under that org.
  • Prefer queueing heavy work (CRM sync, analytics) after returning 200 so Tabbly’s request does not time out.
  • For historical or filtered retrieval, use Get Call Logs in addition to webhooks.