If you've ever sketched out "when my client call wraps, draft a note and file it into the right system automatically," you've probably hit the same wall we did. Every tutorial reaches for a webhook. Webhooks need a public HTTPS endpoint. A public endpoint needs a server, a domain, TLS, and something to keep it alive. Suddenly a one-afternoon automation has turned into infrastructure you have to own, secure, and pay for.
For a solo practitioner or a small team handling sensitive data, that's not a small ask. It's the difference between shipping and never starting.
The good news: for the specific case of "do something after a Zoom recording is ready," you don't need any of it. You can poll. We learned this the hard way while wiring Zoom into legal workflows that ultimately land in Clio, and we want to save you the detour we took.
Why everyone reaches for a webhook (and why it's optional)
Webhooks are genuinely great when you need real-time reaction to an event. Zoom will POST a recording.completed event to your endpoint the moment a cloud recording finishes. n8n, Make, and most automation platforms are built around exactly this model: expose a URL, receive the event, run the flow.
But a webhook is a push. To receive a push, you have to be reachable from the public internet. That's the entire source of the infrastructure burden. You're not hosting a server because your automation is complex; you're hosting it because Zoom needs somewhere to knock.
Polling flips the direction. Instead of waiting to be knocked on, you ask. A small local process calls GET /users/me/recordings on a schedule, sees what's new, and acts. There's no inbound connection, so there's no public endpoint, no server, and no firewall hole. It runs from a laptop, a mini PC in the office, or a single always-on machine.
The trade you're making is latency for simplicity. And here's the part that makes the trade free: the data you're waiting for isn't ready instantly anyway.
The transcript latency that makes polling a non-issue
When a Zoom call ends, the cloud recording and its transcript are not immediately available. Zoom has to process the recording and run audio transcription. In our testing, the realistic rule of thumb is roughly twice the meeting length. A 30-minute consult can take around an hour before the VTT transcript is retrievable through the API.
Sit with that for a second. If your output depends on the transcript, the absolute fastest a webhook could fire useful work is an hour after the call. A poller running every 10 to 15 minutes adds, at worst, 15 minutes to a process that already takes an hour. The "real-time" advantage of webhooks evaporates the moment a transcript is in the loop.
So the honest engineering call is: if your workflow needs the transcript, poll. You give up nothing meaningful and you delete an entire category of infrastructure and security work.
One prerequisite to confirm up front: cloud recording must be turned on (it's a paid Zoom feature, not available on free accounts) and audio transcription must be enabled in the account settings. No cloud recording, no transcript, no automation. Check the tier and the toggle before you write a line of code.
Make the VTT transcript your backbone, not the AI summary
This is the gotcha that cost us the most time, so we'll be blunt about it.
Zoom's AI Companion produces a tidy meeting summary, and it's tempting to build your whole pipeline around pulling that summary through the API. Don't make it your foundation. Two reasons:
1. The read scope is blocked for Server-to-Server apps. If you build a Server-to-Server (S2S) OAuth app, which is the clean, install-once, account-wide choice for transcripts, you cannot read the AI Companion summary. That scope requires a General or Account-Managed OAuth app instead. So the very app type that's easiest for transcripts can't get the summary.
2. Summaries auto-delete. AI Companion summaries expire after about 30 days. If your process ever falls behind or you need to reprocess history, the summary may simply be gone.
The reliable backbone is the VTT transcript from the cloud recording. It's a plain timestamped text file, it's there as long as the recording is, and you control it. Treat the AI summary as a best-effort nicety: use it if it's available, and if it isn't, summarize the VTT yourself with whatever model you're already using. Build for the transcript and the summary becomes a bonus instead of a single point of failure.
Which Zoom OAuth app type should you actually pick?
This is a diagnostic, not a one-size answer. The right choice depends on what your workflow needs:
- Just transcripts and recordings? Use a Server-to-Server OAuth app. One admin installs it once, it works account-wide, and there's no per-user login dance. For "poll recordings, grab the VTT," this is the cleanest path.
- Must have the AI Companion summary through the API? Then you need a General or Account-Managed OAuth app, because S2S can't read that scope. Accept the extra setup, and still keep the VTT as your fallback.
The mistake is choosing the app type by default and discovering the scope limitation after you've built around it. Decide what data you actually depend on first, then pick the app type that can deliver it.
Closing the loop: getting the result back into Clio
Pulling a transcript is only half a workflow. The output has to land somewhere useful, and for a law firm that usually means the practice management system: Clio, MyCase, PracticePanther, or similar. This is where a second set of platform realities matters, and where we've done the most building.
A few things we've confirmed working with the Clio Manage API and our own connector:
- Uploading a document is a two-step presigned-S3 flow, not a single POST. You create the document record, PUT the file bytes to the
put_urlClio hands back, then PATCH it asfully_uploaded. Get any step out of order and the file never lands. Our connector wraps this so the upload "just works," but if you're rolling your own, expect three calls, not one. - There's no
documentwebhook in Clio. If you wanted to react to a new document appearing, you can't subscribe to that event. You detect new documents by polling or by watching thematterupdatedwebhook. The polling theme keeps coming back for a reason: it's often the only option, and it's fine. - Throttle hard. Treat the Clio API as roughly 3 requests per second per app, honor the
X-RateLimit-*headers, and back off cleanly on a 429. This isn't a service you can hammer.
The shape of the full pipeline, then, is simple and entirely local: a poller watches Zoom for a finished recording, pulls the VTT transcript, your model drafts the document, and the connector uploads it into the right matter. No webhook, no public endpoint, no hosted middle tier. Tools like n8n can orchestrate the steps if you prefer a visual flow, but the polling approach means even a plain scheduled script does the job.
If the data is sensitive, local-first is a feature, not a compromise
For legal and healthcare work, "no public server" isn't just an engineering convenience. It's a privacy posture. The fewer places sensitive client data lives, the smaller your exposure. A local poller that pulls a transcript, drafts a note, and files it, all from one machine, keeps the data off third-party automation servers entirely.
Two related points worth knowing if your pipeline involves a model:
- Zero Data Retention is available on the API, not on team chat plans. If you're using Anthropic's Claude, ZDR is an org-level setting obtainable on the API even for a small firm, and the API doesn't train on your data by default. The consumer and Team chat products are a different story. Pick the surface deliberately.
- Watch data residency. Zoom offers a Canadian data center, but AI-content residency isn't guaranteed Canada-only, so the safe pattern is pull-and-store-fast rather than relying on where Zoom keeps it. Claude has no Canadian region and processes US-side at rest, which for Canadian firms under PIPEDA means a cross-border disclosure you should document rather than hide. None of that blocks the build; it just needs to be stated plainly.
And the non-negotiable for legal work: keep a human in the loop. The Law Society of Ontario's 2024 guidance and ABA Opinion 512 both land in the same place, lawyers must verify AI outputs, can't outsource professional judgment to a model, and can't bill AI time as lawyer hours. So the last step of any pipeline like this should hand a draft to a person for review, never auto-finalize. Automate the mechanical assembly; preserve the judgment.
The takeaway
If your automation reacts to a Zoom recording, you almost certainly don't need a webhook or a server. Poll the recordings API locally, build on the VTT transcript instead of the fragile AI summary, pick your OAuth app type by what data you actually need, and respect the rate limits and presigned-upload flow on the system you're writing back into.
We learned most of this by building it wrong first. Our open-source Clio and MyCase MCP connectors exist because we kept hitting these exact walls and decided to package the answers. If you're a small firm or a legal network trying to automate the same workflow across several people without standing up infrastructure for each one, that's the kind of build we do.
The honest framing: this isn't about whether AI can draft your consult note. It's whether the trigger fires reliably, the prompt is consistent, the file lands in the right matter, and the same setup replicates across your team without a server babysitter. That's the part worth getting right.
Building Zoom-to-Clio or Zoom-to-MyCase automation for a firm?
We build local-first legal automation that respects data residency and keeps a human in the loop, and we maintain the open-source Clio and MyCase MCP connectors that close the loop into your practice management system.
Book a call