Call Event Webhooks

Met de Call Event Webhook van Tring kun je telefoniegebeurtenissen realtime doorsturen naar een extern systeem. Denk bijvoorbeeld aan een CRM, dashboard, rapportagetool of maatwerkapplicatie.

Je ontvangt een webhook wanneer een gesprek start, wordt beantwoord, verandert, wordt doorgeschakeld of wordt beëindigd. Wanneer transcriptie en gespreksanalyse zijn ingeschakeld, kan na afloop van het gesprek daarnaast een afzonderlijk transcriptie-event worden verstuurd.

In dit artikel lees je hoe je de webhook configureert, welke events beschikbaar zijn en hoe je de ontvangen gegevens het beste verwerkt.

Webhook configureren

De webhook-URL wordt per tenant ingesteld.

Bijvoorbeeld:

https://partner.example/webhook

Webhooks worden via een POST-request verstuurd.

Content-Type

Standaard wordt de payload als JSON verstuurd:

Content-Type: application/json

Ondersteunde formaten zijn:

application/json
application/x-www-form-urlencoded

Authenticatie

Indien authenticatie is geconfigureerd, kan een Bearer Token worden meegestuurd:

Authorization: Bearer <token>

De naam van deze header is configureerbaar. Standaard wordt Authorization gebruikt.

Extra headers

Aanvullende headers kunnen worden toegevoegd aan iedere webhook-call.

Bijvoorbeeld:

X-Customer-ID: 12345
X-Environment: Production
X-Webhook-Secret: <secret>

URL-parameters

Ook kunnen optioneel parameters aan de webhook-URL worden toegevoegd:

https://partner.example/webhook?tenant=demoTenant&environment=prod

Beschikbare events

De webhook kent vier eventtypes:

EventtypeOmschrijving
call_startEen gesprek is gestart
call_updateDe status of situatie binnen een gesprek is gewijzigd
call_endHet gesprek is beëindigd
transcriptTranscriptie en eventuele analyse van een eerder gesprek zijn beschikbaar

Binnen call-events wordt daarnaast een status meegegeven.

StatusBetekenis
ringingHet toestel gaat over
answeredHet gesprek is aangenomen
hangupHet gesprek is beëindigd
transcriptDe transcriptie is beschikbaar

Voorbeeld: inkomend gesprek

Wanneer een inkomend gesprek binnenkomt, wordt eerst een call_start verstuurd.

{
  "tenantCode": "demoTenant",
  "event_type": "call_start",
  "call_id": "PJSIP1014demoTenant00006ef0",
  "direction": "inbound",
  "status": "ringing",
  "number": "31600000001",
  "user_extension": "1014",
  "from": "31600000001",
  "to": "1014",
  "from_name": "Voorbeeld Klant",
  "to_name": "Medewerker 1014",
  "call_capabilities": [],
  "uniqueid": "LPBX01-1783334374.1405029",
  "linkedid": "LPBX01-1783334374.1405029",
  "timestamp": "2026-07-02T12:09:49.394Z"
}

Zodra het gesprek wordt aangenomen, volgt een call_update:

{
  "tenantCode": "demoTenant",
  "event_type": "call_update",
  "call_id": "PJSIP1014demoTenant00006ef0",
  "direction": "inbound",
  "status": "answered",
  "number": "31600000001",
  "user_extension": "1014",
  "from": "31600000001",
  "to": "1014",
  "from_name": "Voorbeeld Klant",
  "to_name": "Medewerker 1014",
  "call_capabilities": [],
  "uniqueid": "LPBX01-1783334374.1405029",
  "linkedid": "LPBX01-1783334374.1405029",
  "timestamp": "2026-07-02T12:10:00.638Z"
}

Na het beëindigen van het gesprek wordt een call_end verstuurd:

{
  "tenantCode": "demoTenant",
  "event_type": "call_end",
  "call_id": "PJSIP1014demoTenant00006ef0",
  "direction": "inbound",
  "status": "hangup",
  "number": "31600000001",
  "user_extension": "1014",
  "from": "31600000001",
  "to": "1014",
  "from_name": "Voorbeeld Klant",
  "to_name": "Medewerker 1014",
  "call_capabilities": [],
  "uniqueid": "LPBX01-1783334374.1405029",
  "linkedid": "LPBX01-1783334374.1405029",
  "timestamp": "2026-07-02T12:10:20.221Z"
}

Een normale call-flow ziet er daarmee bijvoorbeeld als volgt uit:

ringing
   ↓
answered
   ↓
hangup

Velden in een call-event

De standaardpayload bevat de volgende velden:

