Zum Hauptinhalt springen

Wie du Ereignisse per Webhook empfängst

Statt alle paar Minuten nachzufragen, ob ein Meeting fertig ist, lässt du es dir von Sally sagen. Ein Webhook schickt einen POST-Request an deine URL, sobald eine Zusammenfassung fertig ist. Das ist der Unterschied zwischen einer Anbindung, die sofort wirkt, und einer, die sich wie ein nächtlicher Lauf anfühlt.

Diese Anleitung registriert einen Webhook, baut einen kleinen Empfänger in Node und Python und zeigt, wie du Webhooks pausierst, änderst und löschst. Jedes Beispiel funktioniert so, wie es dasteht, sobald SALLY_TOKEN und DIRECTORY_ID gesetzt sind, siehe Schnellstart. Hilfreich ist, wenn du die Form einer Zusammenfassung aus Zusammenfassungen abrufen kennst.

Schnellnavigation

  1. Webhook registrieren
  2. Die Ereignisse
  3. Persönlich oder unternehmensweit
  4. Die Zustellung empfangen
  5. Auf deiner Seite
  6. Webhook pausieren, ändern oder löschen
  7. Komplettes Einrichtungsskript
  8. Endpunkte im Überblick

1. Webhook registrieren​

POST/v1.0/directories/{directoryId}/webhooks registriert einen Webhook. Der Body nimmt diese Felder:

FeldTypStandardBeschreibung
urlstringPflicht. Der Endpunkt, an den Sally den POST-Request schickt.
eventstringsummary.readyWann der Webhook feuert: summary.ready oder manual, siehe Die Ereignisse.
namestringEine Bezeichnung, an der du den Webhook in der Liste erkennst.
directoryWidebooleanfalsefalse feuert nur für deine eigenen Aufnahmen, true für die Aufnahmen aller Nutzer. Siehe Persönlich oder unternehmensweit.
curl -X POST "https://api.sally.io/v1.0/directories/$DIRECTORY_ID/webhooks" \
-H "Authorization: Bearer $SALLY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/hooks/sally",
"event": "summary.ready",
"name": "CRM-Sync"
}'

Die Antwort ist der neue Webhook:

200 OK
{
"webhookId": "af39409b-ca90-443d-a5e8-47dfd97c518f",
"name": "CRM-Sync",
"event": "summary.ready",
"url": "https://example.com/hooks/sally",
"isActive": true,
"directoryWide": false,
"createdOn": "2026-09-24T09:30:00Z"
}
FeldTypBedeutung
webhookIdstringId des Webhooks. Heb sie auf, um den Webhook später zu pausieren, zu ändern oder zu löschen.
namestringAnzeigename des Webhooks.
eventstringWann der Webhook feuert.
urlstringZiel-URL, an die Sally das Ereignis schickt.
isActivebooleanOb der Webhook gerade feuert.
directoryWidebooleantrue für alle Nutzer des Unternehmenskontos, false nur für deine eigenen Aufnahmen.
createdOnstringZeitpunkt der Erstellung (ISO 8601).

2. Die Ereignisse​

  • summary.ready feuert nach jeder Zusammenfassung. Das ist der Standard und meist genau das, was du willst.
  • manual feuert nie von selbst. Eine Person startet es aus einem Meeting oder einer Aufnahme heraus. Das lohnt sich, wenn jemand entscheiden soll, was verschickt wird.

Webhooks aus der Zeit vor dem heutigen Modell melden möglicherweise noch die älteren Ereignisse recording.summarized oder meeting.summarized. Sie bleiben lesbar, lassen sich aber nicht mehr neu setzen.

3. Persönlich oder unternehmensweit​

Standardmäßig ist ein Webhook persönlich und feuert nur für deine eigenen Aufnahmen. Mit "directoryWide": true feuert er für die Aufnahmen aller Nutzer des Unternehmenskontos. Unternehmensweite Webhooks dürfen nur Admins und Owner anlegen.

Dieselbe Aufteilung gilt, wenn du Webhooks liest und verwaltest:

RolleGET/v1.0/directories/{directoryId}/webhooks zeigtDarf ändern, pausieren und löschen
Admin oder OwnerAlle Webhooks des Unternehmenskontos, persönliche und unternehmensweiteJeden Webhook des Unternehmenskontos
Normaler NutzerNur die eigenen persönlichen WebhooksNur die eigenen persönlichen Webhooks

4. Die Zustellung empfangen​

Wenn das Ereignis feuert, schickt Sally einen POST-Request mit JSON-Body an deine URL. Die Nutzlast enthält die Zusammenfassung mit ihren Abschnittseinträgen, in derselben Form wie in Zusammenfassungen abrufen. Ein Parser reicht also für beide Wege. Diese Felder nutzen die Beispiel-Empfänger:

FeldTypBedeutung
recordingSummaryIdstringId der Zusammenfassung. Nimm sie als Schlüssel für die idempotente Verarbeitung.
recordingIdstringDie Aufnahme, zu der die Zusammenfassung gehört.
appointmentIdstring oder nullDer Termin, falls es einen gibt.
summarystring oder nullText der Zusammenfassung.
sectionItemsarrayDie strukturierten Ergebnisse je Abschnitt des Meeting-Templates. Einträge mit sectionType tasks tragen subject, responsibleUserName und dueDate.

