Chapter 17 GET POST

Webhooks – Real-Time Events

BigBlueButton Webhooks let your application receive real-time HTTP POST notifications whenever meeting events occur. Instead of repeatedly polling getMeetings or getMeetingInfo, you register a callback URL and BigBlueButton pushes events to you automatically. This chapter covers the three webhook API endpoints, the callback format, event types, retry behaviour, and server configuration.

Webhooks require the bbb-webhooks package to be installed on the server. Several details described in this chapter are not covered by the official BigBlueButton documentation and have been determined through source-code analysis. undocumented

Prerequisites

The bbb-webhooks package must be installed on the BigBlueButton server before webhook endpoints become available:

sudo apt-get install bbb-webhooks

If the webhook application is not running when a meeting is created, no internal meeting mapping is established. As a result, no callbacks will be triggered for that meeting.

hooks/create — Register a Webhook

GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/create?<parameters>&checksum=replace-with-checksum

The official documentation does not specify an HTTP method. The Express router registers GET routes only — POST requests are not accepted. undocumented

Parameter Type Required Default Description
callbackURL String Yes The URL that will receive POST callbacks. Duplicate detection is based solely on this URL — the same URL cannot be registered twice, even with a different meetingID or eventID.
meetingID String No Restricts the hook to a specific meeting (external meeting ID). If omitted, the hook becomes a global hook that fires for all meetings.
eventID String No Comma-separated list of event types to listen for (e.g. user-joined,meeting-ended). If omitted, all events are delivered. The filter is case-insensitive. Available since BBB 2.5.
getRaw Boolean No false When set to true, callbacks contain the raw Redis message instead of the processed event data.

Successful Response

<response>
  <returncode>SUCCESS</returncode>
    <hookID>replace-with-hook-id</hookID>
  <permanentHook>false</permanentHook>
  <rawData>false</rawData>
</response>

Duplicate Registration

If the same callbackURL is registered again, the response still returns SUCCESS but includes a duplicateWarning. The existing hook is kept unchanged — meetingID, eventID, and getRaw are not updated.

<response>
  <returncode>SUCCESS</returncode>
    <hookID>replace-with-hook-id</hookID>
  <messageKey>duplicateWarning</messageKey>
  <message>There is already a hook for this callback URL.</message>
</response>

Error Responses

messageKey Description
checksumError The checksum is invalid or missing.
missingParamCallbackURL The callbackURL parameter was not provided. undocumented
createHookError An internal error occurred (e.g. Redis unreachable). Check the server logs.

hooks/list — List Registered Webhooks

GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/list?<parameters>&checksum=replace-with-checksum
Parameter Type Required Description
meetingID String No Filters by meeting ID. The result includes both hooks for the specified meeting and all global hooks. If omitted, all registered hooks are returned.

Successful Response

