audio.{speaker}.webm
One Opus track per participant. WebRTC SSRC-keyed, name-tagged from the meeting roster. No mixing.
01 · meeting bot api
shipping today$0.30/hr flat. Per-speaker audio, captions, chat — to your bucket. POST a Google Meet, Microsoft Teams, or Zoom URL; get clean recordings back via signed webhook.
overview
This is what we ship today. A single REST endpoint that takes a meeting URL and returns a job id. Behind it: a Bun + Drizzle orchestrator dispatches a Puppeteer-driven Chrome bot inside a Docker container, the bot joins the meeting as a regular guest tile, captures per-speaker audio off the WebRTC SSRC mapping, scrapes captions (or reads the Meet data channel where it exists), and uploads everything to the S3-compatible bucket you nominated when you created your account.
When the host leaves, the bot is kicked, or the meeting ends, you get a single signed webhook with the manifest path. No proprietary container format. No "log into our portal to download." Files live in your bucket, on your retention policy, under your KMS keys. We bill by the meeting-minute, not by the meeting — a 17-minute call is 8.5 cents.
Anti-bot is the thing nobody else talks about. We run a rotating pool of Workspace bot accounts to clear Google's April-2026 dual-queue admit screen. Each retry uses a stealthier Chrome fingerprint via tier-escalation in the Trigger.dev task config — no custom retry loops, no flaky for-loops around fetch. The bot containers are single-purpose and ephemeral.
what you get back
One Opus track per participant. WebRTC SSRC-keyed, name-tagged from the meeting roster. No mixing.
VP9 tab capture via x11grab. What a viewer would see, including shared screens. Configurable bitrate.
Newline-delimited JSON, one row per finalized utterance with speakerId + start/end ms.
Inbound meeting-chat messages, sender-attributed and timestamped. Same shape across Meet/Teams/Zoom.
Index of every file plus participant roster, meeting metadata, sub-code on exit, and a content hash per artifact.
Signed webhook (HMAC-SHA256 over the body) when the manifest is uploaded. We retry on non-2xx with exponential backoff via the queue.