Skip to main content

meetstream-migrate

One-command migration from Recall.ai to MeetStream.ai. Scans your codebase, maps every API call, shows the diff, and migrates — safely, with warnings for anything that needs a human look.

v2.1.2 — near feature parity with Recall.ai (verified live against production, July 2026). MeetStream matches Recall across recording, per-participant streams, real-time audio/video/ transcript, chat + image output, Google and Outlook calendar, scheduling, signed-in bots, and retention — plus native AI summaries and MIA voice agents that Recall doesn't have. The only gaps: pause/resume recording and live video output into the call (both shipping soon). See Feature parity & gaps below.


Quick Start

pip install meetstream-migrate
meetstream-migrate scan ./your-recall-project

Commands

# Scan (read-only) — finds every Recall.ai reference, writes NOTHING
meetstream-migrate scan ./your-project

# Dry run — shows exactly what would change, still writes nothing
meetstream-migrate migrate ./your-project --dry-run

# Migrate — applies all transformations (prompts before writing)
meetstream-migrate migrate ./your-project --yes

# Verify your MeetStream credentials + API reachability
meetstream-migrate test --api-key YOUR_MEETSTREAM_API_KEY

CLI reference

meetstream-migrate <command> [path] [options]

Commands:
  scan [path]        Scan only — show what would change
  migrate [path]     Scan & migrate a project
  test                Run API tests against MeetStream.ai

Options:
  --yes, -y          Skip the confirmation prompt
  --dry-run          Show changes without writing files
  --api-key KEY      MeetStream API key (for the test command)
  --verbose, -v      Detailed output
  --help, -h         Show help

What it does

1. Scan — recursively finds:

  • Recall.ai base URLs (us-east-1.recall.ai, eu-west-1.recall.ai, api.recall.ai)
  • API endpoint calls (/api/v1/bot/, /api/v1/bot/{id}/audio/, etc.)
  • Recall-specific field names (meeting_url, recording_mode, transcription_options, metadata, …)
  • Webhook handlers (bot.status_change, joining_call, in_call_recording, call_ended, done, fatal, …)
  • SDK imports (require('recall-ai'), import recall)
  • Environment variables (RECALL_API_KEY, RECALL_API_URL, RECALL_WEBHOOK_SECRET)

Supported file types: .js .ts .jsx .tsx .mjs .cjs .py .go .rb .java .kt .rs .php .cs .swift .env .yaml .yml .json .toml .ini .cfg

2. Display — endpoint mapping table, field mapping table, webhook event mapping, and a compatibility check (auto-migratable vs. needs manual review).

3. Transform — base URL swap, endpoint path rewrites, field renames, webhook event renames, env var renames, import/require updates. Every change carries an inline warning when it needs a second look.

4. Report — what changed, what needs manual review, and a post-migration checklist.


Endpoint Mapping

Recall.ai MeetStream.ai Notes
POST /api/v1/bot/ POST /api/v1/bots/create_bot Field names differ (see below)
GET /api/v1/bot/{id}/ GET /api/v1/bots/{id}/detail Also GET /api/v1/bots/{id}/status
POST /api/v1/bot/{id}/leave_call/ GET /api/v1/bots/{id}/remove_bot ⚠️ Method changes POST → GET
DELETE /api/v1/bot/{id}/ DELETE /api/v1/bots/{id}/delete
GET /api/v1/bot/ GET /api/v1/bots List all bots
GET /bot/{id}/audio/ GET /bots/{id}/get_audio Presigned S3 URL, valid 1h
GET /bot/{id}/video/ GET /bots/{id}/get_video Presigned S3 URL, valid 10min
GET /bot/{id}/transcript/ GET /transcript/{transcript_id}/get_transcript ⚠️ Uses transcript_id, not bot_id
GET /bot/{id}/participants/ GET /bots/{id}/get_participants
GET /bot/{id}/chat_messages/ GET /bots/{id}/get_chats
POST /bot/{id}/send_chat_message/ POST /bots/{id}/send_message REST body { "message": "..." } — drop Recall's to/pin fields
POST /bot/{id}/output_video/ POST /bots/{id}/send_image Public img_url (not base64)
POST /bot/{id}/output_audio/ WebSocket sendaudio command ⚠️ Manual — no REST equivalent, use socket_connection_url bridge
POST /bot/{id}/output_media/ WebSocket bridge (partial) ⚠️ Manual — covers audio + static image today
POST /bot/{id}/pause_recording/ ⛔ Not yet supported (shipping soon)
POST /bot/{id}/resume_recording/ ⛔ Not yet supported (shipping soon)
GET /bot/{id}/screenshots/ GET /bots/{id}/get_screenshots
GET /bot/{id}/speaker_timeline/ GET /bots/{id}/get_speaker_timeline
POST /api/v1/webhook/ callback_url field on create_bot Per-bot, not account-level
GET /bot/{id}/calendar/… POST /calendar/create_calendar (underscore) Body: google_client_id/google_client_secret/google_refresh_token

