Mit Webhooks ruft Veeting Ihr System auf, sobald in einem Meeting etwas geschieht. So müssen Sie die API nicht laufend abfragen. Tritt ein Event ein, sendet die Plattform einen HTTP-Aufruf an eine URL, die Sie konfiguriert haben. Im JSON-Body steht das betroffene Objekt.
Sie konfigurieren Webhooks an zwei Stellen. Beide lösen beim selben Event aus:
Konfigurieren Sie beide, ruft die Plattform Ihren Endpunkt beim selben Event zweimal auf, einmal pro Ebene.
Wenn Sie mit einem KI-Coding-Assistenten arbeiten, können Sie den folgenden Text in Ihren Assistenten kopieren und mit einem Satz ergänzen, der beschreibt, was Sie programmieren möchten.
Der Prompt verweist auf unsere Entwicklerdokumentation, die wir für Coding-Assistenten in einer separaten, token-optimierten KI-Version ausliefern.
Lies zuerst diese Seite, bevor Du Code schreibst:
https://www.veeting.com/de/developer-documentation/web-hooks
Sie dokumentiert die Webhooks von Veeting Rooms. Halte Dich an
diese fünf Regeln:
1. Veeting versucht die Zustellung genau einmal. Es gibt keine
Wiederholung. Bestätige schnell, lege die Arbeit in eine Queue
und gleiche bei Bedarf über die REST API ab.
2. Keine Payload ist in responseCode und data verpackt, auch
onMeetingSummaryCreated nicht.
3. Manche Events senden ein Array statt eines Objekts. Alle fünf
Reminder und onMeetingDeleted tun das. Prüfe das, bevor Du
Felder liest.
4. Die Authentifizierung ist ein einziger optionaler
X-API-KEY-Header. Wenn ich den Endpunkt schützen will, prüfe
diesen Header und weise alles andere ab.
5. Frag mich, ob der Webhook auf Instanzebene oder auf Kontoebene
konfiguriert ist. Beide können aktiv sein, was zwei Aufrufe pro
Event bedeutet.
Was ich bauen möchte:Wir versuchen die Zustellung genau einmal. Es gibt keine Wiederholung, kein Backoff und keine Dead-Letter-Queue. Ist Ihr Endpunkt nicht erreichbar oder antwortet er mit einem Fehlerstatus, loggen wir das Event auf unserer Seite. Auf Ihrer Seite ist es verloren. Richten Sie sich darauf ein: rasch bestätigen, die Arbeit intern in eine Queue legen und, wenn Sie sicher sein müssen, das Meeting mit GET /meeting/{id} erneut abrufen, statt darauf zu vertrauen, dass jedes Event angekommen ist.
Antworten Sie schnell. Für die Zustellung ist kein Timeout konfiguriert. Ein langsamer Endpunkt hält die Verbindung deshalb offen, statt schnell abzubrechen. Geben Sie ein 2xx zurück, sobald Sie die Payload angenommen haben, und erledigen Sie die Arbeit danach.
Der Body ist das Objekt selbst, kein Wrapper. Anders als bei der REST API steckt eine Webhook-Payload nicht in responseCode und data. Zwei Events weichen ab: onMeetingCancelled verschachtelt das Meeting zusammen mit day im Body, und onMeetingRecordingCreated kommt als Objekt an, in dem das Meeting steckt, statt als Meeting selbst. Beide sind unten beschrieben.
Prüfen Sie die Form der Payload, bevor Sie Felder daraus lesen. Manche Events senden ein einzelnes Objekt, andere ein Array. Welche das sind, steht unten.
Sie konfigurieren jeden Webhook einzeln, mit vier Einstellungen:
| Einstellung | Bedeutung |
|---|---|
| enabled | Ob dieser Webhook überhaupt auslöst |
| url | Der Endpunkt, den wir aufrufen |
| method | POST, PUT oder DELETE. Sonst gilt POST. Auf Kontoebene ausdrücklich setzen. |
| apiKey | Optional. Siehe unten. |
Setzen Sie apiKey, sendet die Plattform ihn bei jedem Aufruf als X-API-KEY-Header. So kann Ihr Endpunkt alle Aufrufe ohne diesen Header abweisen. Lassen Sie das Feld leer, sendet die Plattform keinen solchen Header.
Mehr Authentifizierung hat ein Webhook-Aufruf nicht. Einen Endpunkt ohne konfigurierten API-Key ruft jeder auf, der seine URL kennt.
content-type: application/json sendet die Plattform immer mit.
Es gibt 16 Events.
| Event | Löst aus, wenn | Payload |
|---|---|---|
onMeetingScheduled | Ein Meeting erstellt wird | Meeting |
onMeetingUpdated | Ein Meeting geändert wird | Meeting |
onMeetingClosed | Ein Meeting geschlossen wird, automatisch oder manuell | Meeting |
onMeetingDeleted | Meetings gelöscht werden | Array von Meeting |
onMeetingCancelled | Ein einzelner Termin einer Serie abgesagt wird | { meeting, day } |
onMeetingJoined | Jemand einem Meeting beitritt | MeetingParticipantsStatus |
onMeetingLeft | Jemand ein Meeting verlässt | MeetingParticipantsStatus |
onMeetingSummaryCreated | Eine Summary erstellt wird, üblicherweise rund fünf Minuten nach dem Schliessen des Meetings | MeetingSummary |
onMeetingRecordingCreated | Ein aufgezeichnetes Meeting zusammengefügt wurde | Aufzeichnung |
onChatMessageCreated | Eine Chat-Nachricht in einem Meeting gesendet wird | ChatMessage mit IDs |
onChatMessageModerated | Sich der Moderationsstatus einer Chat-Nachricht ändert | ChatMessage mit IDs |
onMeetingsReminder15MinutesBefore | 15 Minuten vor Meeting-Beginn | Array von Meeting |
onMeetingsReminder30MinutesBefore | 30 Minuten vor Meeting-Beginn | Array von Meeting |
onMeetingsReminder60MinutesBefore | 60 Minuten vor Meeting-Beginn | Array von Meeting |
onMeetingsReminder24HoursBefore | 24 Stunden vor Meeting-Beginn | Array von Meeting |
onMeetingsReminder48HoursBefore | 48 Stunden vor Meeting-Beginn | Array von Meeting |
Zwei Dinge zu den Remindern werden leicht übersehen:
Diese Payload senden onMeetingScheduled, onMeetingUpdated und onMeetingClosed. Es ist dasselbe Objekt, das die REST API bei POST /meeting zurückgibt, hier gekürzt:
{
"id": "5e945c36b863b82cefdddf54",
"meetingId": "9974-7653-8886-0485",
"topic": "My Meeting Topic",
"startTime": "2026-09-07T09:00:00.000Z",
"endTime": "2026-09-07T10:00:00.000Z",
"duration": 60,
"type": "standard",
"roomId": "5e9459c5b863b82cefdddf50",
"isRecurring": false,
"isRecorded": false,
"isDialin": false,
"invitedParticipants": [],
"agenda": "",
"whitelabelId": "5c737902b377b0f7fbf81fce",
"accountId": "5e9459c5b863b82cefdddf4f",
"addedByUserId": "5e9459c5b863b82cefdddf4e",
"addedByUserEmail": "test-user@example.com",
"addedByUserName": "Test User",
"timezone": "Europe/Zurich",
"isActive": true,
"isOpen": false,
"isClosed": false
}Die beiden IDs verhalten sich genau wie in der REST API: Verwenden Sie id, wenn Sie die API aufrufen, und meetingId, wenn Sie einen Link bauen oder das Meeting jemandem anzeigen.
Diese Payload senden onMeetingDeleted und alle fünf Reminder. Es ist dasselbe Objekt wie oben, in einem Array:
[
{ "id": "5e945c36b863b82cefdddf54", "meetingId": "9974-7653-8886-0485", "topic": "My Meeting Topic" }
]Bei onMeetingDeleted kann jedes Meeting zusätzlich ein Feld cancellationMessage mitführen. Darin steht der Text, den der Organisator beim Löschen angegeben hat.
Diese Payload sendet onMeetingCancelled, wenn jemand einen einzelnen Termin einer Serie absagt und nicht die ganze Serie. Das Meeting steckt verschachtelt im Body, und day bezeichnet den Termin:
{
"meeting": { "id": "5e945c36b863b82cefdddf54", "meetingId": "9974-7653-8886-0485", "isRecurring": true },
"day": "2026-09-14"
}Diese Payload senden onMeetingJoined und onMeetingLeft:
{
"meetingId": "5df78199c015b37195230596",
"meetingToken": "0000-0000-0000-0000",
"isNamedRoom": false,
"participant": {
"name": "Joe Doe",
"email": "joe@example.com",
"meetingParticipantId": "4edaf0d2-cb6c-42f1-a266-4ae7d971f2e6",
"isModerator": false
},
"totalNumberOfGuests": 3,
"totalNumberOfModerators": 1,
"whitelabelId": "5c737902b377b0f7fbf81fce",
"accountId": "5e9459c5b863b82cefdddf4f"
}Hinweis: Hier enthält
meetingIddie 24 Zeichen langeiddes Meetings, undmeetingTokendie Nummer mit den Bindestrichen. Das ist genau umgekehrt zur Benennung überall sonst. Lesen Sie hier also besonders genau.
Diese Payload sendet onMeetingSummaryCreated. Wie jede andere Payload ist der Body die Summary selbst, ohne Wrapper:
{
"id": "5f7d49eb62e8f9a43b23f986",
"meetingId": "5f7d49e662e8f9a43b23f983",
"meetingType": "boardroom",
"agenda": "",
"minutes": "",
"participants": [
{
"name": "Participant 1",
"durations": [
{ "action": "joined", "timestamp": 1602046445811 },
{ "action": "left", "timestamp": 1602046670808 }
],
"info": {
"browserName": "Chrome",
"browserVersion": "82.0.4062.0",
"osName": "macOS",
"osVersion": "10.15.6",
"platformType": "desktop",
"platformVendor": "Apple"
}
}
],
"documents": [],
"pdf": null,
"accountId": "5c73790ab377b0f7fbf81fde",
"isNamedRoom": false,
"isRecordingPrepared": false,
"sfuHostname": "ch-01-sfu-02.wlvmr.net",
"meetingQuestions": [],
"meetingConversationDuration": 25,
"meetingConversationStartToEndDuration": 25,
"meetingParticipantsStartToEndDuration": 35,
"meetingStartToEndDuration": 60
}Die vier Dauer-Felder messen Unterschiedliches. Alle Angaben in Sekunden:
| Feld | Was es misst |
|---|---|
| meetingConversationDuration | Wie lange mindestens zwei Personen gleichzeitig im Raum waren |
| meetingConversationStartToEndDuration | Vom ersten Moment, in dem zwei Personen zusammen im Raum waren, bis zum letzten |
| meetingParticipantsStartToEndDuration | Vom Beitritt der ersten Person bis zum Verlassen der letzten |
| meetingStartToEndDuration | Die geplante Dauer, einschliesslich Verlängerung |
Diese Payload sendet onMeetingRecordingCreated. Sie ist ein Wrapper: Meeting und Summary stecken darin, statt selbst den Body zu bilden.
{
"meeting": { "id": "5e945c36b863b82cefdddf54", "meetingId": "9974-7653-8886-0485", "topic": "My Meeting Topic" },
"summary": { "id": "5f48a701ee0c388a879bffa7" },
"mergedRecordingUrl": "https://<recording-host>/prepared/<meeting>/<token>.webm",
"recordingUrls": [
"video-file-1.webm",
"video-file-2.webm",
"video-file-3.webm"
],
"emailNotificationRecipients": ["organizer@example.com"]
}| Eigenschaft | Bedeutung |
|---|---|
| meeting | Das vollständige Meeting-Objekt, wie oben beschrieben |
| summary | Die Summary, zu der diese Aufzeichnung gehört |
| mergedRecordingUrl | Die einzelne, zusammengefügte Aufzeichnung |
| recordingUrls | Die einzelnen Teile, aus denen die Aufzeichnung zusammengefügt wurde, so wie der Aufzeichnungs-Host sie meldet |
| emailNotificationRecipients | Wen die Plattform gleich per E-Mail über diese Aufzeichnung informiert |
Hinweis: Lesen Sie die IDs des Meetings aus
meeting.idundmeeting.meetingId. Auf oberster Ebene dieser Payload gibt es kein FeldmeetingId.
Diese Payload senden onChatMessageCreated und onChatMessageModerated. Der Body ist ein Objekt mit vier Feldern: meetingId, whitelabelId, accountId und chatMessage, das die Chat-Nachricht enthält.
onMeetingSummaryCreated in responseCode und data verpackt ankommt. Es ist ein unverpacktes Objekt wie jede andere Payload.meetingId in den Join- und Leave-Payloads als Nummer mit Bindestrichen lesen. Dort ist es die 24 Zeichen lange id, und meetingToken ist die mit den Bindestrichen.apiKey bei einem Endpunkt leer lassen, der Daten verändert.Sprechen Sie mit unserem Team über Ihre Pläne.