Skip to navigation

Automatic Leave Configuration

Control when a bot leaves on its own, so it never waits in a dead lobby, sits in an empty call, or records other notetakers
View as Markdown

Set automatic_leave on create_bot to decide when the bot gives up on the lobby, leaves an empty or silent meeting, or leaves when only other notetakers remain. This page lists every setting, its range and default, and exactly which platforms honor it today.

How it works

  • Every setting lives under automatic_leave in the body of POST /api/v1/bots/create_bot. You can also change it on a scheduled bot with PATCH /api/v1/calendar/scheduled_bots/{bot_id}.
  • Values are whole seconds. Booleans and numeric strings are rejected.
  • Out-of-range values return 400 with a specific message, for example waiting_room_timeout for GMeet must not exceed 600 seconds (got 900) or everyone_left_timeout must be at least 60 seconds (got 30).
  • If you omit a field, the default below applies. Whichever timeout fires first ends the session.
  • Every automatic exit is a normal leave: you get bot.leaving, then a terminal bot.stopped (or bot_event: "bot.notallowed" for the lobby timeout), and the post-call pipeline runs as usual.
"automatic_leave": {
"waiting_room_timeout": 600,
"no_one_joined_timeout": 600,
"everyone_left_timeout": 300,
"voice_inactivity_timeout": 900,
"in_call_recording_timeout": 14400,
"recording_permission_denied_timeout": 60,
"bot_detection": {
"using_participant_names": {
"matches": ["notetaker", "recorder", "otter", "fireflies"],
"activate_after": 300,
"timeout": 30
}
}
}

Ranges and defaults

FieldRange (seconds)DefaultWhen it ends the sessionExit status and message
waiting_room_timeout60 to the platform maximum: Zoom 1200, Google Meet 600, Teams 1800Zoom 600, Google Meet 600, Teams 1200The bot is not admitted in timeNotAllowed. Zoom and Meet: Failed: Not admitted to meeting. Teams: Failed: Bot not allowed to join meeting
no_one_joined_timeout60 to 1800600, Teams 1200Nobody else ever joinsStopped, Bot exited the call: No one joined the meeting (Google Meet only)
everyone_left_timeout60 to 1800600, Teams 1200Everyone else has leftStopped, Bot exited the call: Everyone left the meeting
voice_inactivity_timeout60 to 1800600 (applied by the bot when you omit the field)Nobody has spoken for this longStopped. Zoom and Teams: Bot exited the call: Voice inactivity timeout. Meet: Bot exited the call: Voice inactivity for Ns (threshold: Ns)
in_call_recording_timeout600 to 1800014400 (4 hours)The session reaches this lengthStopped, Bot exited the call: Maximum recording time reached (Zoom, see below)
recording_permission_denied_timeout60 to 30060 on ZoomThe Zoom host does not answer the recording requestRecordingPermissionDenied (Failed: Recording permission timeout), then Stopped
activate_after (bot detection)60 to 1800300See bot detection
timeout (bot detection)5 to 3005See bot detectionStopped
call_end_grace_seconds (WhatsApp calls, Beta)10 to 30030Call audio stops, for example when the other side hangs upStopped

On WhatsApp calls, everyone_left_timeout defaults to 0 (off) and also accepts 0, because WhatsApp does not report reliable presence. Use call_end_grace_seconds instead.

Which settings each platform honors today

Not every setting is enforced on every platform yet. The API accepts and validates all of them on every platform, so a 201 does not mean the setting will act. Check this table before relying on a setting as a safety net.

SettingZoomGoogle MeetMicrosoft Teams
waiting_room_timeoutHonored. The same timer also covers a host who never starts the meeting. The timer includes the wait until a scheduled start.Honored. Measured from the join request, plus the wait until a scheduled start.Honored. Measured from the Join click.
no_one_joined_timeoutNot enforced. Accepted and ignored.Honored. Starts at admission or at the scheduled start, whichever is later.Not enforced. everyone_left_timeout covers this case on Teams (next row).
everyone_left_timeoutPartly. The timer starts only when a participant leaves and at most one other person is left. A bot that joins an empty meeting never starts it.Honored once someone else has been in the meeting.Honored. Starts whenever the bot is alone, including when nobody has joined yet.
voice_inactivity_timeoutPartly. Starts after the first speaker is heard. Incoming meeting audio also refreshes it, so it may not fire in a meeting where Zoom keeps sending audio during silence.Honored. Starts at admission; the first 30 seconds are ignored.Honored. Starts at admission. Any meeting audio resets it, not only speech, so background noise keeps the bot in.
in_call_recording_timeoutPartly. Enforced only when video_required, audio_separate_streams or video_separate_streams is on. Audio-only bots have no maximum length.Not enforced as a leave timer.Not enforced as a leave timer.
recording_permission_denied_timeoutHonored.Ignored (Zoom only).Ignored (Zoom only).
bot_detectionHonored.Honored.Honored.

Need a hard maximum length on every platform today? Stop the bot yourself with Remove Bot from your own scheduler, for example at the meeting’s end time plus a margin. On Zoom, turn on video_required or separate streams if you want in_call_recording_timeout enforced.

