Ontwikkelaars
Webhooks
Ontvang ondertekende HTTPS-meldingen wanneer gesprekken eindigen, berichten worden aangenomen, afspraken, bestellingen en reserveringen wijzigen, of een campagne eindigt, en controleer of elke melding echt van Ringhum kwam.
6 min leestijd Bijgewerkt op 24 september 2026
Op deze pagina
Een webhook stuurt op het moment dat er iets in je werkruimte gebeurt een HTTPS-verzoek naar je server. Gebruik webhooks in plaats van de API te pollen: wanneer een gesprek eindigt, ontvang je meteen de samenvatting, uitkomst, verzamelde gegevens en het transcript. Elke aflevering wordt ondertekend met een geheim dat alleen jij en Ringhum kennen, zodat je server alles kan weigeren dat niet van Ringhum kwam.
Een endpoint toevoegen
Alleen de Eigenaar en Beheerders van de werkruimte kunnen endpoints toevoegen, testen en verwijderen.
- Open Ontwikkelaars in de zijbalk.
- Klik in het kaartje Webhooks op Endpoint toevoegen.
- Voer de Endpoint-URL in. Deze moet beginnen met
https://. - Vink onder Events de events aan die je wilt.
call.endedstaat al aangevinkt. - Klik op Endpoint toevoegen.
- Kopieer het ondertekeningsgeheim uit het groene vak (het begint met
whsec_) en bewaar het op je server. Klik op Klaar.
Belangrijk: Het ondertekeningsgeheim wordt maar één keer getoond. Verwijder het endpoint en voeg het opnieuw toe om een nieuw geheim te krijgen als je het kwijtraakt.
Je kunt zoveel endpoints toevoegen als je nodig hebt. Webhooks dekken elke assistent in de werkruimte. Je kunt endpoints ook via de API beheren, met POST /webhooks en een sleutel met de scope write.
Events
| Event | Wanneer het wordt verstuurd |
|---|---|
call.started |
Een gesprek werd beantwoord door een assistent |
call.ended |
Een gesprek eindigde en werd samengevat (bevat transcript en samenvatting) |
call.transferred |
Een gesprek werd doorverbonden naar een mens |
message.taken |
De assistent nam een bericht aan |
appointment.booked |
De assistent boekte een afspraak |
appointment.rescheduled |
Een afspraak werd verzet naar een nieuwe tijd |
appointment.cancelled |
Een afspraak werd geannuleerd |
order.created |
Er werd een bestelling geplaatst (door een assistent, met de hand of via de API) |
order.updated |
Een bestelling kreeg een nieuwe status |
order.cancelled |
Een bestelling werd geannuleerd |
reservation.created |
Er werd een kamer gereserveerd (door een assistent, met de hand of via de API) |
reservation.updated |
Een reservering kreeg een nieuwe status (bevestigd, ingecheckt, uitgecheckt, niet verschenen) |
reservation.cancelled |
Een reservering werd geannuleerd |
campaign.completed |
Een uitgaande campagne beëindigde het bellen van zijn lijst |
test.ping |
Je klikte op Test versturen |
Hoe een aflevering eruitziet
Elke aflevering is een POST met een JSON-body en deze headers:
POST https://example.com/hooks/ringhum
Content-Type: application/json
User-Agent: Ringhum-Webhooks/1.0
X-Ringhum-Event: call.ended
X-Ringhum-Timestamp: 1789250000
X-Ringhum-Signature: v1=5f1a…
{
"id": "evt_8f2k…",
"type": "call.ended",
"created_at": "2026-09-24T14:03:11+00:00",
"data": {
"call_id": 4812,
"direction": "inbound",
"from": "+14155550132",
"to": "+14155550100",
"assistant_id": 3,
"status": "completed",
"outcome": "message_taken",
"sentiment": "neutral",
"duration_seconds": 94,
"summary": "Caller asked for a quote for a kitchen repair…",
"extracted": { "name": "Dana Lee", "reason": "Quote" },
"transcript": [
{ "role": "assistant", "content": "Hello, you've reached…" },
{ "role": "user", "content": "Hi, I'd like a quote…" }
]
}
}
Het object data hangt af van het event:
call.endedenmessage.taken: de bovenstaande gespreksvelden.call.startedencall.transferred:call_id,direction,from,to,assistant_id,statusenstarted_at.appointment.*:appointment_id,title,status,starts_at,ends_at,timezone,customer(naam, telefoon, e-mail),contact_id,service,staff,call_idennotes.order.*:order_id,number,status,fulfillment,customer,address,itemsmet opties en prijzen,currency,subtotal,fee,total,source,call_iden, bij annuleringen,cancel_reason.reservation.*:reservation_id,number,status,room,check_in,check_out,nights,adults,children,guest,currency,nightly,totalensource.campaign.completed:campaign_id,nameen de voortgangscijfers van de campagne.
Let op: Wanneer de assistent tijdens een gesprek een afspraak boekt, kun je
appointment.bookedtwee keer ontvangen. De ene wordt verstuurd zodra de boeking wordt gemaakt, met de afspraakvelden. De andere wordt verstuurd nadat het gesprek is samengevat, met de gespreksvelden. Controleer ofdataeenappointment_idofcall_idheeft, en gebruik het veldidom te voorkomen dat je een aflevering twee keer verwerkt.
De handtekening controleren
De handtekening is een HMAC-SHA256 van de timestamp, een punt, en de ruwe requestbody, versleuteld met het ondertekeningsgeheim van je endpoint. Deze wordt verstuurd als v1= gevolgd door de hexadecimale digest.
- Lees de ruwe body precies zoals ontvangen, vóór enige JSON-parsing.
- Bouw de string
{X-Ringhum-Timestamp}.{ruwe body}. - Bereken de HMAC-SHA256 met je geheim en zet er
v1=voor. - Vergelijk deze met
X-Ringhum-Signaturemet een constante-tijd vergelijking. - Wijs het verzoek af als de timestamp ouder is dan vijf minuten, om herhaalde verzoeken te blokkeren.
Node.js:
const crypto = require('crypto');
function isValid(req, rawBody, secret) {
const ts = req.header('X-Ringhum-Timestamp');
const sig = req.header('X-Ringhum-Signature') || '';
const expected = 'v1=' + crypto.createHmac('sha256', secret).update(`${ts}.${rawBody}`).digest('hex');
const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300;
return fresh && sig.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}
PHP:
$ts = $_SERVER['HTTP_X_RINGHUM_TIMESTAMP'] ?? '';
$sig = $_SERVER['HTTP_X_RINGHUM_SIGNATURE'] ?? '';
$expected = 'v1=' . hash_hmac('sha256', $ts . '.' . file_get_contents('php://input'), $secret);
if (! hash_equals($expected, $sig) || abs(time() - (int) $ts) > 300) {
http_response_code(400);
exit;
}
Responses, timeouts en herhaalpogingen
- Antwoord met een
2xx-status om de aflevering te bevestigen. Doe traag werk pas nadat je hebt geantwoord. - Ringhum wacht maximaal 10 seconden op je antwoord.
- Antwoordt je endpoint niet met een
2xx, dan wordt de aflevering in totaal tot 3 keer geprobeerd: meteen, opnieuw na ongeveer 10 seconden, en een laatste keer ongeveer 60 seconden later. Daarna wordt deze afgebroken. - Afleveringen kunnen in een andere volgorde binnenkomen. Gebruik
created_aten de id's indataom ze in volgorde te zetten.
De tabel Webhooks toont van elk endpoint de laatste HTTP-status en wanneer deze is verstuurd. Een mislukt endpoint blijft actief; Ringhum zet het niet voor je uit.
Testen, pauzeren en verwijderen
- Test versturen stuurt meteen een
test.ping-event, en een bericht toont de HTTP-status die je endpoint teruggaf. - De schakelaar Actief pauzeert een endpoint. Events die gebeuren terwijl het uitstaat, worden niet later alsnog verstuurd.
- Verwijderen verwijdert het endpoint en zijn geheim.
Veelgestelde vragen
Wat is het verschil met de Zapier-, Make- en n8n-apps onder Integraties? Die koppelingen gebruiken de pagina Integraties en de zes eventtypes ervan. Hun body is {"event", "workspace", "sent_at", "data"}, en wanneer je een geheim instelt, is de handtekeningheader X-Ringhum-Signature: sha256=…, een HMAC-SHA256 van alleen de body. Ontwikkelaarswebhooks, hier beschreven, dekken meer events en gebruiken de v1=-handtekening met een timestamp. Zie Kiezen wat wordt verstuurd.
Mijn endpoint geeft 2xx terug maar mijn code ziet niets. Controleer of het event is aangevinkt voor dat endpoint, of het endpoint actief is, en of je firewall verzoeken vanaf het internet toestaat.
Waarom mislukt de handtekeningcontrole? Meestal omdat de body werd geparseerd en opnieuw gecodeerd vóór het hashen. Hash de ruwe bytes precies zoals ontvangen.
Gerelateerde artikelen
API-sleutels en scopes
Maak en trek API-sleutels in op de pagina Ontwikkelaars, kies lees- of schrijftoegang, en leer de basis van de Ringhum REST API - basis-URL, authenticatie, paginering, fouten en snelheidslimieten.
Koppel Ringhum aan Claude en andere AI-tools (MCP)
Voeg Ringhum toe als connector in Claude, ChatGPT, Cursor, VS Code en andere AI-apps die het Model Context Protocol ondersteunen, kies alleen-lezen of lezen-en-wijzigen toegang, en ontkoppel een app.
Kiezen wat wordt verstuurd
Kies welke gesprekken, inboxitems, afspraken en bestellingen elke gekoppelde app ontvangt, en beperk gespreksupdates tot de gesprekken die actie van iemand vereisen.
Een app koppelen
Hoe je Slack, je CRM, helpdesk, taaktool, spreadsheet, winkel of agenda aan Ringhum koppelt, welk type koppeling elke app gebruikt, en hoe je controleert dat het werkt.
Kom je er niet uit?
Mail naar [email protected] of stuur ons een bericht. De abonnementen Team en Scale krijgen support met voorrang.