Skip to navigation

Scheduling Bots

Future joins, calendar-driven scheduling, and full auto-join

View as Markdown

Put a bot in a meeting that has not started yet. There are three ways, from simplest to most automated:

  1. join_at: one API call, one future meeting
  2. Calendar event scheduling: schedule against synced Google or Outlook calendar events, with recurring support
  3. Auto-join: every meeting on a connected calendar gets a bot automatically

Platform support

ZoomGoogle MeetMicrosoft Teams
join_at schedulingYesYesYes
Calendar scheduling and auto-joinYesYesYes
Bot dispatched (bot.joining)About 2 minutes before the start timeAbout 2 minutes before the start timeAbout 2 minutes before the start time
Bot starts joiningAbout 30 seconds before the start timeAbout 30 seconds before the start timeLoads the meeting about 60 seconds early and clicks Join about 30 seconds before the start time
How long the bot waits to be admittedwaiting_room_timeout, counted from the scheduled startwaiting_room_timeout, counted from the scheduled startwaiting_room_timeout

Early joining means the bot is usually in the lobby when the meeting starts. If the host is late, the bot waits up to waiting_room_timeout (see automatic leave) and then ends as NotAllowed. See the capability matrix for per-platform limits.

1) One-off scheduling with join_at

Add an ISO 8601 timestamp to any create_bot request:

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": "Notetaker",
"join_at": "2026-12-20T20:00:00+05:30"
}'

Response (201):

{
"bot_id": "f923cd21-da86-4d77-b37b-0707d37751c8",
"transcript_id": null,
"meeting_url": "https://meet.google.com/abc-defg-hij",
"status": "Scheduled",
"join_at": "2026-12-20T14:30:00+00:00",
"schedule_name": "..."
}

Rules for join_at:

RuleDetail
FormatISO 8601, for example 2026-12-20T20:00:00Z, 2026-12-20T20:00:00.000Z or 2026-12-20T20:00:00+05:30. A time with no offset is read as UTC
EarliestAny time in the future. A past time returns 400 with {"message": "join_at must be in the future"}
Latest90 days ahead. Further out returns 400 with {"message": "Invalid join_at format: Cannot schedule bot more than 90 days (3 months) in the future. Requested schedule is N days in the future."}

In the dashboard’s API Playground, the Schedule step sets join_at for you:

API Playground bot builder on the Schedule step with the Schedule for later option highlighted
API Playground, Schedule step: (1) Schedule for later lets you pick the date and time sent as join_at.

What happens next:

  • A bot.scheduled webhook fires immediately (bot_status Scheduled, payload carries scheduled_join_time).
  • bot.joining fires when the bot is dispatched, about 2 minutes before join_at.
  • Without webhooks, poll GET /api/v1/bots/{bot_id}/status. It shows Scheduled until then.

CLI: meetstream bot create <link> --join-at 2026-12-20T20:00:00Z.

Change or cancel a scheduled bot

ActionCall
List upcoming scheduled botsGET /api/v1/calendar/scheduled_bots
Reschedule or edit (new scheduled_join_time in the future, and other create_bot fields such as meeting_link, bot_name, recording_config or custom_attributes)PATCH /api/v1/calendar/scheduled_bots/{bot_id}
CancelDELETE /api/v1/calendar/scheduled_bots/{bot_id}

Only bots that are still Scheduled can be changed; an active bot returns 400. CLI: meetstream calendar reschedule <bot-id> <iso8601> / meetstream calendar cancel <bot-id>.

2) Calendar event scheduling

Once a Google Calendar or Outlook Calendar is connected, MeetStream syncs events and finds Google Meet, Zoom and Microsoft Teams links in them. Schedule a bot for any synced event:

curl -X POST "https://api.meetstream.ai/api/v1/calendar/schedule/<EVENT_ID>" \
-H "Authorization: Token <YOUR_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"bot_config": { "bot_name": "Notetaker", "video_required": false }
}'

bot_config takes the same fields as the create_bot body.

