ThunderPhone 2.0 on nüüd saadaval.Iseteenindusena alates 2 senti/min.Loe uudist

Webhooks

telephony.complete / web.complete

Blokeerimata webhook, mis saadetakse kõne lõppedes koos transkriptsiooni, salvestise URL-i ja mõõdikutega.

Lõpetamissündmus käivitub pärast iga kõne lõppu — sissetulev telefonikõne, väljaminev telefonikõne, veebikõne või testkõne (ehitaja mikrofoni seanss). See on mitteblokeeriv: vasta mis tahes 2xx-koodiga.

Sündmus edastatakse mõlemal viisil:

Päringu andmepakett (lõpp-punkti edastused)

{
  "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",
    "extracted_data": {
      "status": "completed",
      "fields": {
        "customer_name": "Alex Morgan",
        "appointment_date": "2026-04-23"
      },
      "evidence": {
        "customer_name": {
          "quote": "My name is Alex Morgan",
          "speaker_role": "caller",
          "turn_index": 4
        },
        "appointment_date": {
          "quote": "April 23 works for me",
          "speaker_role": "caller",
          "turn_index": 7
        }
      },
      "verification": "verified",
      "field_reasons": {},
      "schema_version": "92850758e231a3c95a..."
    },
    "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,
    "unresolved_variables": ["campaign_owner"],
    "variables": {"campaign_name": "Spring renewals"},
    "voice": "john"
  },
  "event_id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
  "type": "telephony.complete"
}
VäliTüüpKirjeldus
call_idintegerPüsib selle kõne kõigi sündmuste puhul samana
agent_idinteger | nullKõnet käsitlenud agent, kui see oli määratud
agent_namestring | nullKõnet käsitlenud agent, kui see oli määratud
directionstringinbound, outbound, web, test. Ajaloolised andmepaketid võivad sisaldada pärandväärtusi mic või widget
from_number, to_numberstringE.164. Veebikõnede ja testkõnede puhul on from_number sõnasõnaliselt "web"
origin_domainstringAinult veeb/test — vidinat majutanud lehe päritolu (mikrofoni seansside puhul tühi)
start_time, end_timetimestampISO 8601 UTC
duration_secondsinteger | nullTuletatud algus- ja lõppajast
statusstringcompleted või failed
end_reasonstringVaata allolevat tabelit
product, voicestringKõne ajal kehtinud agendi konfiguratsioon
variablesobjectSisendmuutujate hetktõmmis kõne algushetkel
unresolved_variablesarrayMuutujate nimed, millele kõne konfiguratsioon viitab, kuid mida kõne alguses ei edastatud
transfer_numberstring | nullMääratakse, kui kõne suunati edasi
recording_urlstring | nullAeguv allkirjastatud URL; laadi alla viivitamata. null, kui salvestise artefakt pole saadaval
billable_minutesnumberArveldatud minutid, ümardatuna lähima veerandminutini (15-sekundilised sammud, miinimum 0,25). Otse kõneposti läinud kõned esitavad siin siiski oma tegelikud mõõdetud minutid, kuid tasu on paketihinnaga piiratud ühe minutiga.
billing_total_centsintegerUSA sendid
transcriptsarrayKõnevoorupõhised transkriptsioonikirjed; võivad olla tühjad, kui transkriptsioon pole saadaval
extracted_dataobject | nullStruktureeritud ekstraktimise tulemus väljadega status, fields, evidence, verification, field_reasons ja schema_version. Igal mitte-null väljal on täpne struktuurselt kontrollitud tsitaat (kuni 1000 tähemärki) ning selle kõneleja roll ja kõnevooru indeks; pikemad mudeli tagastatud tsitaadid lükatakse kärpimise asemel tagasi. Tõendus on null, kui väli on null. verified tähendab, et iga kandidaat sai täpselt ühe kehtiva sõltumatu otsuse. unavailable hõlmab ka vigast või osalist kontrollija väljundit; kehtivaid osalisi otsuseid rakendatakse siiski, samal ajal kui kandidaadid, millel puudub üks kehtiv otsus, muudetakse nulliks. status on completed, failed, exhausted, skipped või skipped_recording_disabled; null, kui agendil polnud ekstraktimisvälju

