Webhooks integration
MeetStream webhooks push every step of a bot's life to your endpoint the moment it happens: dispatch, lobby, admission, recording, how it left.
What you get with webhooks
Each post-call artefact is pushed as it lands, so nothing waits on a timer.

The bot lifecycle reaches your endpoint as it happens, with the reason.
Audio, transcript and video, each sent as it becomes ready to fetch.
Subscriptions, a signing secret and a delivery log, all in the dashboard.
For tenant routing, with your own attributes echoed in every event.
Deliveries from a workspace endpoint carry HMAC-SHA256 signatures and timestamps, and the CLI has a listen command for work on your own machine.
Why webhooks and not polling
The moments that matter in a bot's life are changes of state, and each one has a reason attached.
The full lifecycle, event by event
| Lifecycle step | When it fires | Notes |
|---|---|---|
| Scheduled | A scheduled bot is confirmed | Fires when you book a join time. The payload carries that time |
| Dispatched | The bot is on its way to the meeting | Fires up to three times when you turn on join retries |
| In the waiting room | The bot asked to join and is waiting | Under Meet host management, hosts and co-hosts see the request |
| In the meeting | The host admitted the bot | Exactly once per bot |
| Recording allowed | The Zoom host granted recording | Zoom only |
| Recording declined | The Zoom host declined or the prompt timed out | Zoom only. The bot then leaves and closes cleanly |
| Recording | Capture began | On Meet and Teams this follows admission within about a second |
| Leaving | The bot is on its way out | Comes just before the final event on graceful exits |
| Final event | The bot is gone | Exactly one of the five outcomes below |
Why did the bot leave the meeting?
Five outcomes, one event each, so your product can say what actually happened.
- Route on the event nameA removed bot and a clean exit share one status, and the event name tells them apart.
- Map them to your wordingThen people see the real reason a bot left.
- The exact namesThe webhook events guide lists every one.
| Outcome | Cause | Status code |
|---|---|---|
| Clean exit | The meeting ended, the API stopped the bot, a timeout hit, or the host ended the call | 200 |
| Removed | The host or another participant removed the bot | 200 |
| Join declined | The host turned down the join request | 500 |
| Lobby timeout | The lobby or waiting-room timeout ran out | 500 |
| Ended early | The session ended before the bot finished the call | 500 |
Post-call events for every artefact
Once the bot leaves, the audio, transcript and video are prepared. Each one reports in as it is done.
The mixed recording and the per-participant audio are ready to fetch.
The post-call transcript is ready. Streaming engines deliver text live instead.
The MP4 and the per-participant video are ready to fetch.
One says every artefact is finished. One says media has expired, so cached links can be dropped.
Fetch each artefact on its own event rather than waiting for the completion event.
Store your media in your own S3 bucket to keep it as long as you like.
What a webhook payload contains
Route on the event name, and read the status code beside it.
- 200 or 500A success or a clean exit reads 200. Every other outcome reads 500, with a message naming the cause.
- Your own attributesAnything you set when you create the bot comes back in every event.
- Multi-tenant routingThat is how a product sends each delivery straight to the right customer.
{
"bot_event": "bot.inmeeting",
"bot_id": "6667fd0c-0165-471a-a880-06a1180be377",
"bot_status": "InMeeting",
"message": "Bot successfully joined the meeting",
"status_code": 200,
"timestamp": "2026-02-27T07:11:51.863543+00:00",
"custom_attributes": { "tenant": "acme", "env": "prod" }
}Webhook delivery guarantees
| Guarantee | What MeetStream promises |
|---|---|
| Delivery | Best-effort. Every event is sent once, at the moment it happens |
| Uniqueness | Admission and the final event fire exactly once per bot. Post-call events fire at most once each |
| Ordering | Lifecycle events are sent in order. Post-call artefact events arrive as each one becomes ready |
| Repeats | Dispatch repeats up to three times when join retries are on |
Design for the first row. Reply fast, process later.
Keep the bot status endpoint as your fallback for any delivery that lands while your service restarts. Talk to us about retry and delivery terms for your workload.
Enterprise-level security, keep your data private.
The certificate, the audit status and the Trust Center are all on the security page.
MeetStream is ISO 27001 certified. SOC 2 Type 2 is under audit rather than complete.
MeetStream is GDPR compliant, and bots run in the United States by default.
Workspace endpoints issue a signing secret once, at creation.
Build a reliable webhook handler
Respond with a 2xx at once, so a slow system of your own still receives every event.
On deliveries from a workspace endpoint.
Final events close the session, and each artefact event triggers its own fetch.
Keep the bot, the event and the timestamp together, then drop duplicates.
Poll bot status for any session that has gone quiet past your own timeout.
Register endpoints: per bot or for the workspaceWorkspace webhooks guide: request, response and options in the docsSigning and verification
Every delivery carries a signature header holding the HMAC-SHA256 of the raw request body, and a timestamp header in ISO 8601 form.
Work out the HMAC again over the exact bytes you received and compare in constant time. Accept only what falls inside your tolerance window.
The verification guide has the header names and reference code.
Got a question? We got the answer.
Common questions about webhooks. Event names, delivery, signing and how to build a handler.
Which events does MeetStream send?
The lifecycle runs from scheduled to dispatched, waiting room, admitted, recording, the two Zoom recording-permission events, leaving, then one final event out of five.
After the call you get one event each for audio, transcript and video, a completion event and a deletion event.
The webhooks guide lists the exact names.
Are webhooks retried if my endpoint is down?
Delivery is best-effort, so each event is sent once at the moment it happens.
Reply with a 2xx straight away and do the work afterwards.
Keep polling on bot status as a fallback for anything that has to land.
How do I know a webhook really came from MeetStream?
Signing comes with workspace endpoints, so set one up in the dashboard and you get a signing secret.
Each delivery then carries a signature header, an HMAC-SHA256 of the raw body, plus a timestamp header.
Work out the HMAC with your secret and compare the two.
Can I set one endpoint for everything?
Yes. A workspace endpoint in the dashboard receives every event you subscribe to, for every bot you run.
Per-bot callback URLs still work for tenant routing, and your own attributes travel in every event.
In what order do post-call events arrive?
The audio, transcript and video events arrive in any order, each at most once.
A completion event fires when every artefact is finished. Fetch each on its own event and the order stops mattering.
Why did the join event fire more than once?
Join retries. The dispatch event fires up to three times when you turn retries on.
Admission and the final event fire exactly once per bot, so key your state on those two.
How do I test webhooks locally?
Run the listen command in the MeetStream CLI.
Or open a local server behind a tunnel such as ngrok and point the bot callback at that URL.
The dashboard Logs tab shows every recent delivery.
Every step of the call, at your endpoint.
Point an endpoint at MeetStream, send a bot to a test meeting, and watch every event arrive.
Wire your first webhook in ten minutes
Point an endpoint at MeetStream, send a bot to a test meeting, and watch every event arrive.