Setting details

waiting_room_timeout

How long the bot waits to be admitted before it gives up, withdraws its request and ends as NotAllowed (webhook event: "bot.stopped", bot_event: "bot.notallowed").

  • bot.in_waiting_room fires on every join, even when the host admits the bot instantly, so its arrival does not prove there is a lobby.
  • Use a shorter value for ad-hoc bots so a request nobody will answer does not linger. Use a longer value for scheduled bots where the host may start a few minutes late.
  • On Zoom, a meeting that the host never starts also ends as NotAllowed when this timer expires. If Zoom reports Meeting not yet started, the bot stops immediately instead.
  • On Google Meet, a meeting that has not started ends as Failed with ErrorReason: "MeetingNotStarted", not on this timer.
  • Troubleshooting: Google Meet lobby and admission, Zoom, Microsoft Teams.

no_one_joined_timeout

How long the bot stays in a meeting that nobody else has joined. Enforced on Google Meet only. On Teams, set everyone_left_timeout instead: it also fires when nobody ever joined. On Zoom, see the gap described above.

everyone_left_timeout

How long the bot stays after the other participants leave. If you also use bot detection, this is your safety net for the case where the notetakers leave too.

voice_inactivity_timeout

How long the bot tolerates silence while people are still connected, for example when attendees walk away but keep the call open. The API only forwards the field when you set it; otherwise the bot applies 600 seconds. Voice inactivity is independent of who is in the meeting.

in_call_recording_timeout

The maximum session length, from 10 minutes to 5 hours. Treat it as a failsafe. See the per-platform table above: today it is enforced on Zoom only, and only for bots that capture video or separate streams.

recording_permission_denied_timeout (Zoom only)

When a Zoom bot cannot record right away, it asks the host for recording permission once and waits this long.

  • Host allows: bot.recording_permission_allowed, then bot.recording.
  • Host denies: bot.recording_permission_denied (Failed: Recording permission denied by host), bot.leaving, then bot.stopped with Bot exited the call: Recording permission denied by host.
  • No answer in time: bot.recording_permission_denied (Failed: Recording permission timeout), bot.leaving, then bot.stopped with Bot exited the call: Recording permission timeout.

The bot does not ask again after a denial. The field is validated on every platform (60 to 300) but only Zoom uses it.

Bot detection: leave when only other bots remain

everyone_left_timeout never fires while another vendor’s notetaker is still in the call, because the meeting is not empty. Without bot detection, your bot keeps recording silence or crosstalk between notetakers, and you keep paying for those minutes. Bot detection is opt-in and works on Zoom, Google Meet and Microsoft Teams with the same payload.

How it works

You give the bot a list of name keywords. Once the bot has been in the meeting for activate_after seconds, it checks the participant list. When every other participant’s display name contains at least one keyword, it starts a timeout-second countdown. If a person without a matching name joins, the countdown is cancelled. If the condition still holds when the countdown ends, the bot leaves.

The bot never matches itself. It recognizes its own entry in the participant list by identity, not by name, so a bot named MeetStream Notetaker is safe even with notetaker in matches.

Example

curl -X POST "https://api.meetstream.ai/api/v1/bots/create_bot" \
-H "Authorization: Token YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"meeting_link": "https://meet.google.com/abc-defg-hij",
"bot_name": "MeetStream",
"video_required": false,
"automatic_leave": {
"everyone_left_timeout": 600,
"bot_detection": {
"using_participant_names": {
"matches": [
"notetaker", "recorder", "assistant", "copilot",
"otter", "fireflies", "tl;dv", "read.ai",
"fathom", "grain", "fellow", "notta", "krisp"
],
"activate_after": 300,
"timeout": 30
}
}
}
}'

In plain English: five minutes after admission, start watching the participant list. As soon as everyone else looks like a notetaker, wait 30 seconds, and leave if nothing changes.

Fields

automatic_leave.bot_detection accepts one mechanism, using_participant_names. Any other key (for example using_participant_events or silence_detection) returns 400 with automatic_leave.bot_detection contains unsupported keys: [...].

FieldTypeRequiredDefaultRangeDescription
matchesarray of stringsYesnon-emptyCase-insensitive substrings. A participant counts as a bot when their display name contains any of them. Trimmed, lowercased and de-duplicated, so ["Otter", " OTTER "] becomes ["otter"].
activate_afterinteger (seconds)No30060 to 1800Delay after admission before the check starts, so real participants have time to arrive.
timeoutinteger (seconds)No55 to 300How long the condition must hold before the bot leaves.

Omit bot_detection, or send {}, to turn it off. The other automatic_leave settings keep working either way.

Example timeline

With activate_after: 300 and timeout: 30, and the bot admitted at 0:02:

TimeParticipantsWhat the bot does
0:02Bot admittedCheck is off until 5:02.
0:10Bot, 2 people, 1 notetakerWaiting.
3:00Both people leave; bot and notetaker remainStill waiting for activate_after.
5:02Bot and notetakerCondition holds; 30-second countdown starts.
5:20A person joinsCountdown cancelled.
6:40That person leavesCondition holds again; a new countdown starts.
7:10Bot and notetakerCountdown ends; the bot leaves.