<response>
  <returncode>SUCCESS</returncode>
  <hooks>
    <hook>
    <hookID>replace-with-hook-id</hookID>
            <callbackURL><![CDATA[https://api-guide.bbbserver.com/callbacks/webhook]]></callbackURL>
    <meetingID><![CDATA[replace-with-meeting-id]]></meetingID>
      <eventID>user-joined,meeting-ended</eventID>
      <permanentHook>false</permanentHook>
      <rawData>false</rawData>
    </hook>
  </hooks>
</response>

The <meetingID> element only appears for meeting-specific hooks. Global hooks have no <meetingID> element. Likewise, <eventID> only appears when an event filter was set during creation.

Error Responses

messageKey Description
checksumError The checksum is invalid or missing.
listHookError An internal error occurred while listing hooks. Check the server logs. undocumented

hooks/destroy — Remove a Webhook

GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/destroy?<parameters>&checksum=replace-with-checksum
Parameter Type Required Description
hookID String Yes The ID of the hook to remove (obtained from hooks/create or hooks/list).

Successful Response

<response>
  <returncode>SUCCESS</returncode>
  <removed>true</removed>
</response>

Permanent hooks (configured server-side via permanentURLs) cannot be deleted through the API. Attempting to do so returns a destroyMissingHook error as if the hook does not exist.

Error Responses

messageKey Description
checksumError The checksum is invalid or missing.
missingParamHookID The hookID parameter was not provided.
destroyMissingHook The hook ID does not exist or belongs to a permanent hook.
destroyHookError An internal error occurred while removing the hook. Check the server logs.

hooks/ping — Health Check

GET https://api-guide.bbbserver.com/bigbluebutton/api/hooks/ping

This diagnostic endpoint requires no checksum. If the webhook application is reachable it returns the plain-text string bbb-webhooks API up! (not XML, content type text/plain). undocumented

Callback Format

Webhook callbacks are sent as HTTP POST requests with content type application/x-www-form-urlencoded. The request body contains three fields:

Field Description
domain The server domain (from the webhook configuration). undocumented
event A JSON array containing the event data. Always an array, even for a single event.
timestamp A Unix timestamp in milliseconds at the time of dispatch.

Processed Callback Body (getRaw=false)

domain=myserver.com&event=[{"data":{"type":"event","id":"user-joined","attributes":{...},"event":{"ts":1532718316938}}}]&timestamp=1532718316953

Raw Callback Body (getRaw=true)

domain=myserver.com&event=[{"envelope":{"name":"UserJoinedMeetingEvtMsg","routing":{"sender":"bbb-apps-akka"}},"core":{"header":{...},"body":{...}}}]&timestamp=1532718316953

When the server is configured with multiEvent greater than 1, multiple events can be bundled in the event array within a single callback.

Callback Checksum Validation

In the default mode, each callback URL receives a checksum query parameter that your application should verify:

https://api-guide.bbbserver.com/callbacks/webhook?checksum=replace-with-checksum

The validation formula is:

sha<algo>(<callback-URL-without-checksum> + <URL-encoded-body> + <shared-secret>)

Take the registered callback URL without the checksum parameter.

Append the full URL-encoded request body (domain=...&event=[...]&timestamp=...).

Append the BBB shared secret.

Hash the resulting string with the configured algorithm (default: sha1, configurable via hookChecksumAlgorithm).

Auth 2.0 / Bearer Mode

Alternatively, the server can be configured with auth2_0: true. In this mode, no checksum parameter is appended to the callback URL. Instead, the shared secret is sent as a Bearer token in the Authorization header: undocumented

Authorization: Bearer <shared-secret>

Callback Behaviour

  • Accepted HTTP status codes: HTTP 2xx and HTTP 401 are treated as successful delivery. All other status codes trigger a retry. undocumented
  • Redirects: HTTP 3xx responses are followed (up to 10 hops). Only if no 2xx/401 is reached after 10 redirects does the callback count as failed.
  • Timeout: Each callback request has a timeout of 5 seconds (configurable via requestTimeout).
  • Retry intervals: On failure, retries use exponential back-off: 100ms, 500ms, 1s, 2s, 4s, 8s, 10s, 30s, 60s, 60s, 60s, 60s (12 attempts over approximately 5 minutes, configurable via retryIntervals).
  • After all retries are exhausted: Non-permanent hooks are automatically removed. Permanent hooks continue retrying indefinitely at 60-second intervals (configurable via permanentIntervalReset).

Event Types

Meeting Events

Event ID Description
meeting-created A meeting was created.
meeting-ended A meeting has ended. This also triggers synthetic user-left events for all connected users.
meeting-recording-started Recording has started.
meeting-recording-stopped Recording has stopped.
meeting-recording-unhandled Unhandled recording event (fallback when recording status is neither true nor false).
meeting-screenshare-started Screen sharing started (includes presenter user data).
meeting-screenshare-stopped Screen sharing stopped (includes owner user data).
meeting-presentation-changed The active presentation changed (includes presentation-id).

User Events

Event ID Description
user-joined A user joined the meeting (includes guest flag, user data, IP address, User-Agent).
user-left A user left the meeting (includes guest flag). Also generated synthetically on meeting-ended.
user-audio-voice-enabled Audio enabled (includes listening-only, sharing-mic, muted flags).
user-audio-voice-disabled Audio disabled.
user-audio-muted User was muted.
user-audio-unmuted User was unmuted.
user-audio-unhandled Unhandled audio event (fallback).
user-cam-broadcast-start Webcam started (includes stream-id).
user-cam-broadcast-end Webcam stopped.
user-presenter-assigned User was assigned the presenter role.
user-presenter-unassigned User was removed from the presenter role.
user-emoji-changed User emoji or reaction changed (includes emoji value).
user-raise-hand-changed User raised or lowered their hand (includes raise-hand boolean). On BBB versions prior to 2.7, this is generated synthetically from user-emoji-changed.

Chat and Notes Events

Event ID Description
chat-group-message-sent A message was sent in the public chat. Private chat messages do not generate webhook events.
transcript-updated Transcription updated (includes transcript, locale, final flag).
pad-content Shared notes content changed (includes pad-id, rev, text).

Poll Events

Event ID Description
poll-started A poll was started (includes question and answer options).
poll-responded A participant responded to a poll (includes answer IDs).

Record and Playback (RAP) Events

Event ID Description
rap-archive-started Archiving started.
rap-archive-ended Archiving completed (includes recorded flag and duration).
rap-sanity-started Integrity check started.
rap-sanity-ended Integrity check completed.
rap-post-archive-started Post-archiving started.
rap-post-archive-ended Post-archiving completed.
rap-process-started Processing started.
rap-process-ended Processing completed.
rap-post-process-started Post-processing started.
rap-post-process-ended Post-processing completed.
rap-publish-started Publishing started.
rap-publish-ended Publishing completed (includes full recording object with metadata, playback, and download information).
rap-post-publish-started Post-publishing started.
rap-post-publish-ended Post-publishing completed.
rap-published Recording published.
rap-unpublished Recording unpublished.
rap-deleted Recording deleted.

Most RAP events include record-id, success (boolean), and step-time. Events with a workflow field additionally contain the processing workflow name.

Server Configuration

The following options can be configured in /etc/bigbluebutton/bbb-webhooks.yml or config/default.yml. Most of these options are not covered in the official documentation. undocumented

Option Default Description
hookChecksumAlgorithm sha1 Hash algorithm for callback checksums (sha1, sha256, sha384, sha512).
api.supportedChecksumAlgorithms [sha1, sha256, sha384, sha512] Accepted algorithms for incoming API checksums.
api.port 3005 Port of the webhook API server.
api.bind 127.0.0.1 Bind address of the API server.
includeEvents [] Server-wide event filter: only these events are delivered to all hooks. Empty means all events.
excludeEvents [] Server-wide event filter: these events are suppressed for all hooks. Empty means no exclusions.
permanentURLs [] List of permanent hook URLs that are registered on startup and cannot be removed via the API.
retryIntervals [100,500,1000,...,60000] Retry intervals in milliseconds for failed callbacks.
permanentIntervalReset 60000 Retry interval in milliseconds for permanent hooks after all regular retries are exhausted.
requestTimeout 5000 HTTP timeout in milliseconds for callback requests.
multiEvent 1 When set to a value greater than 1, multiple events are bundled in the event array per callback.
queueSize 10000 Maximum size of the internal event queue.
bbb.auth2_0 false Enables Bearer token authentication instead of URL checksum for callbacks.

includeEvents and excludeEvents are server-wide filters that apply in addition to the per-hook eventID filter. An event must pass both filters to be delivered.

Operational Notes

  • Persistence: Hooks are stored in Redis and survive server restarts (re-synced on startup).
  • Ordering: Callbacks are sent sequentially per hook, one at a time, preserving event order.
  • URL uniqueness: Duplicate detection is based solely on the callback URL. The same URL cannot be registered with different meetingID or eventID filters — the first registration wins.
  • Data cleanup: Internal meeting mappings are removed after one week of inactivity (configurable via mappings.timeout, default: 604800000 ms).
  • Synthetic events: When a meeting ends, user-left events are automatically generated for all still-connected users, because BigBlueButton itself does not emit UserLeftMeetingEvtMsg at meeting end.
  • Private chats: Only public chat messages generate chat-group-message-sent events. Private messages are silently ignored.
On bbbserver.de, webhooks are available with two restrictions: (1) a meetingID is required for every hook — global hooks without a meetingID are not supported; (2) personal data in events is automatically obfuscated for privacy (e.g. participant IP addresses are not visible).

Frequently Asked Questions

Yes. The bbb-webhooks package must be installed via apt-get install bbb-webhooks. Without it, the hooks/create, hooks/list, and hooks/destroy endpoints are not available.

The webhook system retries delivery with exponential back-off over approximately 5 minutes (12 attempts). If all retries fail, non-permanent hooks are automatically removed. Permanent hooks continue retrying indefinitely at 60-second intervals.

No. Duplicate detection is based solely on the callback URL. If you register the same URL again, you receive a duplicateWarning and the existing hook remains unchanged. To monitor specific meetings separately, use distinct callback URLs.

No. Only messages sent to the public chat (MAIN-PUBLIC-GROUP-CHAT) trigger a chat-group-message-sent event. Private messages between participants do not generate any webhook events.

With getRaw=false (the default), you receive processed event data with a standardised structure containing type, id, and attributes fields. With getRaw=true, you receive the raw Redis message as published by BigBlueButton internally, which includes envelope and core fields. The raw format is useful for debugging or when you need data not included in the processed format.

No. Permanent hooks are configured server-side via the permanentURLs setting and cannot be removed through the API. Calling hooks/destroy on a permanent hook returns a destroyMissingHook error as if the hook does not exist.

HTTP 2xx and HTTP 401 are both treated as successful delivery. All other status codes, including 3xx (after following up to 10 redirects), 4xx (except 401), and 5xx, trigger a retry. This behaviour is not documented in the official BigBlueButton documentation.