Ringhum.

Udviklere

Webhooks

Modtag signerede HTTPS-notifikationer, når opkald slutter, beskeder tages imod, aftaler, ordrer og reservationer ændres, eller en kampagne afsluttes, og bekræft, at hver enkelt virkelig kom fra Ringhum.

5 min. læsning Opdateret 24 september 2026

På denne side

En webhook sender en HTTPS-anmodning til din server i det øjeblik, noget sker i dit workspace. Brug webhooks i stedet for at polle API'et: når et opkald slutter, modtager du resuméet, resultatet, indsamlede detaljer og transskriptionen med det samme. Hver levering signeres med en hemmelighed, som kun du og Ringhum kender, så din server kan afvise alt, der ikke kom fra Ringhum.

Tilføj et endpoint

Kun workspacets Ejer og Admins kan tilføje, teste og fjerne endpoints.

  1. Åbn Udviklere i sidebjælken.
  2. I kortet Webhooks skal du klikke på Tilføj endpoint.
  3. Indtast Endpoint-URL. Den skal starte med https://.
  4. Under Events skal du afkrydse de events, du ønsker. call.ended er afkrydset for dig.
  5. Klik på Tilføj endpoint.
  6. Kopiér signeringshemmeligheden fra den grønne boks (den starter med whsec_), og gem den på din server. Klik på Færdig.

Vigtigt: Signeringshemmeligheden vises kun én gang. Hvis du mister den, skal du fjerne endpointet og tilføje det igen for at få en ny hemmelighed.

Du kan tilføje lige så mange endpoints, du har brug for. Webhooks dækker alle assistenter i workspacet. Du kan også administrere endpoints via API'et, med POST /webhooks og en nøgle, der har scopet write.

Events

Event Hvornår det sendes
call.started Et opkald blev besvaret af en assistent
call.ended Et opkald sluttede og blev opsummeret (inkluderer transskription og resumé)
call.transferred Et opkald blev overført til et menneske
message.taken Assistenten tog imod en besked
appointment.booked Assistenten bookede en aftale
appointment.rescheduled En aftale blev flyttet til et nyt tidspunkt
appointment.cancelled En aftale blev annulleret
order.created En ordre blev afgivet (af en assistent, manuelt eller via API'et)
order.updated En ordre skiftede til en ny status
order.cancelled En ordre blev annulleret
reservation.created Et værelse blev reserveret (af en assistent, manuelt eller via API'et)
reservation.updated En reservation skiftede til en ny status (bekræftet, tjekket ind, tjekket ud, udeblevet)
reservation.cancelled En reservation blev annulleret
campaign.completed En udgående kampagne blev færdig med at ringe til sin liste
test.ping Du klikkede på Send test

Sådan ser en levering ud

Hver levering er en POST med en JSON-body og disse 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…" }
    ]
  }
}

Objektet data afhænger af eventet:

  • call.ended og message.taken: opkaldsfelterne ovenfor.
  • call.started og call.transferred: call_id, direction, from, to, assistant_id, status og started_at.
  • appointment.*: appointment_id, title, status, starts_at, ends_at, timezone, customer (navn, telefon, e-mail), contact_id, service, staff, call_id og notes.
  • order.*: order_id, number, status, fulfillment, customer, address, items med valgmuligheder og priser, currency, subtotal, fee, total, source, call_id og, for annulleringer, cancel_reason.
  • reservation.*: reservation_id, number, status, room, check_in, check_out, nights, adults, children, guest, currency, nightly, total og source.
  • campaign.completed: campaign_id, name og kampagnens fremskridtstal.

Bemærk: Når assistenten booker en aftale under et opkald, kan du modtage appointment.booked to gange. Den ene sendes, når bookingen foretages, med aftalefelterne. Den anden sendes, efter opkaldet er opsummeret, med opkaldsfelterne. Tjek, om data har appointment_id eller call_id, og brug feltet id for at undgå at behandle en levering to gange.

Bekræft signaturen

Signaturen er en HMAC-SHA256 af tidsstemplet, et punktum, og den rå anmodningsbody, nøglet med dit endpoints signeringshemmelighed. Den sendes som v1= efterfulgt af hex-digestet.

  1. Læs den rå body præcis, som den modtages, før nogen JSON-parsing.
  2. Byg strengen {X-Ringhum-Timestamp}.{rå body}.
  3. Beregn HMAC-SHA256 med din hemmelighed, og sæt v1= foran.
  4. Sammenlign den med X-Ringhum-Signature ved brug af en konstant-tids sammenligning.
  5. Afvis anmodningen, hvis tidsstemplet er mere end fem minutter gammelt, for at blokere genafspillede anmodninger.

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;
}

Svar, timeouts og gentagne forsøg

  • Svar med en hvilken som helst 2xx-status for at bekræfte leveringen. Udfør langsomt arbejde, efter du har svaret.
  • Ringhum venter op til 10 sekunder på dit svar.
  • Hvis dit endpoint ikke svarer med 2xx, forsøges leveringen op til 3 gange i alt: med det samme, igen efter cirka 10 sekunder, og en sidste gang cirka 60 sekunder senere. Derefter droppes den.
  • Leveringer kan ankomme i vilkårlig rækkefølge. Brug created_at og id'erne i data til at sætte dem i rækkefølge.

Tabellen Webhooks viser hvert endpoints seneste HTTP-status og hvornår det blev sendt. Et fejlende endpoint forbliver aktivt; Ringhum slår det ikke fra for dig.

Test, sæt på pause, og fjern

  • Send test sender et test.ping-event med det samme, og en besked viser den HTTP-status, dit endpoint returnerede.
  • Kontakten Aktiv sætter et endpoint på pause. Events, der sker, mens det er slået fra, sendes ikke senere.
  • Fjern sletter endpointet og dets hemmelighed.

Ofte stillede spørgsmål

Hvad er forskellen fra Zapier-, Make- og n8n-appsene under Integrationer? De forbindelser bruger siden Integrationer og dens seks eventtyper. Deres body er {"event", "workspace", "sent_at", "data"}, og når du indstiller en hemmelighed, er signaturheaderen X-Ringhum-Signature: sha256=…, en HMAC-SHA256 af body'en alene. Udviklerwebhooks, beskrevet her, dækker flere events og bruger v1=-signaturen med et tidsstempel. Se Vælg, hvad der sendes.

Mit endpoint returnerer 2xx, men min kode ser intet. Tjek, at eventet er afkrydset for det endpoint, at endpointet er aktivt, og at din firewall tillader anmodninger fra internettet.

Hvorfor fejler signaturtjekket? Oftest blev body'en parset og genkodet før hashing. Hash de rå bytes præcis, som de blev modtaget.

Sidder du stadig fast?

Skriv til [email protected] eller send os en besked. Team- og Scale-planer får prioriteret support.

Kontakt support