๐ Integration guide
The SDK only needs a join URL. Your backend creates it with your BiggerBlueButton API credentials, and your app hands it to the SDK. The API secret never leaves your server.
โโโโโโโโโโโโโโโโโโโโโโโโ 1. create (signed call) โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Your backend โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโถ โ BiggerBlueButton API โ
โ (BBB URL + secret) โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ (your BBB URL) โ
โโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โ 2. signed join URL, over HTTPS, to a signed-in user
โผ
โโโโโโโโโโโโโโโโโโโโโโโโ 3. join(joinUrl) โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Your mobile app โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโถ โ BigBlueButton SDK โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ (full-screen meeting) โ
โโโโโโโโโโโโโโโโโโโโโโโโ 4. leave reason โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ 1. Get your API credentialsโ
- Sign in to the dashboard and open BigBlueButton API in the sidebar (the API Endpoint page).
- Copy the BBB URL, for example
https://biggerbluebutton.com/bigbluebutton/<username>/. - Reveal and copy the BBB Secret.
API calls go to <BBB URL>api/<method>, for example https://biggerbluebutton.com/bigbluebutton/<username>/api/create. The API reference covers the main calls (create, join, end, meeting info, recordings) and how the checksum works.
The BBB Secret signs every API call. Never put it in the mobile app: anyone can extract it from an app binary. Rotate secret on the API Endpoint page invalidates all existing integrations at once.
๐ฅ๏ธ 2. Create the meeting and the join URL (backend)โ
Your backend calls create, then signs, but does not open, the join URL:
createcreates the meeting. Calling it again for a running meeting is safe if you send the sameattendeePW/moderatorPWevery time, or none (otherwise BigBlueButton answersidNotUnique). The meeting must exist before anyone joins.joinis a signed URL for one user. Your backend builds it but never requests it: the SDK opens it on the device, which starts that user's session. This URL is what the app receives.
Each call carries checksum = sha256(method + queryString + secret); SHA-1 is accepted too.
// Node.js 18+, on your backend only
import crypto from 'node:crypto';
// BBB_URL looks like https://biggerbluebutton.com/bigbluebutton/<username>/
const BBB_URL = process.env.BBB_URL;
const BBB_SECRET = process.env.BBB_SECRET; // never ship this in the app
function signedUrl(method, params) {
// the platform re-encodes the query PHP-style, which escapes '*'
const query = new URLSearchParams(params).toString().replace(/\*/g, '%2A');
const checksum = crypto.createHash('sha256')
.update(method + query + BBB_SECRET)
.digest('hex');
return `${BBB_URL}api/${method}?${query}&checksum=${checksum}`;
}
// 1) create the meeting (safe to call again for the same meetingID)
await fetch(signedUrl('create', { meetingID: 'demo-123', name: 'Weekly sync' }));
// 2) sign (don't fetch) the join URL for one user, and return it to the app
const joinUrl = signedUrl('join', {
meetingID: 'demo-123',
fullName: 'Alice',
role: 'VIEWER', // or MODERATOR
});
Serve that URL from an endpoint of your own API that knows who the user is (for example POST /meetings/demo-123/join), and return it to the app over HTTPS. The PHP, Node.js, Python and ASP.NET pages show the same checksum scheme with SHA-1, which the platform also accepts; use your BBB URL followed by api (for example https://biggerbluebutton.com/bigbluebutton/<username>/api) as their endpoint.
Anyone holding a join URL enters the meeting as that user. Create one per user, right before they join, and don't log or share it.
๐ฒ 3. Join from the appโ
The app asks your backend for a join URL, then hands it to the SDK:
- Android
- iOS
- Flutter
- React Native
import org.bigbluebutton.bbb.sdk.*
val joinUrl = myBackend.joinUrl(meetingId) // from step 2
BigBlueButtonSdk.join(activity, BbbJoinOptions(joinUrl = joinUrl, meetingName = "Weekly sync"),
object : BbbMeetingListener {
override fun onJoined() { /* in the meeting */ }
override fun onLeft(reason: BbbLeaveReason, detail: String?) { /* back in your app */ }
override fun onError(message: String) { /* the meeting may still be running */ }
})
import BBBMeetingSDK
let joinUrl = try await myBackend.joinUrl(meetingId) // from step 2
BigBlueButtonSDK.shared.join(from: self,
options: BBBJoinOptions(joinUrl: joinUrl, meetingName: "Weekly sync"),
delegate: self)
extension MeetingViewController: BBBMeetingDelegate {
func meetingDidJoin() {}
func meetingDidLeave(reason: BBBLeaveReason, detail: String?) {} // the meeting is already dismissed
func meetingDidFail(message: String) {}
}
import 'package:bbb_meeting_sdk/bbb_meeting_sdk.dart';
final joinUrl = await myBackend.joinUrl(meetingId); // from step 2
// completes when the user is back in the app
final left = await BbbMeetingSdk.join(BbbJoinOptions(joinUrl: joinUrl, meetingName: 'Weekly sync'));
print('left: ${left.reason} ${left.detail}');
import { BigBlueButtonMeeting, type LeaveInfo } from '@bbb-mobile/bigbluebutton-mobile-sdk';
// joinUrl comes from step 2
function MeetingScreen({ joinUrl, onDone }: { joinUrl: string; onDone: (info: LeaveInfo) => void }) {
return (
<BigBlueButtonMeeting
joinUrl={joinUrl}
meetingName="Weekly sync"
onJoined={() => {}}
onLeave={(info) => onDone(info)} // unmount the component here
openLogoutUrl={false} // stay in the app when the meeting ends
/>
);
}
Each platform needs a one-time setup first (Gradle, Info.plist keys, Babel plugins and so on): see ๐ค Android, ๐ iOS, ๐ Flutter and โ๏ธ React Native.
๐ช 4. Handle the leave reasonโ
When the meeting UI goes away, the SDK tells your app why:
| Reason | When | What your app usually does |
|---|---|---|
left | The user left: leave button, declined the recording, or cancelled the guest lobby. Also after your app calls leave() (detail is host_leave). | Return to the previous screen. |
ended | The meeting ended on the server; the user was removed or refused (for example by a moderator, or because the meeting is full); or a guest was denied. detail carries the end code. | Show that the meeting has ended, or why the user can't stay. |
error | The join failed before the meeting opened (invalid link, network or HTTP error), or the session hit an unrecoverable error. detail carries the error message or reason code. | Show the error. To retry, fetch a fresh join URL. |
unsupported | The server version or media bridge is not supported by this client (it needs BigBlueButton 4.0.x). | Explain that the meeting can't open in the app. |
cancelled | The meeting screen went away before the meeting UI reported anything, for example when your app calls leave() before the meeting started. Android, iOS and Flutter only. | Treat it like left. |
To take the user out of the meeting from your app (for example on sign-out), call leave: BigBlueButtonSdk.leave() on Android, BigBlueButtonSDK.shared.leave() on iOS, BbbMeetingSdk.leave() on Flutter, or the leaveSignal prop on React Native. The usual leave callback follows (left, with detail host_leave). The meeting keeps running for everyone else; to end it for all participants, call the signed end API from your backend.
โ Integration checklistโ
- Secret on the server โ only your backend signs API calls; the app only ever sees join URLs.
- HTTPS only โ join URLs must be
httpsURLs. - One meeting at a time โ iOS ignores a second
joinwhile a meeting is open, Flutter rejects it withalready_in_meeting, and one React Native runtime hosts one meeting. - Permissions โ the SDK asks for the microphone, the camera and (Android) notifications inside the meeting. iOS apps must declare the usage strings in
Info.plist. - Real devices โ the iOS simulator joins meetings but has no camera and no screen capture; test media on a device.
- Android builds โ build release (the SDK ships release native libraries), keep to the 64-bit ABIs and leave R8 minification off for now.
- Server version โ the meeting server must run BigBlueButton 4.0.x.
- Client type โ the SDK reports itself to the server as
NATIVE_MOBILE; setclientTypein the SDK config to change it.
๐งช Try it quicklyโ
- On the API Endpoint page, click Open API Mate. It builds signed
createandjoinlinks for your account. - Create a meeting, then copy a
joinlink. - Paste it into a test build of your app, or into the Flutter plugin's example screen (a join URL field, a Join meeting button and a log of SDK events, see ๐ Flutter).