Zoom Breakout Rooms
Seamlessly capture conversation data from breakout rooms in Zoom
Overview
When using Zoom breakout rooms, the Recall.ai bot operates much like a human participant. That is, a single bot instance can only monitor one breakout room at a time. To record every breakout room concurrently, you will need to deploy one bot per room.
You can control how Recall.ai bots behave in breakout rooms:
- accept any invite (the default)
- join a specific room
- stay in the main meeting room.
How It Works
Use the regular Zoom meeting invitation URL, including its passcode parameter when present. Each bot joins the main meeting first and can capture only the room it is currently in. Choose one of these two flows:
| Your application needs to… | Bot configuration | Who assigns the rooms? | Zoom self-selection setting |
|---|---|---|---|
| Follow host assignments, including moves between rooms | One auto_accept_all_invites bot per room to record concurrently | Zoom or the host assigns each bot | Can be disabled |
| Dispatch a separate bot when a room opens | One join_main_room coordinator plus one join_specific_room bot per room | Your application creates each room bot using a Recall room ID | Enable Let participants choose room before dispatch |
For example, recording five breakout rooms through automatic dispatch requires six bots: one coordinator and five room bots. A coordinator does not create or distribute room bots for you; your application handles the webhooks and calls Create Bot.
Bots dispatched after an opened event still need time to join, be admitted, enter their room, and obtain recording permission. They cannot capture speech from before they are recording in that room. If the beginning of each discussion matters, have the host wait until its bot is ready.
Host-assigned breakout bots
- Create a bot with the meeting URL and
breakout_room.mode: "auto_accept_all_invites"(the default). Create a separate bot for each room you want to record at the same time. - Admit the bots and allow recording in Zoom when prompted.
- Have Zoom or the host assign each bot to its room. This flow works with Let participants choose room disabled.
- Track each bot's room entry using
breakout_room_entered, and verify that it is recording the expected room audio. When the host ends the breakout session, the bot returns to main and can accept another assignment, provided it has not already left the call.
The bot follows assignments, not a particular participant. If participants return to main while their room remains open, the bot can remain behind and its automatic-leave timers still apply.
Automatic bot dispatch with a coordinator
- Configure a dashboard webhook endpoint as described in Webhooks. Enable Let participants choose room in Zoom before dispatching room bots.
- Send a coordinator using Create Bot, with the following request body. Save its returned bot ID together with this meeting instance's URL.
{
"meeting_url": "https://zoom.us/j/123456789?pwd=MEETING_PASSCODE",
"bot_name": "Main room coordinator",
"breakout_room": {
"mode": "join_main_room"
}
}- Admit the coordinator and open the breakout rooms. For each
bot.status_changeevent withdata.status.code: "breakout_room_opened", read the coordinator ID fromdata.bot_id, the Recall room ID fromdata.status.message.id, and its display name fromdata.status.message.name. See the full opened-event example below. - Look up the meeting URL you saved for that coordinator. Create a new bot for the room by posting to
/api/v1/bot/in the same Recall region. Keepbreakout_roomat the top level of the request:
{
"meeting_url": "https://zoom.us/j/123456789?pwd=MEETING_PASSCODE",
"bot_name": "Room 5 recorder",
"breakout_room": {
"mode": "join_specific_room",
"room_id": "f82e1db1-f41b-466e-bdfa-38343436d434"
}
}Use the room ID from the event in step 3 in place of the example UUID. Do not use a Zoom room ID or the room name. Save the returned room-bot ID alongside the coordinator ID and Recall room ID.
- Admit the room bot and allow recording when prompted. Wait for
breakout_room_enteredfrom that room bot for the requested room ID, then verify that it is recording the expected room audio.in_call_recordingalone does not confirm room entry: the bot may still be recording in main. A room-entry event alone does not guarantee that usable media has arrived. - When the host ends the breakout session, the
join_specific_roombot ends its call instead of returning to main. The coordinator stays in main, subject to its automatic-leave settings. Create a new room bot for a later breakout session when needed.
An opened event from the coordinator does not guarantee that another bot can enter the room. Enable Let participants choose room for independent room entry, even if opened events are already arriving. The requested room must also appear in the room list Zoom sends to the new bot.
Configuring Breakout Room Behavior
Default: auto_accept_all_invites
auto_accept_all_invitesBy default, a Recall.ai bot accepts all invites to breakout rooms. As the meeting host, you may assign the bot to any of the breakout rooms.
With breakout_room.mode: "auto_accept_all_invites", the bot returns to the main room when Zoom sends it the request to leave the breakout room. This can happen during the closing countdown; see Room transitions and automatic leaving.
In the following request to Create Bot, the mode is set explicitly. You can omit the entire breakout_room object to use this default. If you supply the object, its mode field is required.
{
"meeting_url": "https://zoom.us/j/...",
"breakout_room": {
"mode": "auto_accept_all_invites"
}
}Room transitions can emit breakout_room_entered and breakout_room_left notifications, with the room ID and name. Enable delivery as described in Webhooks. Do not assume every entered event will have a matching left event: a bot can end its call while in a room. See Recordings and transcripts.
Breakout Room IDs are normalized by Recall and do not represent Zoom's internal breakout room IDs.
{
"event": "bot.status_change",
"data": {
"bot_id": "ef5ab1ff-16fa-490d-8e6a-eb8450efe643",
"status": {
"code": "breakout_room_entered",
"created_at": "2025-10-15T07:14:27.050380+00:00",
"message": {
"id": "f82e1db1-f41b-466e-bdfa-38343436d434",
"name": "Room 5"
},
"sub_code": null
}
}
}
{
"event": "bot.status_change",
"data": {
"bot_id": "ef5ab1ff-16fa-490d-8e6a-eb8450efe643",
"status": {
"code": "breakout_room_left",
"created_at": "2025-10-15T07:14:27.050380+00:00",
"message": {
"id": "f82e1db1-f41b-466e-bdfa-38343436d434",
"name": "Room 5"
},
"sub_code": null
}
}
}
The coordinator: join_main_room
join_main_roomUse "mode": "join_main_room" in the "breakout_room" payload to Create Bot to dispatch a Recall.ai bot that stays in the meeting room and rejects all invites to join breakout rooms.
{
"meeting_url": "https://zoom.us/j/...",
"breakout_room": {
"mode": "join_main_room"
}
}A
"join_main_room"bot can act as the coordinator for dispatching other bots to breakout rooms. It can receive"breakout_room_{opened,closed}"webhooks.
A "join_main_room" bot may be used in two ways:
- Record the meeting happening in the main room.
- Observe creation/closure of breakout rooms, deciding whether to dispatch additional bots.
When "Let participants choose room" is enabled (see below), a "join_main_room" bot emits "breakout_room_{opened,closed}" webhooks in the format shown below. You can use the returned data.status.message.id to join the specific breakout room
{
"event": "bot.status_change",
"data": {
"bot_id": "ef5ab1ff-16fa-490d-8e6a-eb8450efe643",
"status": {
"code": "breakout_room_opened",
"created_at": "2025-10-15T07:14:27.050380+00:00",
"message": {
"id": "f82e1db1-f41b-466e-bdfa-38343436d434",
"name": "Room 5"
},
"sub_code": null
}
}
}
{
"event": "bot.status_change",
"data": {
"bot_id": "ef5ab1ff-16fa-490d-8e6a-eb8450efe643",
"status": {
"code": "breakout_room_closed",
"created_at": "2025-10-15T07:14:27.050380+00:00",
"message": {
"id": "f82e1db1-f41b-466e-bdfa-38343436d434",
"name": "Room 5"
},
"sub_code": null
}
}
}
See the Zoom breakout rooms sample app on GitHub.
Enable Let participants choose room before dispatching bots that will enter rooms without a host assignment. An opened status from the coordinator can occur when it is assigned a room even with self-selection disabled. Receiving that status does not guarantee that a newly sent bot can enter the room.
Join a specific breakout room
Upon receipt of a breakout_room_opened, you may choose to dispatch a Recall.ai bot to a specific breakout room. Use the breakout room ID returned in the webhook to Create a Bot that joins that specific breakout room.
Set room_id to the Recall ID at data.status.message.id in the opened status. Zoom room IDs and room names cannot be substituted. The following request creates a new bot for that room:
{
"meeting_url": "https://zoom.us/j/...",
"breakout_room": {
"mode": "join_specific_room",
"room_id": "f82e1db1-f41b-466e-bdfa-38343436d434"
}
}When breakout_room.mode is set to join_specific_room, the bot will not return to the main room once the breakout room has been closed, and will instead shut down with the call_ended status.
Webhooks
Some workspaces retain a legacy configuration that disables
breakout_room_entered/breakout_room_leftnotifications. This commonly affects older workspaces, but creation date alone does not establish the current configuration. If these events are missing after checking room movement and endpoint subscriptions, contact [email protected] to verify enablement for that workspace.
| Breakout Room Mode | Webhooks |
|---|---|
auto_accept_all_invites | breakout_room_entered, breakout_room_left |
join_specific_room | breakout_room_entered, breakout_room_left |
join_main_room | breakout_room_opened, breakout_room_closed |
Configure delivery
The v1.10 examples on this page show the legacy bot.status_change payload. Read the breakout status from data.status.code, the bot ID from data.bot_id, and room details from data.status.message. These notifications use the dashboard webhook endpoint, separately from real-time transcription and media destinations. Legacy-compatible workspaces can also receive the named bot.breakout_room_* event format. Check your delivered payload and endpoint subscriptions, and process one format for dispatch so the same room does not create duplicate bots.
- Open the Webhooks dashboard in the same workspace and region as the API key used to create the bots, and add your application's webhook URL.
- Configure the endpoint to receive
bot.status_change. In your handler, processbreakout_room_opened,breakout_room_closed,breakout_room_entered, andbreakout_room_leftaccording to the mode table. Also handle lifecycle statuses such ascall_ended,fatal, anddone. - Verify incoming requests, using the headers and signing secret documented for your account. Persist or enqueue the notification, then return
2xxpromptly. See Bot Webhooks for retries and timeouts. - Run a new test meeting and check endpoint delivery responses. Generation and successful delivery are separate checks. Older workspaces may need entered/left notifications enabled by support as described above.
| Region | Webhooks dashboard |
|---|---|
| US East | us-east-1 |
| US West | us-west-2 |
| EU | eu-central-1 |
| Japan | ap-northeast-1 |
Room transitions and automatic leaving
| Situation | auto_accept_all_invites | join_specific_room |
|---|---|---|
| Zoom asks the bot to leave as the host ends the breakout session | Returns to main | Ends its call with call_ended |
| Participants leave but the room stays open | Does not follow them automatically; automatic-leave timers still apply | Automatic-leave timers still apply |
| Host invites the bot to another room | Accepts the assignment | Ignores moves to a different room ID |
| Another breakout round begins after the bot has ended its call | Create a replacement bot | Create a new bot for the requested room |
Closing countdowns are not guaranteed recording time. A bot can act on Zoom's leave-room request immediately, before the countdown expires and before the coordinator receives a room-closed event. A room-closed event describes the room, not the exact end of a particular bot's capture.
A join_main_room coordinator stays in main and rejects breakout invitations. All modes remain subject to Bot Automatic Leave Behavior. Review everyone_left_timeout, noone_joined_timeout, waiting-room, silence, and not-recording timeouts against your planned waits and transitions. Closing rooms and leaving an open room empty are different actions; have the host close rooms or reassign invited bots when returning to main.
Recordings and transcripts
A recording follows the bot across rooms; moving to a breakout room does not automatically produce a separate file or a transcript containing only that room. If a room bot records in main before entering its room, that content can appear in its recording and transcript too. Configure transcription separately using the Transcription overview.
To estimate room intervals, store each room bot's entered/left events, including the bot ID, Recall room ID, and data.status.created_at event timestamp. Use event time rather than webhook delivery time. Also store call_ended and fatal: if the bot ends its call without a left event, close the pending interval using its terminal event as an upper bound. Intersect that interval with the actual recording/transcript timestamps; do not wait indefinitely for a left event or substitute the coordinator's room-closed time as the exact capture boundary.
Room transitions can include a media gap, and transition events are not sample-accurate audio boundaries. Use the timestamps to select candidate transcript content and validate boundary segments for your application.
For example, if a bot records in main at 10:00 UTC, enters Room 5 at 10:15, and leaves it at 11:00, select transcript content within the 10:15–11:00 interval. If the transcript only has relative timestamps, align them to the recording timeline first; do not compare relative seconds directly with webhook timestamps. See the v1.10 quickstart transcript example for transcript fields. Handle words that overlap a boundary explicitly rather than assuming every transcript segment belongs entirely to one room.
Limitations
-
Single Room Focus:
Each Recall.ai bot can only join and record one breakout room at a time, mirroring the experience of a human participant. Therefore, simultaneous recordings of multiple rooms require multiple bot instances. -
Participant Tracking:
Zoom participant tracking across rooms depends on your workspace configuration. Legacy tracking can produce duplicate entries or incorrect participant attribution after room moves. If you see these symptoms, contact [email protected] to verify whether the workspace needs the updated tracking configuration; do not infer enablement solely from its creation date. The update applies to future bots and does not rewrite participant IDs in completed recordings. It changes the participant ID format, so confirm your integration can accept the new IDs with support before the switch. Do not assume participant IDs are stable across different bots or meetings; see Identify Meeting Participants Uniquely for platform identifiers.
Best Practices
- Planning Ahead:
Determine the number of breakout rooms and the corresponding number of bots required before the meeting begins. Test admission, room assignment, recording permission, and media delivery before relying on coverage. Planning bot count alone does not guarantee that all discussion is captured. - Consistent Naming Conventions:
Use a clear naming convention for your bots (e.g., "BreakoutBot-1", "BreakoutBot-2", etc.) to easily identify which bot is assigned to which breakout room.
- Avoid duplicate dispatch: Store a meeting-instance/coordinator → room → bot mapping and reserve a room before creating its bot. Deduplicate webhook deliveries so retries do not create additional bots. When a new breakout round needs a new bot, update that room's dispatch state deliberately.
- Plan capacity: The coordinator counts as an additional bot. If host assignments can be planned ahead, schedule bots more than 10 minutes before
join_at. Bots created immediately in response to opened events are ad-hoc; check workspace concurrency and API rate limits before dispatching many rooms.
Troubleshooting
| Symptom | Check |
|---|---|
| No opened/closed events | Coordinator uses join_main_room; correct workspace/region and dashboard subscriptions; Zoom self-selection enabled for the automatic-dispatch flow; endpoint responses succeed. |
| No entered/left events | Check actual room movement, mode, endpoint subscriptions, and workspace enablement. If the bot ended its call while in the room, a matching left event may not be emitted; handle its terminal status too. |
| Create Bot rejects a breakout event as an invalid choice | Configure bot.status_change in the dashboard, separately from real-time media/transcript destinations. |
breakout_room_not_open after admission | Self-selection is enabled and the requested Recall ID appears in the new bot's room list. An earlier opened event is not sufficient. |
| Bot stays in an empty breakout or leaves before main resumes | Check whether the host closed the room or only participants left; inspect the bot's call_ended/fatal sub-code and automatic-leave settings. |
| Multiple bots are dispatched to one room | Check webhook retry handling and your stored active room-bot mapping before calling Create Bot again. |
| Same person appears more than once after room moves | Check the participant-tracking compatibility note in Limitations. |
If these checks do not resolve the issue, send support the Recall region, coordinator and room-bot IDs, Recall room ID, event timestamps, and the terminal status/sub-code. Include the Zoom self-selection setting and webhook delivery response where relevant.
FAQ
Why am I not receiving the breakout_room_opened and breakout_room_closed webhooks?
breakout_room_opened and breakout_room_closed webhooks?Use a coordinator configured with breakout_room.mode: "join_main_room" and receive bot.status_change through the dashboard. Inspect data.status.code for breakout_room_opened and breakout_room_closed. For the automatic-dispatch flow, enable Let participants choose room so newly sent bots can choose their rooms. Check endpoint delivery responses as well as event generation.
An opened event can occur with self-selection disabled when the main bot is assigned a room. That event does not establish that a different bot can enter it. See Troubleshooting for the full checklist.
I've configured my bot to join a specific breakout room, but it's not joining. Why is this happening?
Before sending a join_specific_room bot that the host will not assign, enable Let participants choose room in Zoom.
If the requested room is missing from the room list Zoom sends to that bot, the bot leaves with breakout_room_not_open. This can happen even if the main bot already generated an opened webhook for that room.

Can bots join breakout rooms when “Let participants choose room” is disabled?
Yes, a bot configured with auto_accept_all_invites can accept room assignments or invitations delivered by Zoom. This mode does not discover rooms or distribute bots across them; Zoom or the host must assign each bot.
Updated 3 days ago

