Deduplication & Idempotency: Never Double-Book a Meeting Bot
Retry create_bot safely and guarantee one bot per meeting, even when your workers crash, time out or run twice.
Both are optional. If you omit them, every call creates a new bot.
Scope
Idempotency-Key:POST /api/v1/bots/create_botonlydeduplication_key:POST /api/v1/bots/create_botandPOST /api/v1/calendar/schedule/{event_id}
Platform support
Both checks run in the API before the bot is dispatched, so they behave the same on every platform. See the capability matrix for platform-specific features.
At a glance
For every request field, see the create_bot API reference.
deduplication_key (request body)
Pass a string in the JSON body to say: “for this account, this key should always map to the same bot.”
Example: first create
Response (HTTP 201):
Example: repeat with the same key and meeting
Response (HTTP 200):
Same bot_id as the first call. No new bot. No extra credits.
The repeat response has the same shape as a fresh create, with two differences: transcript_id is always null, and status is the bot’s current status (for example InMeeting, or Stopped if that meeting is over). Fetch transcript_id from GET /api/v1/bots/{bot_id}/detail if you need it.
Example: same key, different meeting (error)
If you reuse a deduplication_key with a different meeting_link, MeetStream returns HTTP 409:
This is deliberate: it surfaces a client bug instead of silently joining the wrong meeting. The comparison is an exact string match against the link stored on the bot, so send the link in the same form every time (for example, do not add or drop the ?pwd= part of a Zoom link between calls).
Field rules
Good key choices: calendar event ID plus occurrence start time, CRM opportunity ID, internal job ID, user_id + meeting_start_time.
Avoid: timestamps that change on every click, auto-increment integers shared across workers without coordination, and a bare recurring-event ID. Keys never expire, so reusing a series ID for next week’s occurrence returns last week’s finished bot instead of creating a new one.
Calendar scheduling
deduplication_key also works on POST /calendar/schedule/{event_id}. Put it in bot_config:
A repeat returns HTTP 200 with the existing scheduled bot (bot_id, schedule_id, scheduled_time). Separately, scheduling an event that already has a scheduled bot returns HTTP 409 with "error": "A bot is already scheduled for this event". See scheduling bots.
Idempotency-Key (HTTP header)
Pass a unique string in the Idempotency-Key header to safely retry the same HTTP request without creating duplicate bots.
Example
- First call:
HTTP 201 - Retry with the same header:
HTTP 507with the original bot (treat as success)
The 507 body:
status is the original bot’s current status. A repeat returns the original bot even if the rest of the body changed (the body still has to pass basic request validation).
Generate one UUID per logical create attempt, persist it across retries, and accept both 201 and 507 as success.
Using both together
You may send both on the same request. MeetStream checks Idempotency-Key first, then deduplication_key.
Typical pattern:
deduplication_key: a stable business ID for this meeting (survives across days and re-schedules)Idempotency-Key: one UUID for this logical create, reused by every retry of it
Which one should I use?
Best practices
DO
- Generate one UUID v4 per logical create:
uuid.uuid4()(Python),crypto.randomUUID()(Node),UUID.randomUUID()(Java). - Persist the key alongside your job or queue record before the HTTP call, so a retry reuses the same key.
- Treat
507(and200fordeduplication_key) as success: parse the body and proceed as if you just created the bot. - Generate the key on the client that owns the retry loop (your worker, or the entry point of your background job) so it survives across attempts.
DON’T
- Don’t reuse a key across different logical creates. Two different meetings → two different keys, or the second call replays the first bot (wrong meeting).
- Don’t fire parallel retries with the same key. Serialize your retry loop (there is no in-flight race protection).
- Don’t generate the key inside the retry attempt: a new UUID per attempt defeats the purpose. Generate it once, outside the loop.
- Don’t rely on the key as an identifier in your own system. Track by the
bot_idMeetStream returns.
Reference implementations
Python (requests + tenacity)
Node.js (axios + axios-retry)
Worker-queue pattern (recommended)
Generate and persist the key when the job is enqueued, not when the worker picks it up, so a redelivered message reuses the same key:
If the worker crashes after the HTTP call but before acking, the queue redelivers the job, and the same key returns the original bot. No duplicate.
Shared guarantees and limits
Both mechanisms share these behaviors:
- Per-account isolation: the same key value used by two different MeetStream accounts does not collide.
- No protection against parallel first calls: two simultaneous first creates with the same key may both succeed, and there is no
409for a request still in flight. Serialize retries in your client. - Failed creates are not remembered: if the original request failed before the bot was created (validation error, low balance, and so on), a retry runs as a fresh create.
- The lookup fails open: on a rare internal lookup error, MeetStream creates the bot rather than blocking the request.
- Keys never expire: a key stays bound to its bot for good. Generate a new key for each distinct logical create.
FAQ
Q: Does a replay charge credits? A: No. Only the original successful create charges credits.
Q: Can I look up a bot by deduplication_key or Idempotency-Key later?
A: Not via a dedicated API endpoint. Use the bot_id returned in the response.
Q: What HTTP codes should my client treat as success? A:
- With
Idempotency-Keyonly:201and507 - With
deduplication_keyonly:201and200 - With both:
201,200, and507
Q: Why 507 for a repeat?
A: It is MeetStream’s signal that nothing new was created. Many HTTP clients treat 5xx as an error or retry it automatically, so allow 507 explicitly (as in the examples above) and do not retry on it.
Q: Does deduplication_key work for scheduled bots (join_at)?
A: Yes, on POST /api/v1/bots/create_bot with a future join_at, and on calendar schedule endpoints.
Q: What if I omit both? A: Every call creates a new bot, same as before these features existed.
Related docs
- create_bot API reference: the
Idempotency-Keyheader and all request body fields - Scheduling bots:
join_at, calendar scheduling and auto-join - Google Calendar OAuth setup and Outlook Calendar setup
- HTTP errors from create_bot