VeldTypeOmschrijving
tenantCodestringIdentificatie van de tenant
event_typestringcall_start, call_update, call_end of transcript
call_idstringTechnische ID van de betreffende call-leg
previous_call_idstringAlleen aanwezig bij bepaalde transfers; verwijst naar de vorige call-leg
uniqueidstringAsterisk UniqueID van de call-leg
linkedidstringAsterisk LinkedID waarmee gerelateerde call-legs kunnen worden gegroepeerd
directionstringinbound of outbound
statusstringringing, answered, hangup of transcript
numberstringTelefoonnummer van de tegenpartij van de gebruiker
user_extensionstringExtensie van de gebruiker
fromstringBeller
tostringBestemming
from_namestringNaam behorend bij from, indien bekend
to_namestringNaam behorend bij to, indien bekend
timestampstringUTC-tijdstip in ISO 8601-formaat
call_capabilitiesarrayBeschikbare acties of capabilities; momenteel meestal leeg

Call-ID’s en call-legs

Een belangrijk aandachtspunt bij het verwerken van de webhook is de betekenis van call_id.

Een call_id vertegenwoordigt een technische call-leg en niet noodzakelijk het volledige gesprek zoals een eindgebruiker dat ervaart.

Voor een eenvoudig gesprek kan één call_id gedurende het volledige gesprek worden gebruikt. Bij complexere scenario’s, zoals een transfer, kunnen echter meerdere call-legs ontstaan.

Tijdens een transfer kan:

  • dezelfde call_id andere gesprekspartijen krijgen;
  • een nieuwe call_id ontstaan;
  • een previous_call_id worden meegestuurd.

Behandel call_id daarom niet als de enige unieke identificatie van een volledig gesprek.

Voor rapportages en correlatie adviseren we om ten minste call_id, previous_call_id, uniqueid en linkedid te bewaren.

Gesprekken doorschakelen

De webhook ondersteunt attended transfers.

Stel dat een externe beller eerst met extensie 1014 spreekt:

Externe beller → 1014

Medewerker 1014 start vervolgens een consultatie met 1004:

Externe beller → 1014 → 1004

Na het voltooien van de transfer blijft de externe beller verbonden met 1004:

Externe beller → 1004

Bij een succesvolle transfer kan bijvoorbeeld het volgende event worden verstuurd:

{
  "tenantCode": "demoTenant",
  "event_type": "call_update",
  "status": "answered",
  "call_id": "PJSIP1004demoTenant000019ec",
  "previous_call_id": "PJSIP1014demoTenant00006ef0",
  "direction": "inbound",
  "number": "31600000001",
  "user_extension": "1004",
  "from": "31600000001",
  "to": "1004",
  "from_name": "Voorbeeld Klant",
  "to_name": "Medewerker 1004",
  "call_capabilities": [],
  "uniqueid": "LPBX01-1783334401.1405101",
  "linkedid": "LPBX01-1783334374.1405029",
  "timestamp": "2026-07-02T12:10:20.221Z"
}

Wanneer previous_call_id aanwezig is in combinatie met:

event_type: call_update
status: answered

kan het event worden beschouwd als een afgeronde transfer.

Een bijbehorende call-flow kan er bijvoorbeeld zo uitzien:

12:09:49   31600000001 → 1014      ringing
12:10:00   31600000001 → 1014      answered
12:10:14   1014 → 1004             ringing
12:10:17   1014 ↔ 1004             consultatie
12:10:20   transfer uitgevoerd
12:10:20   31600000001 → 1004      actief gesprek
12:10:21   consultatiegesprek eindigt

Transcriptie en gespreksanalyse

Wanneer transcriptie is ingeschakeld, kan na afloop van een gesprek een apart transcript-event worden verstuurd.

Transcriptie-events zijn optioneel en worden alleen verstuurd voor tenants die gebruikmaken van webhook_type: custom.

Een transcriptie wordt niet direct bij call_end verstuurd. Eerst moeten onder andere de opname, AI-transcriptie en eventuele aanvullende analyses worden verwerkt.

Hierdoor kan het transcriptie-event ongeveer één tot meerdere minuten na call_end arriveren. De verwerkingstijd hangt onder andere af van:

  • de duur van het gesprek;
  • de verwerkingswachtrij;
  • eventuele aanvullende analyses;
  • eventuele vertalingen.

Niet ieder gesprek resulteert in een transcriptie. Een gesprek kan bijvoorbeeld niet zijn opgenomen, te kort zijn geweest, niet zijn beantwoord of van transcriptie zijn uitgesloten.

Voorbeeld van een transcriptie-event