How the exit is reported

The exit is a normal Stopped, never bot.kicked, bot.denied or bot.failed, and recording, transcription and bot.done follow as usual. To attribute the exit, look for the text only other bots remain (compare case-insensitively):

PlatformWhere the text appears
Zoombot.stopped message: Bot exited the call: only other bots remain (bot_detection.using_participant_names)
Google Meetbot.stopped message: Bot exited the call: Only other bots remain (N matched: ...), with the matched names
Microsoft Teamsbot.leaving message, which mentions only other bots remain (bot_detection.using_participant_names). The bot.stopped message is Bot exited the call

Choosing matches

A good starting list:

[
"notetaker", "recorder", "assistant", "copilot",
"otter", "fireflies", "tl;dv", "read.ai",
"fathom", "grain", "fellow", "notta",
"krisp", "meetgeek", "supernormal", "tactiq",
"rewatch", "circleback"
]
  • Match the name people see. Most notetakers join with names like “Otter.ai Notetaker” or “Fathom AI Notetaker”, so either the brand (otter) or the role (notetaker) works.
  • Substrings, not exact names. otter matches “Otter.ai Notetaker”, “OtterPilot” and “otter-bot”.
  • No regular expressions. Characters like ., : and ; match literally.
  • Avoid short fragments. ai would match a person named “Ainsley”. Prefer read.ai or otter.ai.
  • Non-Latin names. Matching works on any script, but the keyword must appear in the name exactly as the platform shows it.

Tuning activate_after and timeout

Profileactivate_aftertimeoutWhen to use
Aggressive60 to 1205 to 30Internal meetings that start on time. Faster exit, higher risk if a person joins late.
Balanced (recommended)30030 to 60Gives latecomers five minutes, then leaves within a minute once only notetakers remain.
Conservative600 to 120060 to 300Customer meetings where leaving early is costly.

Err on the side of larger values. A bot that stays too long is caught later by the other timeouts; a bot that leaves while people are still talking loses the recording.

Google Meet notes

  • Meet can show a participant as “Unknown” for the first seconds after they join. An unnamed participant does not match, so the bot waits until names settle.
  • If you send two of your own bots to the same meeting at the same moment, keep activate_after at 300 or more so each bot has reliably identified itself before the check starts. If a bot cannot yet tell which entry is its own, it skips the check rather than leave.

Putting them together

ScenarioWhat ends the session
Nobody admits the botwaiting_room_timeout, ending as NotAllowed
Zoom meeting that the host never startswaiting_room_timeout, ending as NotAllowed
Bot admitted, nobody else ever joinsMeet: no_one_joined_timeout. Teams: everyone_left_timeout. Zoom: not covered today; remove the bot yourself
Real meeting; everyone, including notetakers, leaveseveryone_left_timeout
People leave, notetakers staybot_detection, usually well before everyone_left_timeout
People connected but silentvoice_inactivity_timeout
Meeting runs much longer than expectedin_call_recording_timeout on Zoom bots with video or separate streams; otherwise remove the bot yourself
Zoom host ignores the recording promptrecording_permission_denied_timeout, then Stopped

Updating a scheduled bot

PATCH /api/v1/calendar/scheduled_bots/{bot_id} accepts automatic_leave and validates it with the same rules as create_bot. The patch replaces the whole automatic_leave object, so send every setting you want to keep. To turn off bot detection on a scheduled bot, send your full automatic_leave object without bot_detection. Changes apply the next time the bot starts; there is no way to change settings while a bot is already in a meeting.

Troubleshooting

Why did my bot leave too early?

  • Check the message on bot.stopped (or in the dashboard timeline) to see which rule fired. The error reference lists every message.
  • For bot detection, a keyword is probably too broad. Remove short fragments and raise activate_after or timeout.
  • For voice inactivity on a quiet meeting, raise voice_inactivity_timeout (the default is 600 seconds even if you never set it).

Why is my bot still in the meeting when only notetakers remain?

  1. Check that you set bot_detection: it is off by default. GET /api/v1/bots/{bot_id}/detail returns the stored request in RequestPayload.
  2. Check the notetakers’ names actually contain one of your keywords.
  3. Check that activate_after has passed. If the people left before then, the check starts at activate_after.

Why is my Zoom bot alone in a meeting and not leaving?

On Zoom, no_one_joined_timeout is not enforced, and everyone_left_timeout only starts after someone leaves. If the bot joined a meeting nobody else attended, stop it with Remove Bot.

FAQ

Is bot detection on by default? No. Bots without automatic_leave.bot_detection never check names.

Does it cost extra? No. It usually saves money, because the bot stops recording sooner.

Does it work in breakout rooms? No. The bot stays in the main meeting and checks only the main meeting’s participants.

Will the post-call transcript still be generated? Yes. Automatic exits are normal leaves, so audio, video, transcription and bot.done follow as usual.