Field Mapping

Recall.ai MeetStream.ai Notes
meeting_url meeting_link
recording_mode (string) video_required (boolean) "speaker_view"/"gallery_view"true, "audio_only"false
metadata custom_attributes Values must be strings
transcription_options recording_config.transcript.provider.{provider} Object structure differs — see provider config
noone_joined_timeout voice_inactivity_timeout
destination_url webhook_url (nested in live_transcription_required)
assembly_ai assemblyai Also: assemblyai uses speech_models[] + language_code, not model/language
output_media.websocket.url socket_connection_url.websocket_url

Webhook Events — live-verified against production

MeetStream's envelope key is event — the same key Recall uses. No envelope rename needed. Alongside it: bot_id, message, status_code (200 success / 500 failure), custom_attributes, and on lifecycle events, bot_status.

{ "event": "bot.inmeeting", "bot_id": "...", "bot_status": "InMeeting",
  "message": "...", "status_code": 200, "custom_attributes": {} }

Two-layer model: bot.stopped fires once; bot_status tells you whyStopped (normal) / NotAllowed (lobby timeout) / Denied (host denied) / Error (crash). Recall's separate end-reason events collapse into this single event + status.

Recall.ai Event MeetStream event bot_status status_code
bot.joining_call bot.joining (may fire up to 3×) Joining 200
bot.in_waiting_room bot.in_waiting_room InWaitingRoom 200
bot.in_call_not_recording bot.inmeeting InMeeting 200
bot.in_call_recording bot.recording Recording 200
(none — new) bot.leaving Leaving 200
(none — new) bot.error (non-terminal streaming-provider error; bot keeps running) InMeeting — (omitted)
bot.call_ended bot.stopped Stopped 200
bot.call_ended (lobby timeout) bot.stopped NotAllowed 500
bot.call_ended (host denied) bot.stopped Denied 500
bot.fatal bot.stopped Error 500
recording.done manifest.completedaudio.processedvideo.processed (if video_required) 200
transcript.done transcription.processed 200
transcript.failed transcription.failed 500
(post-call) bot.done — post-call providers only Done 200 / 500
(retention) data_deletion 200

Streaming-only providers (deepgram_streaming, assemblyai_streaming, meeting_captions) do not fire transcription.processed/transcription.failed/bot.done — their terminal event is audio.processed. Don't wait on bot.done for a streaming bot, or your handler hangs forever.

transcript_id is never in the webhook payload. Resolve it via GET /bots/{id}/detail (bot_details.transcript_id), the create_bot response, or GET /bots/{id}/transcriptions.

Full bot_status enum: Joining, InWaitingRoom, InMeeting, Recording, Leaving, Stopped, NotAllowed, Denied, Error, Done.

Real-time events

Recall.ai MeetStream Notes
transcript.data / transcript.partial_data delivered to live_transcription_required.webhook_url Chunk shape: { speakerName, timestamp, transcript, words[] }
participant_events.join / .leave same event names, requires recording_config.realtime_endpoints Different payload shape — nested under data.bot.{id,metadata}, no top-level bot_id

