Every candidate at Wynisco gets weekly 1:1 coaching — interview prep, resume work, project deep-dives. Five to six instructors. Around three hundred sessions a month.
For a long time, recordings lived in instructors’ personal Zoom accounts. Transcripts were a manual export. Summaries were whatever a human remembered to write down.
We knew we had to fix it. The fix we almost shipped was the wrong one.
The seductive option
In 2026, if you Google “record and transcribe coaching calls,” you end up at Recall.ai. One API, joins any meeting on any platform, returns a structured transcript and event stream. We built against it for two weeks. The integration was clean. The demo worked.
Then we did the math.
At three hundred recordings a month — and growing — Recall landed at roughly $100/month and climbing. Not catastrophic. But the curve was wrong: every new instructor and every new candidate cohort pushed the number up. And there was a UX thing that kept nagging at us.
“Wynisco Notetaker has joined the meeting.”
That line appears in front of a candidate who is already nervous about a mock interview. Their first thirty seconds should be the instructor’s face. Not a third-party service disclaimer.
We pulled the Recall branch before it shipped.
What we shipped instead
Two Zoom Business seats. $44 a month. Flat.
Zoom Business includes AI Companion — native meeting summaries, no extra integration, no extra bill. The well-known catch: one Zoom user can host one meeting at a time. Six instructors on one seat means one concurrent session. One instructor per seat means six seats.
So we built a seat pool.
The seat pool
We own two Zoom accounts: host-1@wynisco.com and host-2@wynisco.com. Both carry Business + AI Companion. Every coaching session gets created against one of them via Server-to-Server OAuth.
When an instructor books a session, the backend asks one question:
Which seat has no overlapping booking in this window?
First free seat wins. If both are taken, the booking is rejected and the UI shows the next open slot.
Zoom Business allows two concurrent meetings per host. Two seats means up to four concurrent sessions — which covers our peak load comfortably, since half the instructor team is always doing async work at any given time.
The booking constraint lives in two places on purpose:
Frontend: the scheduler hides conflicting slots. Instructors never see them.
Backend: same constraint, enforced as source of truth. The frontend can lie. The backend can’t.
That’s the architecture. One database column and an hour of code.
The three flags that matter
Every session we create has these set:
Flag | What it does |
|---|---|
| Recording starts itself — nobody has to remember |
| Candidate isn’t staring at “waiting for host” if the instructor is two minutes late |
| AI Companion fires the moment the call begins |
We learned all three the hard way during testing. Obvious in hindsight. Everything is.
Webhooks — and the one that lies
Zoom sends three webhooks per session:
meeting.ended→ mark session completerecording.completed→ store the recording linkmeeting.summary_completed→ pull the AI Companion summary
The first two are reliable. The third one is not. AI Companion sometimes finishes and never fires the event.
So we run a 24-hour polling fallback: if a session ended yesterday and we still don’t have a summary, ask Zoom directly. This sounds unsophisticated. It is the difference between 95% reliability and 100%.
Never trust a webhook to be the only path. We write it on the wall every sprint.
What we deliberately didn’t ship
We had a more ambitious plan: a custom GPT-4o-mini summarization layer generating two versions of every session summary — a warm, encouraging one for the candidate and a blunt one for managers, flagging missed commitments and candidates not doing the homework.
We cut it.
The reason: we wanted to validate the full loop before adding our own prompt surface. Custom prompts drift. They need evaluations. They need an owner. Shipping Zoom’s native summary first tells us whether instructors and managers open the summary at all — before we spend three weeks tuning something nobody uses.
The dual-summary code is still in the branch. Dormant. Not deleted. We’ll turn it back on when we have signal that the manager view is getting used.
The numbers, cleanly
What we shipped | ||
|---|---|---|
Monthly cost | ~$100, usage-based | $44, flat |
Bot visible in meeting | Yes | None |
Custom summarization | Yes | Not yet (by choice) |
Pipeline drift risk | Medium | None |
Integration complexity | Medium | Low |
The honest lesson
The most useful thing we did this sprint was delete a service we’d already integrated.
Shipping a custom pipeline is easy to take credit for. Not shipping one is harder — it means noticing that the platform you’re already paying for has the feature, and that the real work is wiring a webhook and writing twenty lines of seat-allocation logic.
If you’re looking at this problem in 2026: check whether your video platform already does this. If it does, the work is glue. If you genuinely need a meeting bot — your sessions run on five different platforms, or you need to extract something the platform won’t expose — you’ll know. Otherwise, the boring answer is probably right.
We’ll revisit when one of two things happens: AI Companion’s accuracy on Indian-accented English stops being good enough, or we start running sessions on Meet and Teams. Until then, the system that’s running is the system we want.
Session recording is live in SMO, Wynisco’s internal coaching tool used by instructors and managers to run candidates through the US and Canadian job market.
Written by
Mohammad Tauqeer
