> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.meetstream.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.meetstream.ai/_mcp/server.

# Scheduling Bots

> Schedule MeetStream bots ahead of time: join_at for one-off future joins, calendar event scheduling with recurring support, full auto-join, rescheduling, and deduplication.

There are three ways to put a bot in a meeting that hasn't started yet, 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

## 1) One-off scheduling with `join_at`

Add an ISO 8601 timestamp to any `create_bot` request:

```bash
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"
  }'
```

What happens:

* A `bot.scheduled` webhook fires immediately (bot\_status `Scheduled`, payload carries `scheduled_join_time`).
* `bot.joining` fires when the scheduled time arrives.
* Without webhooks, poll `GET /bots/{bot_id}` — status shows `Scheduled` until then.

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

### Change or cancel a scheduled bot

| Action                                                                                                             | Call                                              |
| ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------- |
| List upcoming scheduled bots                                                                                       | `GET /api/v1/calendar/scheduled_bots`             |
| Reschedule (new `scheduled_join_time`, must be in the future; can also update `bot_username`, `custom_attributes`) | `PATCH /api/v1/calendar/scheduled_bots/{bot_id}`  |
| Cancel                                                                                                             | `DELETE /api/v1/calendar/scheduled_bots/{bot_id}` |

CLI: `meetstream calendar reschedule <bot-id> <iso8601>` / `meetstream calendar cancel <bot-id>`.

## 2) Calendar event scheduling

Once a [Google Calendar](/guides/calendar-integrations/google-calendar-oauth-setup) or [Outlook Calendar](/guides/calendar-integrations/outlook-calendar-setup) is connected, MeetStream syncs events and detects meeting links (Google Meet, Zoom, Teams, plus Webex, GoToMeeting, BlueJeans, and Whereby links are recognized in events). Schedule a bot for any synced event:

```bash
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` accepts everything `create_bot` does — transcription providers, webhooks, per-participant streams, timeouts.

### Recurring meetings

* `occurrence_date` — schedule one specific occurrence
* `schedule_all_occurrences: true` — schedule every occurrence (capped by `occurrence_limit`, default 52)
* `recurring_event: true` — auto-reschedule the next occurrence after each meeting ends
* `POST /api/v1/calendar/toggle-recurrence` with `{event_id, recurring_enabled}` flips auto-rescheduling per event (400 if the event has no recurrence rule)
* Standard iCalendar RRULEs are supported: daily, weekly, bi-weekly, monthly, yearly

### When the calendar changes

MeetStream listens to real-time push (Google watch channels / Microsoft Graph subscriptions):

* Meeting rescheduled → the bot's join time updates automatically
* Meeting cancelled (or moved into the past) → the schedule is deleted and the bot marked `Cancelled`
* Recurring series edited → existing schedules are rebuilt with the updated times
* Google watch channels are renewed automatically before their \~30-day expiry

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

## 3) Full auto-join

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

```bash
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" } }'
```

Mechanics worth knowing:

* A background job runs every 24 hours (midnight UTC) over events in the next 24 hours.
* Events that already have a bot are skipped (via deduplication keys), so auto-join composes safely with manual scheduling.
* Bots join **1 minute before** the meeting starts.
* 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`.

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](https://fdr-prod-docs-files-public.s3.us-east-1.amazonaws.com/meetstream-ai-573402.docs.buildwithfern.com/1ee65490b1c21be305f066ddfb5f9e686e72533bcbf9288d6e8d26706b2b1aa2/docs/assets/images/dashboard/dashboard-calendar.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIA6KXJSKKNFOCF7G4B%2F20260814%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260814T144058Z&X-Amz-Expires=604800&X-Amz-Signature=f546210b5bdef63eacbd6ccca98afdfccd391d29d548f94c1b7ae6d84ff88037&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject)

## Never double-book a meeting

Scheduling and [deduplication](/guides/features/deduplication-idempotency-keys) are designed to compose:

* Scheduling the same event twice returns `409 Conflict` with the existing bot's ID — change its config 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 replay returns the existing bot (200), and a key reused against a different meeting URL returns 409.
* Retrying the create call safely: use an `Idempotency-Key` header — a replay returns 507 with the original bot and no new charge.

## Next steps

* [Google Calendar OAuth Setup](/guides/calendar-integrations/google-calendar-oauth-setup) · [Outlook Calendar Setup](/guides/calendar-integrations/outlook-calendar-setup)
* [Deduplication & Idempotency Keys](/guides/features/deduplication-idempotency-keys)
* [Webhooks and events](/guides/webhooks/webhooks-and-events) — `bot.scheduled` and the full lifecycle