> 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.

# Migrate from Recall.ai

> Move an existing Recall.ai integration to MeetStream.ai. The migration kit rewrites endpoints, fields, and webhook handlers automatically and flags anything that needs manual review.

MeetStream is a near drop-in replacement for Recall.ai at a lower price point — roughly 30% less per hour, and about half at volume. The migration kit does the mechanical rewrite for you and tells you exactly what — if anything — needs a human.

## What it does

Point the tool at your existing Recall.ai project and it works in four passes:

1. **Scan** — recursively finds Recall base URLs, endpoint calls, field names, webhook handlers, SDK imports, and `RECALL_API_KEY` usage.
2. **Map** — prints endpoint, field, and webhook mapping tables so you can see every change before it happens.
3. **Transform** — rewrites base URLs, endpoint paths, field names, webhook event handling, env vars, and imports.
4. **Report** — summarizes what changed, warns on anything that needs manual review, and prints a post-migration checklist.

Run it in `scan` or `--dry-run` mode as many times as you like — nothing is written until you confirm.

## Install & run

#### Node.js

```bash
# Scan only — no changes
npx @meetstream/migrate scan /path/to/your-recall-project

# Dry run — see the full diff
npx @meetstream/migrate --dry-run /path/to/your-recall-project

# Migrate (asks for confirmation first)
npx @meetstream/migrate /path/to/your-recall-project

# Verify against the live API after migrating
npx @meetstream/migrate test --api-key YOUR_MEETSTREAM_API_KEY

# Full lifecycle test against a real meeting
npx @meetstream/migrate test --api-key YOUR_KEY --meeting-url https://meet.google.com/xxx-xxxx-xxx
```

#### Python

The Node CLI above is the reference implementation and is always current — we recommend it even for Python codebases, since it edits files in place regardless of language. A Python package (`meetstream-migrate`) is published on PyPI and is being brought up to match the latest release.

```bash
pip install meetstream-migrate

# Scan only
meetstream-migrate scan /path/to/your-recall-project

# Dry run
meetstream-migrate migrate /path/to/your-recall-project --dry-run

# Migrate
meetstream-migrate migrate /path/to/your-recall-project --yes

# Verify against the live API
meetstream-migrate test --api-key YOUR_KEY
```

## What gets rewritten

### Endpoints

| 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 `/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`                       |                                               |
| `GET /bot/{id}/video/`              | `GET /bots/{id}/get_video`                       |                                               |
| `GET /bot/{id}/transcript/`         | `GET /transcript/{transcript_id}/get_transcript` | Uses `transcript_id`, resolved from `/detail` |
| `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`                   | Body `{ "message": "..." }`                   |
| `POST /bot/{id}/output_video/`      | `POST /bots/{id}/send_image`                     | Public `img_url` (not base64)                 |
| `GET /bot/{id}/speaker_timeline/`   | `GET /bots/{id}/get_speaker_timeline`            |                                               |
| `POST /api/v1/webhook/`             | `callback_url` on `create_bot`                   | Webhooks are per-bot                          |

### Fields

| Recall.ai               | MeetStream.ai                 |
| ----------------------- | ----------------------------- |
| `meeting_url`           | `meeting_link`                |
| `recording_mode`        | `video_required` (boolean)    |
| `metadata`              | `custom_attributes`           |
| `transcription_options` | `recording_config.transcript` |
| `noone_joined_timeout`  | `voice_inactivity_timeout`    |
| `assembly_ai`           | `assemblyai`                  |
| `destination_url`       | `webhook_url`                 |

### Webhooks

Recall's global webhook becomes a per-bot `callback_url` passed to `create_bot`, and Recall's string events map onto MeetStream's event model. The event envelope key is `event`, and bot completion is two-layered (`bot.stopped` carries a `bot_status` such as `Stopped`, `NotAllowed`, `Denied`, or `Error`). Before finalizing your handlers, read the **Webhooks and Events** guide (Guides → Webhooks), or have your assistant call the `webhook_events_guide` tool on the [MeetStream MCP server](https://docs.meetstream.ai/build-with-ai/meetstream-mcp-server).

## Feature parity & gaps

As of **v2.1 (June 2026)** MeetStream matches Recall.ai across recording, per-participant audio/video streams, real-time audio/video/transcript, chat and image output, Google **and** Outlook calendar, advance scheduling, signed-in bots, and retention — and adds native AI summaries and MIA voice agents that Recall does not have.

The migrator explicitly flags the two remaining gaps, both shipping with the video launch:

* **Pause / resume recording** mid-call
* **Live video output** into the meeting

Everything else migrates automatically.

## After migrating

1. Swap `RECALL_API_KEY` for `MEETSTREAM_API_KEY` in your environment and secrets manager.
2. Change the auth header to `Authorization: Token <your-key>`.
3. Point webhooks at your handler via `callback_url` on `create_bot`.
4. Run `test --api-key ...` (optionally with `--meeting-url`) to confirm the live API responds as expected.
5. Review anything the report flagged for manual attention.

#### [npm — @meetstream/migrate](https://www.npmjs.com/package/@meetstream/migrate)

#### [PyPI — meetstream-migrate](https://pypi.org/project/meetstream-migrate/)

Prefer to drive MeetStream from a chat assistant instead of rewriting code by hand? The [MeetStream MCP server](https://docs.meetstream.ai/build-with-ai/meetstream-mcp-server) gives Claude direct access to the same API.