Open in
telephony.complete / web.complete
அழைப்பு முடிவடையும் போது, டிரான்ஸ்கிரிப்ட், பதிவு URL மற்றும் அளவீடுகளுடன் வழங்கப்படும் தடைசெய்யாத webhook.
ஒவ்வொரு அழைப்பும் முடிந்த பிறகு ஒரு நிறைவு நிகழ்வு செயல்படும் — உள்வரும் தொலைபேசி அழைப்பு, வெளிச்செல்லும் தொலைபேசி அழைப்பு, வலை அழைப்பு அல்லது சோதனை அழைப்பு (builder மைக் அமர்வு). இது தடையற்றது: எந்த 2xx பதிலையும் வழங்குங்கள்.
நிகழ்வு இரண்டு பாதைகளிலும் வழங்கப்படும்:
- Webhook எண்ட்பாயிண்ட்கள் கீழே ஆவணப்படுத்தப்பட்ட நிலையான payload, ஒவ்வொரு வழங்கலுக்குமான
event_id, 30 s நேரமுடிவு மற்றும் 24 h வரை மீண்டும் முயற்சிகள் உடன்telephony.complete(தொலைபேசி அழைப்புகள்) அல்லதுweb.complete(வலை அழைப்புகள் மற்றும் builder மைக் சோதனை அழைப்புகள்) பெறும். - மரபு ஒற்றை-URL webhook சற்று மாறுபட்ட payload உடன் ஒரு ஒத்திசைவு முயற்சியைப் பெறும் (10 s நேரமுடிவு, மீண்டும் முயற்சிகள் இல்லை) — மரபு payload வேறுபாடுகள் என்பதைப் பார்க்கவும்.
கோரிக்கை payload (எண்ட்பாயிண்ட் வழங்கல்கள்)
{
"data": {
"billable_minutes": 1.25,
"billing_total_cents": 8,
"call_id": 987654321,
"direction": "inbound",
"duration_seconds": 54,
"end_reason": "user_hangup",
"end_time": "2026-04-20T18:25:04.822Z",
"from_number": "+14155550199",
"product": "spark",
"recording_url": "https://storage.example.com/…",
"start_time": "2026-04-20T18:24:10.113Z",
"status": "completed",
"to_number": "+15551234567",
"transcripts": [ /* see Transcript format */ ],
"transfer_number": null,
"voice": "john"
},
"event_id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
"type": "telephony.complete"
}| புலம் | வகை | விளக்கம் |
|---|---|---|
call_id | integer | இந்த அழைப்பிற்கான ஒவ்வொரு நிகழ்விலும் நிலையானது |
agent_id | integer | null | ஒதுக்கப்பட்டிருந்தால், அழைப்பைக் கையாண்ட ஏஜென்ட் |
agent_name | string | null | ஒதுக்கப்பட்டிருந்தால், அழைப்பைக் கையாண்ட ஏஜென்ட் |
direction | string | inbound, outbound, web, test. வரலாற்று payloadகளில் மரபு mic அல்லது widget மதிப்புகள் இருக்கலாம் |
from_number, to_number | string | E.164. வலை அழைப்புகள் மற்றும் சோதனை அழைப்புகளுக்கு from_number என்பது நேரடியான "web" ஆகும் |
origin_domain | string | வலை/சோதனை மட்டும் — widgetஐ ஹோஸ்ட் செய்த பக்கத்தின் தோற்றம் (மைக் அமர்வுகளுக்கு காலி) |
start_time, end_time | timestamp | ISO 8601 UTC |
duration_seconds | integer | null | தொடக்க/முடிவு நேரத்திலிருந்து பெறப்பட்டது |
status | string | completed அல்லது failed |
end_reason | string | கீழேயுள்ள அட்டவணையைப் பார்க்கவும் |
product, voice | string | அழைப்பு நேரத்தில் செயலிலிருந்த ஏஜென்ட் கட்டமைப்பு |
transfer_number | string | null | அழைப்பு மாற்றப்பட்டபோது அமைக்கப்படும் |
recording_url | string | null | காலாவதியாகும் கையொப்பமிடப்பட்ட URL; உடனடியாகப் பதிவிறக்கவும். பதிவு கலைப்பொருள் கிடைக்காதபோது null |
billable_minutes | number | கட்டணமிடப்பட்ட நிமிடங்கள், அருகிலுள்ள கால் நிமிடத்திற்கு வட்டமிடப்படும் (15-வினாடி அதிகரிப்புகள், குறைந்தபட்சம் 0.25). நேரடியாக voicemailக்கு செல்லும் அழைப்புகளும் அவற்றின் உண்மையான மீட்டர் செய்யப்பட்ட நிமிடங்களை இங்கே தெரிவிக்கும், ஆனால் கட்டணம் திட்ட விகிதத்தில் ஒரு நிமிடமாக வரம்பிடப்படும். |
billing_total_cents | integer | USD சென்ட்கள் |
transcripts | array | ஒவ்வொரு முறைக்குமான transcript உள்ளீடுகள்; transcript கிடைக்காதபோது காலியாக இருக்கலாம் |
முடிவு காரணங்கள்
| மதிப்பு | பொருள் |
|---|---|
user_hangup | தொலைதூர தரப்பு முதலில் அழைப்பைத் துண்டித்தது |
ai_hangup | AI திட்டமிட்டு அழைப்பை முடித்தது |
ai_transfer | AI அழைப்பை மாற்றியது; transfer_number அமைக்கப்படும் |
ai_warm_transfer | AI ஒரு warm (attended) மாற்றத்தை நிறைவு செய்தது |
voicemail_hangup | Voicemail கண்டறியப்பட்டு, உங்கள் voicemail_action படி அழைப்பு முடிக்கப்பட்டது |
max_duration | அழைப்பு அதிகபட்ச கால அளவு வரம்பை எட்டியது |
superseded | அமர்வு புதிய ஒன்றால் மாற்றப்பட்டது |
unknown | முடிவு காரணத்தைத் தீர்மானிக்க முடியவில்லை |
உரையாடல் பதிவின் வடிவம்
transcripts இல் உள்ள ஒவ்வொரு பதிவும் ஒரு உரையாடல் முறை ஆகும். பங்குகள்
user (அழைப்பாளரின் பேச்சு), model (ஏஜென்டின் பேச்சு மற்றும் கருவி அழைப்புகள்),
tool (கருவி முடிவுகள்), மற்றும் system (மொழி
மாற்றங்கள் போன்ற அழைப்பு நிகழ்வுகள்) ஆகும்.
[
{
"role": "user",
"content_type": "text/plain",
"content": "Hi, I'm calling about my appointment.",
"start_ms": 1200,
"end_ms": 4100,
"audio_url": "https://storage.example.com/…"
},
{
"role": "model",
"content_type": "text/plain",
"content": "Sure, what date works best?",
"start_ms": 4200,
"end_ms": 6100
},
{
"role": "model",
"content_type": "application/json",
"content": {
"tool_call": "search_appointments",
"arguments": { "date": "2026-04-21" }
}
},
{
"role": "tool",
"content_type": "application/json",
"content": {
"tool_name": "search_appointments",
"response": { "available_slots": ["9:00 AM", "2:00 PM"] }
}
}
]| புலம் | வகை | விளக்கம் |
|---|---|---|
role | string | user, model, tool, அல்லது system |
content_type | string | பேச்சுக்கு text/plain; கருவி அழைப்புகள், கருவி முடிவுகள் மற்றும் அமைப்பு நிகழ்வுகளுக்கு application/json |
content | string | object | பேச்சு உரை அல்லது மேலே காட்டப்பட்ட கட்டமைக்கப்பட்ட பொருள். கருவி அழைப்புகள்: {"tool_call": name, "arguments": {…}}. கருவி முடிவுகள்: {"tool_name": name, "response": {…}} |
start_ms, end_ms | integer | அழைப்பு தொடக்கத்திலிருந்து இடைவெளிகள், ms. ஆடியோ நேரம் அறியப்படும்போது இருக்கும் |
ttfa_ms | integer | அளவிடப்பட்டிருந்தால், model முறைக்கான முதல் ஆடியோ வரையிலான நேரம் |
audio_url, audio_urls | string / array | ஒவ்வொரு முறையாக பதிவு செய்யப்பட்டால், அந்த முறையின் ஆடியோவுக்கான காலாவதியாகும் கையொப்பமிடப்பட்ட URLs |
முழுமையாக கட்டமைக்கப்பட்ட முறை வரலாற்றுக்கு (குறுக்கீட்டு குறிப்பான்கள்,
ஒப்புதல் promptகள் மற்றும் மூல நிலைகள் உட்பட),
GET /v1/calls/{call_id}/history ஐப் பயன்படுத்துங்கள்.
பழைய payload வேறுபாடுகள்
பழைய ஒற்றை-URL webhook உறை
{"type": "telephony.complete" | "web.complete", "data": {…}}; இதில்
event_id இல்லை, மேலும் அதன் data, endpoint payload இலிருந்து வேறுபடுகிறது:
பழைய நிறைவு payload இல் agent_id மற்றும் agent_name ஆகியவையும் இருக்கும்.
- முறை வரிசை
transcriptsஇல் அல்லாமல்historyஇன் கீழ் இருக்கும் (மேலே உள்ள அதே முறை schema). - புலத் தொகுப்பு என்பது அழைப்பு முடிவின் மூல அறிக்கையாகும்; இதில் மேலே உள்ள அட்டவணைக்கு அப்பாற்பட்ட கூடுதல் உள்புறப் புலங்கள் இருக்கலாம் — அறியப்படாத புலங்களை தகவலுக்கானவை எனக் கருதுங்கள்.
- வலை அழைப்புகள் (
direction: "web")from_number/to_numberஐ விடுத்துவிடும் மற்றும்origin_domainஐச் சேர்க்கும். - Builder மைக் சோதனை அழைப்புகள் பழைய பாதையில்
telephony.completeஆக அறிக்கையிடப்படும் (endpoint அமைப்பு அவற்றைweb.completeஆக வரைபடமாக்கும்). - பரிமாற்ற ஒருங்கிணைப்பு: ஒரு அழைப்பு பரிமாற்றத்தில் முடிவடைந்தால், பழைய webhook ஒத்திசைவாக அழைக்கப்படும்;
பரிமாற்ற இலக்கு தயாராக இல்லை என்பதைக் குறிக்க அது
{"transfer_ready": false}எனப் பதிலளிக்கலாம். வேறு எந்தப் பதிலும் (அல்லது பழைய webhook இல்லாததும்) பரிமாற்றத்தைத் தொடர அனுமதிக்கும். இதற்காக endpoint வழங்கல்கள் ஒருபோதும் ஆலோசிக்கப்படாது.
எடுத்துக்காட்டு ஹேண்ட்லர்
import hashlib
import hmac
import json
import os
from fastapi import FastAPI, HTTPException, Request
app = FastAPI()
SECRET = os.environ["THUNDERPHONE_WEBHOOK_SECRET"]
def verify(body: bytes, signature: str) -> bool:
expected = hmac.new(SECRET.encode(), body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature or "")
@app.post("/thunderphone-webhook")
async def webhook(request: Request):
body = await request.body()
if not verify(body, request.headers.get("X-ThunderPhone-Signature", "")):
raise HTTPException(status_code=401)
event = json.loads(body)
if event["type"] in ("telephony.complete", "web.complete"):
data = event["data"]
# Endpoint deliveries use "transcripts"; the legacy webhook uses "history".
turns = data.get("transcripts") or data.get("history") or []
await persist_call_record(
call_id=data["call_id"],
turns=turns,
recording_url=data.get("recording_url"),
)
if data["end_reason"] in ("ai_transfer", "ai_warm_transfer"):
await notify_team(data.get("transfer_number"), data["call_id"])
return {"ok": True}import crypto from "node:crypto";
import express from "express";
const app = express();
const SECRET = process.env.THUNDERPHONE_WEBHOOK_SECRET;
function verify(body, signature) {
const expected = crypto.createHmac("sha256", SECRET).update(body).digest("hex");
return signature &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}
app.post(
"/thunderphone-webhook",
express.raw({ type: "application/json" }),
async (req, res) => {
if (!verify(req.body, req.header("X-ThunderPhone-Signature"))) {
return res.sendStatus(401);
}
const event = JSON.parse(req.body.toString("utf8"));
if (["telephony.complete", "web.complete"].includes(event.type)) {
const data = event.data;
// Endpoint deliveries use "transcripts"; the legacy webhook uses "history".
const turns = data.transcripts ?? data.history ?? [];
await persistCallRecord({ ...data, turns });
if (["ai_transfer", "ai_warm_transfer"].includes(data.end_reason)) {
await notifyTeam(data.transfer_number, data.call_id);
}
}
res.json({ ok: true });
},
);பொதுவான பயன்பாட்டு நிலைகள்
ஒவ்வொரு அழைப்பின் உரைநகல் + பதிவு URL-ஐ உங்கள் வாடிக்கையாளர் பதிவுகளுடன் சேமிக்கவும்.
தலைப்பு மாதிரியாக்கம், CSAT சிக்னல் பிரித்தெடுத்தல் அல்லது மாற்று-விகித கண்காணிப்புக்காக உரைநகல்களை ஒரு பைப்லைனுக்கு ஸ்ட்ரீம் செய்யவும்.
மனித மதிப்பாய்வுக்காக அழைப்புகளை ஒரு QA கருவியில் திறக்கவும் அல்லது அவற்றை உங்கள் சொந்த மதிப்பீட்டு மாடல் மூலம் இயக்கவும்.
மாற்றுதல் / தோல்வியின்போது ஒரு மனித அணியினருக்கான அறிவிப்பைத் தொடங்கவும்.