Kamil DzikowskiCTO · AI-Era Engineering · Advisory

EN PL
Case Study · Data Governance

Otter.ai is being sued for what it did with your meetings. Read AI has been banned by universities. Here's what I built instead — and why.

My calendar has a growing list of recurring meetings across multiple organisations — daily standups, weekly partner syncs, leadership reviews — and I cannot be in all of them. The obvious fix is a meeting notetaker. The obvious choices turned out to be a legal and governance problem, not a convenience — so I built my own, self-hosted, with the audio and transcript never leaving infrastructure I control. This is why, what it cost, and where the line actually sits between "I did this for myself" and "I could do this for your company."

The trigger

"Read the transcript later" isn't a system — it's a hope. What I needed was narrow: find out what happened in a meeting I wasn't in, get my action items into my own tracker, and never think about it again. That's a search for a notetaker. What I found looking at the market changed the decision entirely.

What's actually happening to companies that used the obvious tools

This isn't a hypothetical privacy concern. It's active litigation and institutional bans, and it's worth reading the primary sources rather than taking my word for it.

Otter.ai — a federal class action, consolidated December 2025

Four lawsuits filed against Otter.ai between August and September 2025 were consolidated into one federal class action in December 2025. The allegation isn't just "it recorded without consent" — it's that Otter used those recordings to train its own speech-recognition models, and that it structured its terms so customers, not Otter, carry the legal responsibility for getting attendees' consent. The claims span the federal Electronic Communications Privacy Act, California's Invasion of Privacy Act, and Illinois's Biometric Information Privacy Act — statutes with damages of up to $10,000, $5,000, and $5,000 per violation respectively, against a user base Otter itself put above 35 million. A motion-to-dismiss hearing was held in May 2026.
Read the analysis — Workplace Privacy Report → · UC Today's coverage →

Read AI — banned outright, not merely criticised

Chapman University investigated Read AI and prohibited its use, citing security, privacy, and institutional data risk. The University of Washington's IT department issued a required deactivation notice. The specific mechanic both flagged: once connected to a calendar, Read AI can join, transcribe, and summarise meetings the account holder isn't even attending — without the awareness or consent of the other people in the room.
Chapman University's notice → · University of Washington IT →

Read AI says it doesn't train on meeting content unless a customer opts in, and offers workspaces where that's contractually impossible. Take that at face value — it still leaves the actual question untouched:

A privacy policy is a promise about behaviour. Self-hosting is a fact about architecture. Policies get revised, companies get acquired, and a promise you skimmed in an email six months ago can change. The question isn't whether you trust them today — it's whether there's anywhere for this to go wrong once you've handed it over.

And no policy fixes the bigger problem: you cannot un-share a transcript. My standups routinely cover live security-incident status, a regulator's position, staffing constraints. None of that belongs in someone else's bucket, under someone else's future decisions.

What I built

A self-hosted meeting bot, on my own infrastructure, that joins Google Meet calls it's invited to, reads the transcript, and delivers a summary and my own action items straight into the tools I already use — no audio or transcript ever leaves my network, and no cloud transcription service is in the loop at all. Attendee, an open-source project, joins the call. Everything after that — summarising, routing to my task list, delivery to the right chat — is mine.

The capture technology isn't proprietary. Attendee is open source (Elastic License 2.0 — free to run internally, can't be resold as a hosted service). Any competent engineering team could build the shape of this. The build notes further down are what it actually took.

The design is two halves joined by one deliberately thin handoff — a transcript plus a calendar event id, nothing else crosses the line:

Capture Real Chrome joins the meeting, reads Google's own captions
→ transcript + event id →
My tools Summarise → Todoist tasks → Telegram, in the right project's chat

That thin handoff is what makes the capture side swappable — Attendee today, something else tomorrow — without touching anything downstream.

What it actually gets you, beyond "the data stays put"

ApproachTranscription costWhere your data goes
Hosted meeting-bot API (e.g. Recall.ai) ~$0.50 + $0.15/hr Their cloud
Otter.ai / Read AI / similar Bundled in subscription Their cloud — see above
This setup — platform captions $0, any volume Never leaves my network
Transcription cost only — the Workspace seat itself is a fixed cost either way, not usage-based.

Costs and limits

If this is a live question for your company

If your team has looked at Otter, Read AI, Fireflies, or similar and something about "an outside company sees our meetings" doesn't sit right — that instinct is correct, and it's exactly what I look at in an Engineering Velocity Audit or a technical due diligence engagement: where your data actually goes, what it costs you if it goes wrong, whether a self-hosted alternative is worth the engineering effort for your size and risk. No price here — a company rollout is a different build from what I run for myself. Scope it on a call.

If this is a live question for your company, let's talk about what your data exposure actually looks like.

I read every message and reply personally.


Want to see it, not just read about it? Here's what it actually looks like day to day — the bot in a real meeting, a real notes output, and how it plugs into the tools I already use.

How it works

Invite the bot's account to a calendar event and that's the whole interface — no dashboard, no app to open. It shows up on the guest list, joins on time by itself, and sits in the meeting like any other participant:

The self-hosted meeting bot, named 'Kamil's Notetaker', shown as a participant tile inside a live Google Meet call
The bot inside a live call — a normal participant tile, muted, named clearly so nobody mistakes what it is.

Behind that tile: it reads Google Meet's own live captions (no audio leaves the network), and when the meeting ends, a summariser turns the transcript into structured notes — what happened, what was decided, what's blocked, and what's actually mine to do. Here's a real one, with names swapped for the write-up:

A real meeting-notes message delivered to Telegram: title, short summary, highlights, decisions, and action items with an owner and due date
Delivered straight to Telegram — one message per meeting, so I can react to that specific one.

The part that actually saves time isn't the summary — it's what happens to it next. Action items that are genuinely mine become real tasks, with a due date, filed under a label I can filter on across every project:

A Todoist view filtered to the meeting_notes label, showing tasks generated from meetings with due dates and status
Every meeting-derived task carries a meeting_notes label — one filter, every project, nothing to hunt for.

Rules I could only add because I own the pipeline

A hosted vendor summarises for their median customer. Mine only has one reader, and that shows up as actual rules in the prompt, not settings in a menu:

It also works while the meeting is still running

The transcript is readable live, not just after the call ends — so a question like "what's been discussed so far?" gets answered from what's actually been said, mid-meeting, without me being in the room. I tested this exact thing while writing this piece: asked what had been said in a call I wasn't attending, and got the real answer back before the meeting even finished.

"So how is yours any safer?"

Fair question, and the right one to ask anyone making this argument. Building it yourself doesn't automatically make it safe — it makes the security posture yours, which is only an improvement if you actually do something with it. What that means concretely here:

What self-hosting does not buy you: a vendor's security team, their audit history, or their patch cadence. You're taking that on. For meeting content specifically, I'll make that trade every time — but it is a trade, not a free upgrade, and anyone selling it as free hasn't run one in production.

Build notes: where the time actually went

None of the time went where you'd expect. Standing up the containers took an afternoon. Everything below is what came after — real dead ends, in the order they cost me a day each. If you're weighing "we could just build this ourselves," this is the list to read first.

1. A signed-in meeting bot doesn't use a password

This is the one that surprises people. A bot that joins Google Meet as a real signed-in account authenticates over SAML — your capture server acts as an identity provider, Google redirects to it, it signs an assertion with a private key. Three consequences fall out of that, none of them optional: the bot must live on a paid Workspace account (a consumer Google account has no admin console and literally cannot host the profile); it must not be an admin (Google lets super-admins bypass SSO, so an admin bot never triggers the flow at all); and the SSO profile you create redirects sign-in for everyone it covers — scope it wrong on a live company domain and you lock real staff out of their own accounts.

That last point is why mine runs in a throwaway tenant on a domain nobody depends on. It costs one seat and removes the only genuinely dangerous step in the build. On a client's production identity system, that decision is not one to get wrong on a Friday.

2. The bug that ate a day: a cookie flag

First SAML attempt failed with an unhelpful login error. Google's side was fine — it was returning a perfectly valid assertion request. The actual cause: the capture server marks its session cookie Secure by default, Chrome refuses to store a Secure cookie over plain HTTP, so the cookie silently vanished and sign-in failed for lack of it. One setting fixed it. Nothing in any log said "cookie."

The upside discovered along the way: Google accepted an http:// sign-in URL without complaint, so no TLS termination or certificate work was needed at all.

3. Being in the right domain doesn't get you into the meeting

Anonymous joining simply doesn't work for a Workspace-hosted Meet — you get a flat "You can't join this video call" with no ask-to-join button. What actually admits the bot is being on the calendar guest list. And there's a trap inside that: if an organiser has set "guests can't invite others," adding the bot via the API returns success and Google silently discards it. No error, no bot, and nothing to tell you why until the meeting starts without it.

4. The bot that kept joining and leaving in front of everyone

For a while the bot would join, vanish, rejoin — several times, visibly, in front of the room. Root cause: a dialog's close button was being clicked while it was still animating, which throws "element not interactable." Upstream classified that as a retryable join failure, so every failed click restarted the entire join instead of retrying the click. Three failures in a two-minute window before it settled. The fix was a JavaScript click instead of a native one — two lines, once you know that's what you're looking at.

5. Operational edges you only learn by hitting them

What's next — and what I haven't built

Meet's captions are free and fast, but they handle one language at a time with no auto-detect — a real limit for teams that mix languages mid-sentence, which is common running teams across several countries. That's a genuine opening to do better than the platform itself: run the audio locally through a speech-to-text model like Whisper instead of (or alongside) captions, and you get auto-detection and real code-switching handling that Meet's own captions simply don't offer, still without any audio leaving the network. I haven't built that layer for myself — the setup above runs on captions alone — but the architecture already leaves room for it, and it's exactly the kind of extension I'd scope in for a team that genuinely operates across languages.

Want to talk through what a version of this looks like for your team?

I read every message and reply personally.

← Back to case studies