{
  "tenantCode": "demoTenant",
  "event_type": "transcript",
  "call_id": "PJSIP1014demoTenant00006ef0",
  "direction": "inbound",
  "status": "transcript",
  "number": "31600000001",
  "user_extension": "1014",
  "from": "31600000001",
  "to": "1014",
  "from_name": "Voorbeeld Klant",
  "to_name": "Medewerker 1014",
  "call_capabilities": [],
  "uniqueid": "LPBX01-1783334374.1405029",
  "linkedid": "LPBX01-1783334374.1405029",
  "duration": 143,
  "detected_language": "nl",
  "detected_language_iso": "nl",
  "transcription": "Beller: Goedemiddag, ik heb een vraag over mijn abonnement.\nMedewerker: Natuurlijk, ik kijk graag met u mee.",
  "category": 2,
  "category_name": "Support",
  "subject": "Vraag over abonnement",
  "sentiment": 0,
  "summary": "De beller vraagt om hulp bij een abonnement. De medewerker geeft aan mee te kijken.",
  "bullet_points": [
    "De beller heeft een vraag over een abonnement.",
    "De medewerker biedt aan de gegevens te controleren.",
    "Er wordt een vervolgactie afgesproken."
  ],
  "local_date_time": "2026-07-06T12:39:34+02:00",
  "timestamp": "2026-07-06T12:42:11.184Z"
}

Extra velden bij transcripties

Bij event_type: transcript kunnen de volgende aanvullende velden aanwezig zijn:

VeldTypeOmschrijving
durationnumberGespreksduur in seconden
detected_languagestringGedetecteerde taal of taalcode, afhankelijk van de analyseconfiguratie
detected_language_isostringISO-code van de gedetecteerde taal, bijvoorbeeld nl, en of de
transcriptionstringVolledige transcriptietekst
categorynumber/stringCategorie-ID of categoriecode
category_namestringNaam van de categorie
subjectstringOnderwerp van het gesprek
sentimentnumberSentimentscore, meestal -1, 0 of 1
summarystringAI-samenvatting van het gesprek
bullet_pointsarrayBelangrijkste punten uit het gesprek
local_date_timestringLokale gesprekstijd inclusief timezone-offset

Gebruik voor het koppelen van transcripties aan eerdere call-events onder andere uniqueid, linkedid en de beschikbare call-ID’s.

HTTP-responses

Het ontvangende endpoint moet een succesvolle HTTP-statuscode retourneren wanneer de webhook correct is ontvangen.

Ondersteunde succesvolle responses zijn bijvoorbeeld:

HTTP/1.1 200 OK

of:

HTTP/1.1 204 No Content

Andere statuscodes worden als een mislukte aflevering beschouwd, bijvoorbeeld:

400 Bad Request
401 Unauthorized
403 Forbidden
500 Internal Server Error

Wat gebeurt er als een webhook niet kan worden afgeleverd?

Wanneer het ontvangende endpoint tijdelijk niet bereikbaar is, probeert het platform de webhook automatisch opnieuw af te leveren.

Het standaard retrybeleid is:

  1. De eerste poging wordt direct uitgevoerd.
  2. Een tweede poging volgt na ongeveer één seconde.
  3. Daarna wordt exponentiële backoff gebruikt, bijvoorbeeld ongeveer 2, 4, 8, 16 en 29 seconden.
  4. De totale retryperiode bedraagt maximaal ongeveer één minuut.

Retries worden uitgevoerd bij:

  • HTTP 5xx;
  • timeouts;
  • netwerkfouten.

Bij een HTTP 4xx-response wordt niet opnieuw geprobeerd. Een 4xx wijst doorgaans op een probleem met bijvoorbeeld authenticatie, autorisatie of payloadvalidatie.

Wanneer alle pogingen mislukken, wordt de aflevering als mislukt geregistreerd.

Realtime call-events worden niet langdurig bewaard om na een procesherstart opnieuw af te leveren. Transcriptie-events worden daarnaast via een queue verwerkt en kunnen daardoor ook later opnieuw worden verwerkt.

Aanbevolen manier van verwerken

Voor een betrouwbare integratie adviseren we om rekening te houden met de volgende punten:

  • Verwerk webhooks asynchroon. Accepteer het event en voer zwaardere verwerking vervolgens buiten het webhook-request uit.
  • Gebruik timestamp voor de gebeurtenistijd. Ga niet uitsluitend uit van de volgorde waarin requests bij jouw endpoint aankomen.
  • Maak de verwerking idempotent. Houd er rekening mee dat hetzelfde event meer dan één keer kan worden aangeboden.
  • Sla call-relaties op. Bewaar naast call_id ook previous_call_id, uniqueid en linkedid wanneer deze beschikbaar zijn.
  • Gebruik previous_call_id voor transferdetectie.
  • Behandel een call_id als call-leg. Ga er niet vanuit dat één call_id altijd gelijkstaat aan één volledig gesprek.
  • Ga er niet vanuit dat from en to binnen dezelfde call_id nooit kunnen wijzigen.

Ondersteunde scenario’s

De Call Event Webhook kan worden gebruikt voor:

  • inkomende gesprekken;
  • uitgaande gesprekken;
  • interne gesprekken;
  • attended transfers;
  • CRM-pop-ups;
  • call logging;
  • rapportages;
  • realtime dashboards;
  • synchronisatie met externe applicaties.

Met de webhook kun je externe systemen daarmee realtime laten reageren op telefoniegebeurtenissen binnen Tring.