Idempotency Key Guide for Bot Creation
This guide explains how to use the Idempotency-Key header on the Create Bot endpoint to safely retry requests without creating duplicate bots.
Scope: This feature is currently supported only on
POST /api/v1/bots/create_bot(bot creation). Other write endpoints (PATCH scheduled bots, remove bot, etc.) do not honorIdempotency-Keyyet.
1) Why idempotency matters
When you call the Create Bot API, several real-world conditions can cause your client to retry the same request:
- The network drops mid-request and your HTTP client retries.
- API Gateway returns a 5xx and your retry library kicks in.
- Your worker queue redelivers the same job because the previous worker didn’t ack in time.
- A user double-clicks the “Join meeting” button in your UI.
Without idempotency, every one of these retries would create a new bot — and you’d end up with two, three, or more bots in the same meeting, each consuming credits.
Idempotency-Key solves this: MeetStream remembers the key you sent, ties it to the bot that got created, and replays the original bot’s details on every subsequent retry — never creating a duplicate.
2) How it works (one-paragraph summary)
You generate a unique string per logical bot creation (a UUID is ideal) and pass it in the Idempotency-Key HTTP header. The first request with that key creates a bot normally and returns HTTP 201. Every subsequent request that sends the same key from the same API key/user returns HTTP 507 with the original bot’s details — the request body is ignored, no new bot is created, no credits are charged again.
Keys are scoped per user (the API key owner). The same key value sent by two different MeetStream accounts will not collide.
3) Quick example
First call — creates the bot
Response (HTTP 201):
Retry with the same key — replays the original
Response (HTTP 507):
The bot ID and meeting URL match the original. No new bot was created. No credits were charged. The status field reflects the bot’s status at the time of the replay — so if the bot has progressed from Joining to Active between calls, you’ll see the latest state.
4) The header
Header rules:
- Case-insensitive. Both
Idempotency-Keyandidempotency-keyare accepted. (REST API Gateway preserves casing, HTTP API lowercases — MeetStream handles both.) - Whitespace is trimmed. Leading/trailing whitespace is removed before lookup.
- Whitespace-only values are ignored (treated as if the header was absent).
- No length cap enforced — but keep keys reasonably short. UUID v4 (
9b1c3f4a-7e2b-4d8f-9a1c-2e6f4b8a0c11) is the canonical choice.
If you omit the header, the endpoint behaves exactly as before — every call creates a new bot.
5) Response codes
507 replay response shape
Why
transcript_idisnullon replay: the transcript ID is generated and returned only at original creation time. If you need it later, fetch it from the bot detail endpoint using thebot_id.
6) Rules and guarantees
What MeetStream guarantees
- No duplicate bots from sequential retries. Once a
(user_id, idempotency_key)pair is bound to a bot, every future request with that pair replays the original bot — forever. - Per-user isolation. The same key value used by two different MeetStream accounts will not collide. Keys are scoped to your API key’s user.
- Request body is ignored on replay. If you change the
meeting_link,bot_name, or any other field but send the same key, you still get the original bot back. To create a different bot, use a different key. - Failed creates are not cached. If the original request returned a 4xx/5xx before any bot record was written (validation error, wallet rejection, server error), a retry with the same key will be treated as a fresh attempt.
What MeetStream does not guarantee
- No in-flight (409) detection. If you fire two requests with the same key in parallel before the first one finishes writing to the database, both may create a bot. Subsequent retries will then deterministically resolve to whichever bot the index surfaces first.
- Mitigation: in your client code, serialize retries (don’t fire them in parallel). For UUID-keyed clients this is almost never an issue.
- No key expiration. Keys are bound for the lifetime of the bot record. Never reuse a key for a different logical create — treat each new bot creation as a fresh UUID.
- Lookup fails open. If MeetStream’s internal lookup encounters a transient database error, the request proceeds to create a new bot rather than reject the call. In that very rare case you may see one duplicate bot. This is intentional: we prefer a rare duplicate over refusing legitimate traffic.
7) Best practices
DO
- Generate a fresh UUID v4 per logical create. Use your language’s standard UUID library —
uuid.uuid4()(Python),crypto.randomUUID()(Node),UUID.randomUUID()(Java), etc. - Persist the key alongside your job/queue record before the HTTP call, so a retry uses the same key.
- Treat
507as success. Parse the body and proceed as if you’d just created the bot. - Generate the key on the client that owns the retry loop — typically your worker or the entry point of your background job. The key must survive across retry attempts.
- Use UUIDs, not auto-incrementing integers or timestamps. UUIDs eliminate the risk of accidental collisions when scaling out workers.
DON’T
- Don’t reuse a key across different logical creates. If a user clicks “Join meeting” twice for two different meetings, generate two different keys. If you reuse the same key, the second click will return the first bot’s details (wrong meeting!).
- Don’t fire parallel retries with the same key. Serialize your retry loop.
- Don’t generate the key inside the retry attempt. A new UUID per attempt defeats the purpose. Generate it once, outside the retry loop.
- Don’t rely on the key as a unique identifier in your own system. Use the
bot_idreturned by MeetStream for tracking and lookups.
8) Reference implementations
Python (with requests and tenacity)
Key points:
idempotency_keyis generated once, outside the retry decorator, so all retries share the same key.- Both
201and507are treated as success. - Only
5xxtriggers a retry;4xxerrors fail fast (no point retrying a validation error).
Node.js (with axios and axios-retry)
Worker queue pattern (recommended)
If you’re creating bots in response to a queue message (SQS, Kafka, BullMQ, Sidekiq, etc.), generate and persist the idempotency key when the message is first written, not when the worker picks it up:
If the worker crashes after the HTTP call but before acking the message, the queue redelivers the same job — but the same key replays the original bot. No duplicate.
9) FAQ
Q: Does the idempotency key work for scheduled bots (join_at in the future)?
A: Yes. Idempotency-Key is honored on every call to POST /api/v1/bots/create_bot, including scheduled-bot creations. A retry returns the same scheduled bot’s details.
Q: What happens if I send Idempotency-Key but no Authorization header?
A: The request is rejected at the auth layer before idempotency is evaluated. No key is bound.
Q: Can I look up a bot by its idempotency key later?
A: Not via a dedicated endpoint. The intended use is retry safety, not as a public lookup key. Use the bot_id returned in the response to fetch bot details.
Q: Are keys deleted when a bot is deleted? A: The key lives on the bot record. If the bot record is deleted, the key is gone with it and the same key could be reused. Best practice is still to never reuse keys — always generate a fresh UUID.
Q: Does idempotency-key affect billing?
A: A 507 replay does not charge credits — only the original 201 creation did. Failed creates (4xx/5xx) also don’t charge.
Q: What if my client sends the header with a value of null or an empty string?
A: That’s treated as if the header was absent. Every call creates a new bot.
Q: Is there a maximum number of bots I can bind to one key? A: One. A key maps to exactly one bot. After that, every future request with that key replays that one bot.
10) Related docs
- Create Bot Payload Reference — full list of body fields accepted by
POST /api/v1/bots/create_bot. - First Bot Quickstart — end-to-end walkthrough of creating your first bot.
- Bot Lifecycle Webhook Events — webhook events you’ll receive after the bot is created.
- API reference: https://docs.meetstream.ai/api-reference/api-endpoints/bot-endpoints/create-bot