Transcripts for calendar bots. Calendar-scheduled bots (this endpoint and auto-join) record the meeting. To get a transcript, call POST /api/v1/bots/{bot_id}/transcribe after audio.processed or bot.done. To transcribe during the meeting, create the bot with create_bot and join_at (section 1).

Recurring meetings

  • occurrence_date: schedule one specific occurrence
  • schedule_all_occurrences: true: schedule every occurrence (capped by occurrence_limit, default 52)
  • recurring_event: true: when the bot for one occurrence is dispatched, MeetStream schedules a bot for the next occurrence
  • You choose auto-rescheduling when you schedule the event. To change it for a scheduled event, unschedule the event and schedule it again
  • Standard iCalendar RRULEs are supported: daily, weekly, bi-weekly, monthly, yearly

When the calendar changes

MeetStream listens for calendar changes (Google push notifications and Microsoft Graph subscriptions) and renews those subscriptions automatically:

  • Meeting rescheduled: the bot’s join time moves with it.
  • Meeting cancelled or deleted: the schedule is deleted and the bot is marked Cancelled.
  • Meeting link changed: the scheduled bot keeps the old link. Update it with PATCH /api/v1/calendar/scheduled_bots/{bot_id} and a new meeting_link, or cancel and schedule again.

Unscheduling: DELETE /api/v1/calendar/schedule/{event_id}, optionally with cancel_all_occurrences: true or from_date for a series.

3) Full auto-join

Turn on auto-scheduling and every upcoming meeting with a meeting link gets a bot:

curl -X POST "https://api.meetstream.ai/api/v1/calendar/auto-schedule/enable" \
-H "Authorization: Token <YOUR_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"default_bot_config": {
"bot_name": "Notetaker",
"video_required": false,
"automatic_leave": { "everyone_left_timeout": 60 }
}
}'

Mechanics worth knowing:

  • Events starting in the next 24 hours are scheduled by a daily job (midnight UTC) and again whenever the calendar changes.
  • Auto-join covers every synced event with a meeting link that starts in the next 24 hours, including events that you declined and events that you do not own. To choose events by RSVP, organizer or attendees, keep auto-join off and schedule events one at a time.
  • Only Google Meet, Zoom and Microsoft Teams links are joined.
  • An event that already has a scheduled bot is skipped, so auto-join composes safely with manual scheduling.
  • If you omit default_bot_config, bots are named MeetStream Calendar Bot and record audio only.
  • To transcribe an auto-joined bot, call POST /api/v1/bots/{bot_id}/transcribe after the meeting.
  • Override any individual meeting by scheduling it manually with a custom bot_config.
  • Disable with POST /api/v1/calendar/auto-schedule/disable; inspect with GET /api/v1/calendar/auto-schedule/settings.
  • Auto-join uses your account’s first active API key. With no active key, nothing is scheduled.

CLI: meetstream calendar auto-join on|off [-n name] [--video]. There’s also an Auto-schedule bots toggle on the dashboard’s Calendar page:

Calendars page in the MeetStream dashboard with the Auto-schedule bots toggle

Never double-book a meeting

Scheduling and deduplication are designed to compose:

  • Scheduling the same event twice returns 409 with "error": "A bot is already scheduled for this event", the existing bot_id and a hint. Change the existing bot with PATCH /calendar/scheduled_bots/{bot_id} instead.
  • A deduplication_key works inside bot_config on calendar scheduling and on create_bot with a future join_at: a repeat returns the existing bot (200), and a key reused for a different meeting URL returns 409.
  • To retry the create call safely, use an Idempotency-Key header: a repeat returns 507 with the original bot and creates nothing new.

Troubleshooting

  • Status Failed with error reason ScheduledDispatchExhausted? MeetStream could not start the scheduled bot within 20 minutes of its join time. If the meeting is still running, create a new bot without join_at. See bot status and error codes.
  • The bot went to the old link after the invite changed? The link was updated in the calendar after the bot was scheduled. PATCH the new meeting_link onto the scheduled bot.
  • The bot ended as NotAllowed? Nobody admitted it within waiting_room_timeout. See your platform guide: Zoom, Google Meet, Microsoft Teams.

Next steps