Breaking changes to review manually

  1. Transcript retrieval uses transcript_id (from the create_bot response, /detail, or /transcriptions), not bot_id.
  2. recording_mode (Recall string) → video_required (MeetStream boolean).
  3. Chat messages: Recall's separate POST /send_chat_message/ → MeetStream's POST /bots/{id}/send_message.
  4. Webhook registration: Recall registers globally via POST /webhook/; MeetStream uses callback_url per bot at creation.
  5. Webhook event values rename (see table above) — but the envelope key stays event, so most handler code needs a value rename, not a restructure.
  6. Post-call processing arrives as discrete events (manifest.completed, audio.processed, transcription.processed/transcription.failed, video.processed, bot.done) instead of one bot.done-then-fetch signal.
  7. Live transcription: real_time_transcription.destination_urllive_transcription_required.webhook_url on create_bot.
  8. Pause/resume recording has no MeetStream equivalent yet — remove these calls, or segment via remove_bot + re-create.
  9. Output audio/media into the call is REST on Recall, WebSocket-bridge on MeetStream — needs a real refactor, not a rename (flagged, not auto-migrated).

Post-Migration Checklist

  1. Set MEETSTREAM_API_KEY (get one at app.meetstream.ai/api-keys)
  2. Review every ⚠️ warning from the migration output
  3. Update webhook handlers: keep branching on event, rename the values, and check bot_status for bot.stopped's reason
  4. Store transcript_id for transcript retrieval — from create_bot, /detail, or /transcriptions
  5. Add handlers for manifest.completed, audio.processed, transcription.processed/failed, video.processed
  6. Verify the recording_modevideo_required boolean logic
  7. Remove any pause_recording/resume_recording calls (not supported yet)
  8. Run meetstream-migrate test --api-key YOUR_KEY to confirm connectivity

Feature parity & gaps

Recall capability MeetStream Migrator behaviour
Create/list/get/remove/delete bot auto-mapped
Recording (audio/video) + retention auto-mapped
Per-participant streams get_audio_streams / get_recording_streams
Real-time audio/video/transcript live_audio_required / live_video_required / live_transcription_required
Send chat message send_chat_message → REST send_message
Output image/camera frame output_videosend_image (public URL)
Calendar (Google + Outlook) + scheduling calendar/events/{id}/botcalendar/schedule/{id}
Signed-in / OAuth bots Google login domains/logins; Zoom OBF
AI summaries ✅ (MeetStream-only) GET /bots/{id}/summary
Conversational voice agents (MIA) ✅ (MeetStream-only) agent_config_id on create_bot
Output audio / interactive media ⚠️ partial WebSocket bridge (manual, flagged)
Pause/resume recording ⛔ not yet flagged — shipping soon
Live video output into the call ⛔ not yet send_image covers static frames only

Run scan first to see exactly which of these appear in your codebase before migrating.


Requirements

Python ≥ 3.8

Development

pip install -e .
python -m pytest test/    # or: python -m meetstream_migrate.cli test --api-key YOUR_KEY

License

MIT © MeetStream.ai — meetstream.ai · docs.meetstream.ai

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

meetstream_migrate-2.3.0.tar.gz (22.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

meetstream_migrate-2.3.0-py3-none-any.whl (19.7 kB view details)

Uploaded Python 3

File details

Details for the file meetstream_migrate-2.3.0.tar.gz.

File metadata

  • Download URL: meetstream_migrate-2.3.0.tar.gz
  • Upload date:
  • Size: 22.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for meetstream_migrate-2.3.0.tar.gz
Algorithm Hash digest
SHA256 f6c370609389fa35ed9818e59483cafd5c2d3d364bfb75f149bdb1b161334a97
MD5 dda28dc37036fc43775e9ed964d6eb7e
BLAKE2b-256 dc259fae6c6ac3d861f8fc8fdd2cfccfc83705a029f86ea95d909eeab0daabae

See more details on using hashes here.

File details

Details for the file meetstream_migrate-2.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for meetstream_migrate-2.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 47e29ef0c111fc906bf4fd8e962c26d2864d8e6ad38f99132b3d8a595cea91b6
MD5 c972c6a0d2c1e38849495cd780d063a7
BLAKE2b-256 6b36732e6c2faf411d5ddba3cf4e9119cf38b049228e23a96d8753192c41ac5e

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

2.3.0 This release

2 files

1.0.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page