Google Meet Bots
Send a bot into any Google Meet call with one API request. Guest bots need no app, no OAuth and no admin setup.
Need a meeting to test against? Open meet.new while signed in to Google. You are the host of that meeting, so you can admit your own bot.
Google Meet at a glance
Meeting links
Send the standard meeting-code link. MeetStream checks the host when you create the bot, and the bot checks the link again before it joins.
How the bot joins
Guest or signed in?
Set up signed-in bots with the Google Signed-In Bots guide. On the MeetStream side, you register your bot domain under Integrations > Signed Bots, then add each bot account and its SSO key pair.

Display name, camera and microphone
- Name. A guest bot shows
bot_name(defaultMeetStream). A signed-in bot shows its Google account name instead. - Camera. The bot’s camera tile shows your
bot_image_url. Change it during the call with Send Image. - Microphone. The bot’s microphone only carries audio that you or your agent send (for example
initial_audioor an agent’s voice). It is silent otherwise. - Hiding the bot. Tile layout is chosen by each viewer in Meet, so no API can hide the bot from everyone. A clear
bot_nameand abot_messagethat explains why the bot is there work best.
Google’s transcription and Gemini notices
When a meeting already has Google’s own transcription or “Gemini is taking notes” turned on, Meet shows a notice before joining. The bot accepts that notice and continues to join, just as a person clicking Join now would.
Admission and the lobby
The meeting’s access settings, the organizer’s Google Workspace policies and the people in the call decide who Google Meet lets in. MeetStream controls how long the bot waits and how it reports each outcome.
How Meet decides
Meeting access is set by the host in Host controls > Meeting access (in the call) or in the Calendar event under Video call options > Host controls. Google defines three access types (Google’s description):
Two more things can stop a bot before any of this applies:
- The organizer’s Workspace admin can limit who joins the organization’s meetings, for example to signed-in Google accounts only, or to people in the organization. A guest bot then ends with
SignInRequired,MeetingRestrictedorCantJoinCall. A signed-in bot helps only if the policy allows its account. - Someone must be there to admit. A bot that asks to join can only be let in once the host (or, depending on settings, another eligible participant) is in the call.
Google states that anonymous users and third-party note takers that use “Ask to join” are automatically denied when the “Anyone with the meeting link can ask to join” option is off. In that case no admission prompt ever reaches the host.
Who can admit the bot
- With Host management on, only the host and co-hosts can admit people. Other attendees may never see the bot’s request, which is why a bot can look like it “never arrived” while MeetStream reports it waiting.
- With Host management off, people from the organizer’s organization who are in the call can usually respond to join requests too.
- With the Waiting room on, the host uses Bring in or Bring everyone in, or turns on Bring in automatically so waiting participants join when the host does (Google’s Waiting room help).
Get on the calendar invite
For Trusted and Restricted meetings, the reliable way to skip the lobby is a signed-in bot whose Google account email is a guest on the Calendar event. Pin the bot to that account with sign_in_email (and keep strict_email: true) so MeetStream never picks a different login. A Waiting room still holds every participant, invited or not.
What MeetStream reports while waiting
bot.in_waiting_roomfires as soon as the bot clicks Ask to join or Join now. When no approval is needed it is followed within seconds bybot.inmeeting.- The bot waits up to
automatic_leave.waiting_room_timeoutseconds: 60 to 600 on Google Meet, default 600. A higher value returns HTTP 400waiting_room_timeout for GMeet must not exceed 600 seconds. - For a scheduled bot, the wait is measured from the scheduled start time, so arriving a few seconds early does not shorten it.

Nobody admits the bot
When waiting_room_timeout passes, the bot clicks Leave, which withdraws its request so the host is not left with a stale prompt. Then:
If the meeting link or code changes while the bot waits, the bot reports the same WaitingRoomTimeout outcome.