Ein minimaler Empfänger antwortet sofort und erledigt die Arbeit danach. Der cURL-Reiter zeigt, wie du deinen Endpunkt lokal mit einer echten Zusammenfassung testest, bevor Sally die erste schickt.

# Eine echte Zusammenfassung holen und an deinen lokalen Endpunkt schicken, wie Sally es tun würde.
curl -s "https://api.sally.io/v1.0/directories/$DIRECTORY_ID/summaries/$RECORDING_SUMMARY_ID" \
-H "Authorization: Bearer $SALLY_TOKEN" > summary.json

curl -i -X POST "http://localhost:3000/hooks/sally" \
-H "Content-Type: application/json" \
--data @summary.json
Empfehlung

Schreib den rohen Body der ersten echten Zustellung einmal ins Log und vergleich ihn mit deinem Parser. So überrascht dich ein Feld, auf das du dich verlässt, nie erst im Betrieb.

5. Auf deiner Seite​

  • Antworte schnell mit 2xx und erledige die eigentliche Arbeit danach, damit eine langsame Verarbeitung die Zustellung nicht blockiert.
  • Bau deinen Empfänger idempotent, mit der Id der Zusammenfassung (recordingSummaryId) als Schlüssel, damit eine wiederholte Zustellung keinen Schaden anrichtet.
  • Die Nutzlast enthält die Zusammenfassung mit ihren Abschnittseinträgen, in derselben Form wie in Zusammenfassungen abrufen. Ein Parser reicht also für beide Wege.

6. Webhook pausieren, ändern oder löschen​

POST/v1.0/directories/{directoryId}/webhooks/{webhookId}/deactivate pausiert einen Webhook, ohne ihn zu löschen. Er bleibt in der Liste, feuert aber nicht, bis du ihn mit POST/v1.0/directories/{directoryId}/webhooks/{webhookId}/activate wieder aktivierst. Beide Aufrufe brauchen keinen Request-Body und liefern den geänderten Webhook zurück.

# Pausieren
curl -X POST "https://api.sally.io/v1.0/directories/$DIRECTORY_ID/webhooks/$WEBHOOK_ID/deactivate" \
-H "Authorization: Bearer $SALLY_TOKEN"

# Fortsetzen
curl -X POST "https://api.sally.io/v1.0/directories/$DIRECTORY_ID/webhooks/$WEBHOOK_ID/activate" \
-H "Authorization: Bearer $SALLY_TOKEN"

Nach einem Deaktivieren steht isActive auf false:

200 OK
{
"webhookId": "af39409b-ca90-443d-a5e8-47dfd97c518f",
"name": "CRM-Sync",
"event": "summary.ready",
"url": "https://example.com/hooks/sally",
"isActive": false,
"directoryWide": false,
"createdOn": "2026-09-24T09:30:00Z"
}
Empfehlung

Während du deinen Endpunkt umbaust, deaktiviere den Webhook, statt ihn zu löschen, und aktiviere ihn danach wieder.

Um einen Webhook auf eine neue URL umzustellen, umzubenennen oder sein Ereignis zu wechseln, nimm PATCH/v1.0/directories/{directoryId}/webhooks/{webhookId}. Es ändern sich nur die Felder, die du mitschickst (url, event, name). Aktivieren und Deaktivieren geht dort nicht, sondern über die beiden Aufrufe oben. DELETE/v1.0/directories/{directoryId}/webhooks/{webhookId} entfernt einen Webhook und antwortet mit 204.

7. Komplettes Einrichtungsskript​

Dieses Skript sorgt dafür, dass genau ein Webhook auf deine URL zeigt: Es sucht einen vorhandenen Webhook mit dieser URL, aktiviert ihn, falls er pausiert ist, und registriert nur dann einen neuen, wenn es keinen gibt. Du kannst es bei jedem Deployment laufen lassen.

#!/usr/bin/env bash
# Braucht SALLY_TOKEN, DIRECTORY_ID und HOOK_URL sowie jq.
set -euo pipefail
BASE="https://api.sally.io/v1.0/directories/$DIRECTORY_ID"

existing=$(curl -s "$BASE/webhooks" -H "Authorization: Bearer $SALLY_TOKEN" \
| jq -c --arg url "$HOOK_URL" 'map(select(.url == $url)) | first // empty')

if [ -z "$existing" ]; then
curl -s -X POST "$BASE/webhooks" \
-H "Authorization: Bearer $SALLY_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"url\": \"$HOOK_URL\", \"event\": \"summary.ready\", \"name\": \"CRM-Sync\"}" | jq .
elif [ "$(echo "$existing" | jq '.isActive')" = "false" ]; then
id=$(echo "$existing" | jq -r '.webhookId')
curl -s -X POST "$BASE/webhooks/$id/activate" -H "Authorization: Bearer $SALLY_TOKEN" | jq .
else
echo "$existing" | jq .
fi

8. Endpunkte im Überblick​

Jeder Eintrag führt zur Referenz, wo du die Anfrage mit deinem eigenen Token senden kannst.

Wie du Webhooks ohne Code direkt in der Sally-App einrichtest, zeigt die Anleitung zur Webhook-Integration.