Python SDK
Official meetbot-sdk on PyPI. Sync + async clients, pydantic v2 models, webhook signature verification. Python 3.10+.
The official Python SDK ships as meetbot-sdk on PyPI (the bare
meetbot name was already taken by an unrelated 2024 project; the
Python import is meetbot). Source is MIT at
github.com/meetbot-dev/meetbot/tree/main/packages/sdk-python.
Install
bash pip install meetbot-sdk bash uv add meetbot-sdk bash poetry add meetbot-sdk Requires Python 3.10+. Sync (MeetBot) and async (AsyncMeetBot)
clients ship in the same package; HTTP transport is httpx.
Auth
from meetbot import MeetBot
mb = MeetBot(api_key="mb_live_…") # explicit
mb = MeetBot() # picks up $MEETBOT_API_KEY| env var | default | purpose |
|---|---|---|
MEETBOT_API_KEY | — | Bearer token. Required if not passed. |
MEETBOT_API_BASE_URL | https://api.meetbot.dev | Override for self-hosted / staging. |
Method reference
All methods on MeetBot have an identical async twin on
AsyncMeetBot (same name, same kwargs, same return type, plus
await).
| Method | HTTP | Returns |
|---|---|---|
dispatch_bot(...) | POST /api/v1/jobs | Job |
get_bot(job_id) | GET /api/v1/jobs/{id} | Job or None (404 → None) |
list_bots(...) | M1.1 | list[Job] |
cancel_bot(job_id) | DELETE /api/v1/jobs/{id} | None |
request_recording_permission(job_id) | POST /api/v1/jobs/{id}/request-recording-permission | RequestRecordingPermissionResult |
pause_recording(job_id) | POST /api/v1/jobs/{id}/pause-recording | RequestRecordingPermissionResult |
resume_recording(job_id) | POST /api/v1/jobs/{id}/resume-recording | RequestRecordingPermissionResult |
stop_recording(job_id) | POST /api/v1/jobs/{id}/stop-recording | RequestRecordingPermissionResult |
leave_bot(job_id) | POST /api/v1/jobs/{id}/leave-call | RequestRecordingPermissionResult |
send_chat_message(job_id, message) | POST /api/v1/jobs/{id}/send-chat-message | RequestRecordingPermissionResult |
verify_webhook_signature(...) (module) | n/a — local | bool |
Example 1 — dispatch + poll until completion
import os
import time
from meetbot import MeetBot
with MeetBot(api_key=os.environ["MEETBOT_API_KEY"]) as mb:
job = mb.dispatch_bot(
external_id="lesson-2026-05-09-pavel",
meeting_url="https://meet.google.com/abc-defg-hij",
display_name="Acme Notetaker",
)
print(f"dispatched {job.id} → {job.status}")
while True:
snapshot = mb.get_bot(job.id)
assert snapshot is not None
print(snapshot.status)
if snapshot.status in ("completed", "failed", "cancelled"):
print("manifest:", snapshot.manifest_uri)
break
time.sleep(5)Example 2 — async dispatch with auto-leave + metadata
import asyncio
from datetime import datetime, timezone
from meetbot import AsyncMeetBot, AutoLeaveConfig
async def main() -> None:
async with AsyncMeetBot() as mb:
job = await mb.dispatch_bot(
external_id="q2-board-meeting-acme",
meeting_url="https://meet.google.com/xyz-abcd-efg",
join_at=datetime(2026, 5, 15, 14, 0, tzinfo=timezone.utc),
display_name="Acme Notetaker",
on_finalize_url="https://api.acme.example/meetbot/finalize",
metadata={"customer_id": "cust_4711"},
auto_leave=AutoLeaveConfig(
after_entry_delay_seconds=300,
after_max_seconds=7200,
on_bot_detected=True,
),
)
print(job.id, job.status, job.join_at)
asyncio.run(main())Example 3 — verify an inbound webhook (Flask)
The signed webhook is the recommended completion signal. Verify before parsing — anyone with your webhook URL could otherwise POST garbage at it.
import os
from flask import Flask, request, abort
from meetbot import verify_webhook_signature
app = Flask(__name__)
WEBHOOK_SECRET = os.environ["MEETBOT_WEBHOOK_SECRET"] # whsec_…
@app.post("/webhook/meetbot")
def meetbot_hook():
raw = request.get_data() # bytes — do NOT use request.json
if not verify_webhook_signature(
body=raw,
header=request.headers.get("X-Meetbot-Signature"),
secret=WEBHOOK_SECRET,
):
abort(401)
event = request.get_json()
if event["data"]["event"] == "job.finalized":
manifest_uri = event["data"]["manifestUri"]
process_recording_async(event["data"]["jobId"], manifest_uri)
return "ok"The same algorithm in JavaScript and Go is at Webhooks: Signature Verification.
Errors
Every SDK exception subclasses MeetbotError. HTTP errors carry both
a numeric status and the orchestrator's machine-readable code:
from meetbot import (
MeetBot,
MeetbotNotFoundError,
MeetbotRateLimitError,
MeetbotUnauthorizedError,
MeetbotValidationError,
)
try:
job = mb.dispatch_bot(external_id="bad", meeting_url="not-a-url")
except MeetbotValidationError as e:
print("validation:", e.body) # {"error": "invalid_input", "issues": [...]}
except MeetbotRateLimitError as e:
print("over quota / rate-limited:", e.status, e.code)
except MeetbotUnauthorizedError:
print("rotate the key at /account/keys")Retry + idempotency
- Transport-level retry: 3x with exponential backoff + jitter on
HTTP 429 / 500 / 502 / 503 / 504 and
httpx.TransportError. HonoursRetry-After. Override viaMeetBot(max_retries=…). - Idempotency: every POST sends an auto-generated
Idempotency-Keyheader. Passidempotency_key=to fix it yourself. - Server-side dedupe:
dispatch_bot()'sexternal_iddoubles as a server-side idempotency key — reposting the sameexternal_idreturns the existing job.
See also
- Bot Quickstart
- TypeScript SDK — same surface in TS
- Webhooks: Signature Verification
- Failure sub-codes
TypeScript / JavaScript SDK
Official @meetbot/sdk for Node.js 22+. Typed HTTP client, webhook signature verification, full surface for the meetbot orchestrator API.
Go SDK (shipping Q3 2026)
Official meetbot SDK for Go. Hand-written ergonomic facade over an oapi-codegen-generated transport. Importable as github.com/meetbot-dev/meetbot/sdk-go.