The host denies the bot
When someone clicks Deny entry, Meet shows “You’ve been denied entry to this meeting” or “Someone in the call denied your request to join”. The bot reports:
For step-by-step fixes, see Google Meet Lobby & Admission Troubleshooting.
Join errors
Pages that block joining
When Meet shows one of these pages instead of the join screen, the bot stops right away with status Failed. The terminal webhook has event: bot.stopped, bot_event: bot.failed, bot_status: Failed and a lowercase failure_reason.
ErrorReason is returned by Get Bot Details. The full list of statuses and reasons across platforms is in the Bot status and error code reference.
Automatic retries
You don’t need to create a new bot for these; the same bot retries.
- “You can’t join this video call”. This page is sometimes temporary, so the bot retries the join up to three more times before it stops with
CantJoinCall. - Temporary Meet or network errors. “Something went wrong”, “There was a problem connecting to the meeting”, “Can’t connect to the meeting”, “You lost your network connection” and similar messages get up to 3 attempts in total. If all fail, the bot stops with status
Failed,ErrorReasonMeetTransientErrororNetworkError, and a message such asFailed: Google Meet reported a temporary error (after 3 attempts).
Other join failures
Leaving the meeting
Why a bot left mid-call
Planned leaves (your API call or an automatic-leave rule) end with status Stopped and no ErrorReason: Bot stopped via API request (Remove Bot), Bot exited the call: No one joined the meeting, Bot exited the call: Everyone left the meeting, and Bot exited the call: <reason> for other automatic-leave rules. In every case post-call processing runs as usual.
Automatic leave on Google Meet
All fields go in automatic_leave. Full behavior, including bot detection, is in Automatic Leave Configurations.
recording_permission_denied_timeout is Zoom only and has no effect on Meet.
Webhooks on Google Meet
A bot that joins and records normally sends:
Scheduled bots send bot.scheduled first. Every terminal webhook uses event: bot.stopped; the cause is in bot_event (bot.stopped, bot.kicked, bot.denied, bot.notallowed or bot.failed). Branch on bot_event.
Signed-in bots also include profile_image_url (the Google account’s photo) when available. Payloads are signed with X-MeetStream-Signature; see Webhooks and Events and Verifying Webhook Signatures.
Media on Google Meet
Live transcription on Meet
Set a streaming provider in recording_config.transcript.provider and a live_transcription_required.webhook_url; the webhook is required for every _streaming provider. Google Meet supports:
Speaker names in live transcripts come from Meet’s active speaker. Live transcript and caption POSTs do not include the X-MeetStream-Signature header. Put a secret token in the webhook URL and check it on each request. More in Live Transcription.
Native captions
With recording_config.transcript.provider.meeting_captions, the bot turns on Meet’s captions after it is admitted and records them. Meet captions are recorded in English. For other languages, use sarvam_streaming or a post-call provider. If captions do not switch on at first, the bot tries again every 15 seconds and stays in the meeting.
- With a
live_transcription_required.webhook_url, each caption is POSTed as{"type": "caption", "bot_id": "...", "caption": {"text", "speakerName", "speakerDisplayName", "deviceId", ...}}. - After the call, Get Bot Details returns
caption_file.availableand acaption_file.download_url(valid for 1 hour) when a caption file was saved.
See Meeting Captions.
Pause and resume
POST /api/v1/bots/{bot_id}/pause_recording and /resume_recording work on Google Meet (guide). While paused, the recording keeps its real duration but contains black video and silence, per-participant audio included. A second pause (or resume) changes nothing and returns HTTP 409 with "status": "no_op".
Native captions, chat capture and participant events continue during a pause. Remove the bot to keep captions, chat and participant events out of a paused stretch.
Find Meet bots in the dashboard
All Bots lists every bot with its platform and status. Filter by Google Meet to see only Meet bots; open a bot to see its status timeline.

Good to know
- Send
https://meet.google.com/<code>links. waiting_room_timeoutis 60 to 600 seconds on Meet.- Meetings that admit only signed-in accounts need a signed-in bot that the meeting’s policy allows.
- Set the maximum length with
remove_botor the timers above. voice_inactivity_timeoutis 600 seconds when you do not set it.- Meet captions are recorded in English.
- Remove the bot to keep captions, chat and participant events out of a paused stretch.
- Per-participant audio and video record up to 16 streams each.
- The bot stays in the main room.
- A signed-in bot always joins with its Google account. If sign-in fails, the bot ends with
GoogleSignInFailed.
Calendar auto-join
Connect a Google or Outlook calendar and MeetStream can schedule a bot for every event with a Meet link. See Scheduling Bots and Google Calendar OAuth Setup.
FAQ
Why is my bot stuck in the waiting room?
Someone who can admit has to let it in. With Host management on, only the host and co-hosts see the request; other attendees don’t, so to them it looks like the bot never arrived while MeetStream reports bot.in_waiting_room. Make sure the organizer or a co-host is in the call, or use a signed-in bot on the calendar invite. Troubleshooting steps: Lobby & Admission.
Why did my bot end with NotAllowed after 10 minutes?
Nobody admitted it within waiting_room_timeout (default 600 seconds, the Google Meet maximum). ErrorReason is WaitingRoomTimeout. The bot withdraws its request when it leaves. Lower the timeout for ad-hoc calls, or remove the need for admission with a signed-in, invited bot.
Why did my bot fail with CantJoinCall?
Meet showed “You can’t join this video call” on every attempt (the bot retries up to three more times first). This usually means the meeting doesn’t let people from outside the organization, or people who aren’t signed in, ask to join. Ask the organizer to check Host controls > Meeting access, or use a signed-in bot whose email is on the invite.
Why did my bot fail with SignInRequired?
The organizer’s Google Workspace only admits signed-in Google accounts, so a guest bot is sent to Google’s sign-in page. Use a signed-in bot.
Why did the bot join without anyone admitting it?
The meeting is Open, or the bot is a signed-in account on the calendar invite of a Trusted or Restricted meeting. You still get bot.in_waiting_room, followed within seconds by bot.inmeeting.
My signed-in bot is on the invite. Why is it still waiting?
The Calendar event has the Waiting room turned on, which holds everyone until a host brings them in. Also check that the invited email is exactly the login the bot used: set sign_in_email with strict_email: true to pin it.
Why does my bot show a different name than bot_name?
It is a signed-in bot. Meet shows the Google account’s name and photo, and bot_name is not used. Rename the account in Google Admin to change it.
Why did my bot leave a quiet meeting after about 10 minutes?
On Google Meet, voice_inactivity_timeout defaults to 600 seconds even if you don’t set it. Set a higher value (up to 1800) for meetings with long silences.
How do I set a maximum meeting length on Google Meet?
On Google Meet, set the maximum length with everyone_left_timeout, voice_inactivity_timeout or a Remove Bot call from your backend.
Why did my bot fail with 'Invalid Google Meet URL'?
The link started with http://. The bot joins https://meet.google.com/... links. Send the https:// version.
Which language do native captions use?
Meet captions are recorded in English. For other languages, use sarvam_streaming or a post-call provider.
What happens when the host clicks 'End call for everyone'?
The bot leaves with status Stopped (usually ErrorReason MeetingEndedByHost), and post-call processing and webhooks run as normal.