Lõpetamise põhjused

VäärtusTähendus
user_hangupKaugosapool katkestas kõne esimesena
ai_hangupAI lõpetas kõne tahtlikult
ai_transferAI suunas kõne edasi; transfer_number on määratud
ai_warm_transferAI lõpetas sooja (osalejaga) edasisuunamise
voicemail_hangupTuvastati kõnepost ja kõne lõpetati vastavalt sinu voicemail_action seadistusele
max_durationKõne saavutas maksimaalse kestuse piirangu
supersededSeanss asendati uuemaga
unknownLõpetamise põhjust ei õnnestunud kindlaks teha

Transkripti vorming

Iga transcriptsi kirje on üks vestlusvoor. Rollid on user (helistaja kõne), model (agendi kõne ja tööriistakutsed), tool (tööriista tulemused) ja system (kõnesündmused, näiteks keele vahetused).

[
  {
    "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"] }
    }
  }
]
VäliTüüpKirjeldus
rolestringuser, model, tool või system
content_typestringtext/plain kõne jaoks; application/json tööriistakutsete, tööriistatulemuste ja süsteemisündmuste jaoks
contentstring | objectKõnetekst või eespool näidatud struktureeritud objekt. Tööriistakutsed: {"tool_call": name, "arguments": {…}}. Tööriistatulemused: {"tool_name": name, "response": {…}}
start_ms, end_msintegerNihe kõne algusest millisekundites. Olemas, kui heli ajastus on teada
ttfa_msintegerEsimese heli esitamiseni kuluv aeg modeli vooru puhul, kui mõõdetud
audio_url, audio_urlsstring / arrayAeguvad allkirjastatud URL-id vooru heli jaoks, kui see salvestati voorupõhiselt

Täielikult struktureeritud vooruajalooga (koos katkestusmarkerite, kinnitusküsimuste ja töötlemata positsioonidega) tutvumiseks kasuta GET /v1/calls/{call_id}/history.

Pärandandmekoormuse erinevused

Pärandne ühe URL-iga webhooki ümbrik on {"type": "telephony.complete" | "web.complete", "data": {…}}, millel puudub event_id, ning selle data erineb lõpp-punkti andmekoormusest:

Pärandne lõpetamisandmekoormus sisaldab ka agent_id ja agent_name.

  • Voorude massiiv asub väljal history, mitte transcripts (sama vooruskeem nagu eespool).
  • Väljade komplekt on töötlemata kõnelõpu aruanne ja võib sisaldada lisaks eespool toodud tabelile täiendavaid sisemisi välju — käsitle tundmatuid välju teabena.
  • Veebikõned (direction: "web") ei sisalda välju from_number / to_number ning lisavad välja origin_domain.
  • Builderi mikrofoni testkõned edastatakse pärandteel kui telephony.complete (lõpp-punkti süsteem vastendab need väärtusele web.complete).
  • Edasisuunamise koordineerimine: kui kõne lõpeb edasisuunamisega, kutsutakse pärandwebhook sünkroonselt ning see võib tagastada vastuse {"transfer_ready": false}, et anda märku, et üleandmise sihtmärk ei ole valmis. Iga muu vastus (või pärandwebhooki puudumine) lubab edasisuunamisel jätkuda. Selleks ei kasutata kunagi lõpp-punkti edastusi.

Näidiskäitleja

Python (FastAPI)
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}
Node.js (Express)
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 });
  },
);

Levinud kasutusjuhtumid

CRM-i integreerimine

Salvesta iga kõne transkriptsioon ja salvestise URL koos oma kliendiandmetega.

Analüütika

Edasta transkriptsioonid töötlusvoogu teemade modelleerimiseks, CSAT-signaalide eraldamiseks või edastamismäära jälgimiseks.

Kvaliteedi ülevaatus

Ava kõned inimülevaatuseks kvaliteedikontrolli tööriistas või töötle neid oma hindamismudeliga.

Teavitused

Käivita inimkolleegi teavitus edastamise või tõrke korral.


Seotud