Undervid Privacy Policy
Last updated: 2026-10-01
Undervid records a product call on your Mac, transcribes it, finds the visual moments behind deictic feedback ("make this bigger"), and turns the call into a brief a coding agent such as Claude Code or Codex can act on. If you connect Zoom, it can also bring in Zoom meetings and stream a live meeting's transcript to your coding agent.
This policy describes what Undervid actually does with your data. It is written against the behaviour of the shipping code, not against an aspiration. Where a data flow only happens if you turn it on, this policy says so explicitly.
The short version: capture is local-first. Your screen recording, audio, and transcript stay in your own macOS Application Support directory. Nothing about a meeting is analyzed in the cloud until you choose a specific action that sends a specific, inspectable payload. Analysis uses your own API key and goes straight from your Mac to the provider you chose.
1. Who we are
Undervid ("Undervid", "we", "us") provides
the Undervid macOS app, the local MCP connector
(undervid-mcp) that ships inside it, the optional Zoom
Realtime Media Streams (RTMS) relay, and the website at
undervid.rackmind.ai. Undervid is a RackMind product.
The website distributes only the macOS app. The source repository also contains an Electron review companion for other platforms; it is frozen and not distributed, so this policy does not describe it.
For data you record with Undervid, you are the controller and Undervid is a processor. You decide which calls to record, which participants are present, and which evidence, if any, leaves your machine. Undervid does not run an account system, and there is no paid subscription today: no sign-up, no payment processing, and no billing data of any kind (see §9).
2. What Undervid captures
When you start a local capture on macOS, Undervid uses Apple's ScreenCaptureKit to record:
| What | Detail |
|---|---|
| Screen frames |
The display you select, at that display's native resolution,
at up to 30 frames per second, written to a local
screen.mp4.
|
| System audio | The audio playing on your Mac, which is how remote participants' voices are captured. Undervid's own process audio is deliberately excluded. |
| Microphone | Your own microphone, on macOS 15 and later, recorded as a separate track so that "you" and "the call" stay attributable. |
| Transcript | A timestamped, speaker-attributed transcript derived from those audio tracks. |
| Session manifest | Timing, display dimensions, track filenames, and integrity digests (SHA-256) of the artifacts. |
| Consent record |
A consent.json beside each recording: the time you
confirmed that everyone on the call was told, whether that was a
standing "don't ask again" confirmation, and the
app version. It records your claim; Undervid cannot verify it.
|
| Evidence artifacts | Candidate evidence moments, the selected evidence document, and the individual frames cited by it. |
| Analysis results | If you analyze a meeting: the grounded feedback, the meeting summary, and the implementation brief built from them. A meeting's name in your library is the first topic of its model-written summary. |
| Repository snapshot (optional) | If Undervid is launched with a repository path configured, it records that repository's local root path, current commit SHA, and branch name, so a brief can be tied to the code it describes. This is local metadata about your own working copy; no source code is read or copied. |
Undervid does not capture keystrokes, clipboard contents, browser history, individual window contents outside the recorded display, or your cursor and click stream. Of the recording itself it takes the display's pixels and the audio, nothing more. When Undervid shows a visual-change hint on a frame, it is derived from the frames themselves; it is never labelled as a cursor or a click, because no capture adapter currently provides that evidence.
There is exactly one thing Undervid observes outside a recording, and it
is stated here rather than left to be discovered. While the macOS app is
open it reads the
frontmost application's name and bundle identifier about once a
second
(MeetingReadiness), so it can offer to record when a
meeting app comes forward and so the prompt can name it. That reading is
held in memory only to decide what the prompt says: it is never written
to disk, never attached to a recording or an export, never included in
diagnostics, and never transmitted. Nothing else about your other
windows, your other applications, or their contents is read.
Names and words
Under Settings › Words you can list names and terms that come up in your meetings (products, clients, teammates), so they are heard and spelled right. The list is stored in this Mac's app preferences. It is used in two places: on-device transcription is biased toward those terms, and the terms are added to the analysis prompts in §5, so they go to your analysis provider whenever you approve an analysis. Leave the list empty and nothing is added.
Where it lives
Local sessions and exports are written under your own user account:
~/Library/Application Support/Undervid/Sessions/<session-uuid>/
~/Library/Application Support/Undervid/Exports/<session-uuid>/
Undervid has no cloud media library. There is no "all your recordings" server. If you delete the local directory, the local copy is gone.
Imported recordings
If you use Import recording (MP4/MOV/M4V) or Add transcript (VTT/SRT), Undervid normalizes that file locally into the same session artifacts. The import is a local file operation; importing does not upload anything.
3. Permissions Undervid asks for
- Screen Recording — required by macOS for ScreenCaptureKit. Without it there is no capture.
- Microphone — required to record your own voice as a separate track.
- Speech Recognition — required by macOS before Apple Speech may transcribe your audio.
Each of these is a standard macOS permission that you grant and can revoke in System Settings at any time.
4. Transcription
Default: Apple Speech, pinned to on-device
By default Undervid transcribes using the macOS built-in speech
recognizer (SFSpeechRecognizer). Every recognition request
sets requiresOnDeviceRecognition = true, and Undervid
checks
SFSpeechRecognizer.supportsOnDeviceRecognition before it
starts. If macOS has no on-device model for the session's locale,
transcription fails with an explanation rather than
falling back to Apple's speech servers:
macOS has no on-device speech model installed for
<locale>. Undervid will not send this recording to Apple's speech servers instead. Install the language under System Settings › General › Language & Region, or import an existing transcript.
This is the fail-closed direction on purpose. On the default path your audio is handed to the operating system on your own machine and to nothing else. Your Words list (§2) is passed to the recognizer as hints on this Mac.
Optional: speaker labels (diarized transcription), off until you turn it on
Undervid can produce speaker-labelled transcripts that Apple Speech cannot. This path uploads the complete system-audio track, and the complete microphone track when one was recorded: whole files, not excerpts. It is the largest thing Undervid can send. The screen recording never leaves the Mac on this path.
It is off on every fresh install, and a stored API key is never
treated as consent.
The switch is Speaker labels under
Settings › Privacy, and it only appears on a Mac where
a remote route actually exists. The opt-in is a persisted per-machine
value under the UserDefaults key
ai.undervid.transcription.remoteRoute; absence of that
value means off. Turning it off returns transcription to on-device
immediately. While it is on, the analysis dialog says so and offers to
turn it off.
Two routes exist, and the disclosure differs:
| Route | Who receives the audio | Requires |
|---|---|---|
| Hosted (the only route a shipping build offers) | Undervid's own hosted transcription service, part of the relay Undervid operates on Railway, which then calls ElevenLabs Scribe v2 with a key held server-side. Undervid's operator and Railway can technically see the audio while the request is in flight. |
The opt-in above, a uv1_ device credential issued
after you connect Zoom, and a relay host compiled into the build
|
| Direct ElevenLabs (personal development only) |
api.elevenlabs.io/v1/speech-to-text straight from
the Mac, under your own ElevenLabs account and terms
|
The opt-in set to that route, an
ai.undervid.elevenlabs Keychain key you installed
yourself, and
UNDERVID_LOCAL_ELEVENLABS=1 in the process
environment. A normally launched app has none of these
|
What the hosted route does with the audio. The track is
sent as a raw audio/mp4 request body to
POST {relay}/analysis/transcribe, authenticated with your
device credential. The relay holds it in process memory for the duration
of that one request, forwards it to ElevenLabs, and writes nothing to
its disk. A track over the relay's 64 MiB body ceiling is refused
on your Mac before the upload starts, so the bytes
never leave.
Failure never strands a meeting. If the remote request
fails, or returns a well-formed response with no speech in it, Undervid
discards the result, transcribes on-device instead, and writes the
reason to transcription-diagnostics.txt beside the session.
What the client does not check. The hosted route is
offered only when this Mac holds a uv1_ device credential,
which exists only after Zoom is connected. The client does not ask the
relay whether transcription is configured before an upload. If the relay
has no transcription key, an opted-in track is still uploaded, answered
with 503 transcription_unavailable, and transcribed
on-device instead.
Do not turn this on unless you have the consent and the contractual basis to send that meeting's audio to Undervid's service and, through it, to ElevenLabs.
5. Analysis: what leaves the device, who receives it, and only when you ask
5.0 Which mode is live, and who the recipient is in each
Analysis runs under a signed policy the app fetches
from the relay at launch (§6) and verifies on the device with an Ed25519
key compiled into the app. The policy the relays serve is
mode: byok, issued 2026-08-19 and valid to 2027-08-19.
Bring your own key (live). You paste an API key for
Anthropic, Google Gemini or
OpenAI under Settings › API keys. The
key is stored in the macOS Keychain as a this-device-only,
non-synchronizing item, one item per provider, and the app never shows
it again. Analysis then goes from this Mac
straight to that provider
(api.anthropic.com,
generativelanguage.googleapis.com or
api.openai.com) in one hop, billed to your own account
there and handled under that provider's terms. Undervid's relay
is not in that path and does not see the payload. With no key installed,
the app asks you to add one, and nothing leaves the Mac.
Hosted (supported by the code, not live). The policy
can be switched to hosted without a new build. In that mode
evidence frames, transcript windows and the full transcript do
not go from your Mac to a model provider. They go first
to Undervid's own hosted analysis service, part of
the relay Undervid operates on Railway, which then
calls Google's Gemini API with a key Undervid holds server-side. Two
parties would therefore see what you approve, not one, and the first of
them is us. The app says so before it sends anything: its privacy screen
reads "Screenshots and transcript go to Undervid's server,
which sends them to Google Gemini. Both can see them." We will
update this policy before switching the live policy to
hosted.
What the hosted mode does, if it is ever switched on:
- Retention at the relay: none. Frames, transcript windows and transcript text exist in the relay's process memory for the duration of the one request that carried them. Nothing from the analysis routes is written to the relay's disk. Its logs carry byte counts, a hashed subject prefix and spend counters, never transcript text, frame bytes, an API key, or your device token.
-
Spend ceiling, not a plan. Because each call spends
real money, the relay enforces two hard daily ceilings: 120 requests
per credential and 600 for the whole service by default, counted
before the upstream call and reset at UTC midnight, persisted at
<RTMS_DATA_ROOT>/.analysis/daily-spend.json. Exceeding one returns429withdaily_limit_credentialordaily_limit_service. There is no subscription, no plan and no paywall behind these numbers; see §9. -
A credential is required. Hosted analysis
authenticates with the same
uv1_device credential the relay issues after you connect Zoom. Without one, the app says "Connect your Zoom account to send to<relay host>."
Which relay. A Release build addresses only
undervid-relay.rackmind.ai and refuses rather than falling
back to the development deployment. A Debug build defaults to the
Railway development deployment
(media-relay-development.up.railway.app). A build with no
relay host compiled in says "This build has no relay set up.
Nothing leaves this Mac."
Capture, on-device transcription, evidence extraction, export, the local rules-based summary, and the MCP connector's library tools all keep working with no key and no credential at all.
5.1 Evidence analysis ("Key moments")
After a meeting is exported, Undervid can analyze it. It sends one candidate per request, at most 16 candidates for a meeting, each containing:
- the selected frames for that candidate, inlined as images (at most 8 frames, 16 MiB decoded), and
- the aligned transcript window for that candidate (the surrounding speech, not the whole call; the hosted route caps it at 20,000 UTF-16 code units), plus the trigger phrase, the time range, and the normalized visual-change hint.
Under bring-your-own-key the request also carries Undervid's
instructions to the model, the bundle-relative names of the attached
frames (frames/<name>.jpg), and your
Words list if you set one.
It does not send screen.mp4, your other
frames, your other candidates' transcript, your repository contents,
filesystem paths, or your account identifiers. On the hosted route, the
relay rejects any unrecognized top-level field and names
recording-shaped keys explicitly in its refusal.
You can inspect the exported bundle on disk before analyzing it. That is the point of exporting a bundle rather than streaming a session: the payload is a reviewable directory, not a hidden request.
5.2 Meeting summary ("Full transcript")
If you explicitly approve the Full transcript pass, Undervid sends the complete timestamped transcript text of that session (capped at 350,000 UTF-16 code units), plus the already-grounded requested-change lines as a wording aid and your Words list if you set one, in a single request. No frames and no audio are sent on this path.
This is the one analysis flow where the whole transcript leaves the device, and it is separately approvable for exactly that reason. The Analyze this meeting? dialog gives each pass its own checkbox, names the provider, says who pays, and counts the moments, screenshots and transcript lines before anything is sent. The Full transcript box starts unchecked: approving key moments alone is the default answer, and it does not send the transcript, because the approved set is what is passed down into the analysis run rather than assumed. Every combination is a real answer: the full transcript alone constructs no evidence request and sends only the transcript; untick both and there is nothing to send, so the button is disabled. If you choose Not now, or leave the transcript box empty, Undervid produces a local, rules-based summary instead and nothing is transmitted on this path.
5.3 Which actions can reach a provider at all
Only four things in the app can start an outbound request that carries meeting content, and each has its own gate:
| Action | What it can send | Gate |
|---|---|---|
| Analyze in the Analyze this meeting? dialog | Evidence candidates, then the full transcript if that pass was ticked | Your approval for that meeting, re-checked against the verified policy when you give it |
| Retry for moments that did not finish | The candidates that failed the first time | The same approval: a retry is a second request, not a continuation |
| The summary that follows analysis | The complete transcript | The Full transcript pass specifically; otherwise the local rules-based summary is used |
| Preparing the dialog (runs right after a recording or an import) | The complete audio tracks, if Speaker labels is on | The separate persisted opt-in in §4, which is off by default, and nothing else |
The last row is worth reading twice. It is not a button: the app prepares the dialog as soon as a recording or import is ready, so that the dialog can state real counts instead of guesses, and it transcribes the meeting to do so. With the §4 opt-in off, its default, that transcription is Apple Speech on this Mac and nothing is uploaded. With the opt-in on, the complete audio tracks are uploaded at that moment, before you have answered the analysis dialog. Nothing else about the analysis passes happens then: no frame and no transcript reaches an analysis provider until you approve a pass.
Approvals are per meeting and held in memory only. They are never persisted: an approval is a decision about one meeting at one moment, and quitting the app forgets it. Reopening a meeting never sends anything; analyzing it again asks again.
5.4 Analysis diagnostics
Analysis writes a candidate-scoped
analysis-diagnostics.json next to the report so a failed or
partial analysis is auditable. It stays on your machine.
6. Connected Zoom capture (RTMS relay)
Undervid can optionally receive a Zoom meeting through Zoom's Realtime Media Streams instead of recording your local screen. This path is opt-in, requires Zoom OAuth, and requires the Zoom account to allow it.
What Zoom sends the relay: per-participant audio, speaker-attributed transcript segments, and desk-share frames at roughly 1 frame per second, each carrying Zoom's own timestamp.
What Zoom tells participants: the relay is not a meeting bot and does not appear as a participant. Instead, the Zoom account must enable "Share realtime meeting content with apps." The meeting host retains approval, and Zoom presents its own in-meeting disclosure to participants that meeting content is being shared with an app. Undervid depends on Zoom's disclosure mechanism here; we do not suppress, bypass, or replace it.
Ownership and access control: every RTMS session is
stamped with the Zoom account ID and Zoom user ID at the moment the
signed meeting.rtms_started webhook is accepted. Listing a
session, reading its files, following it live, and deleting it all
require a match on both identity values. The administrative bearer token
is an operator escape hatch and is disabled for desktop sync by default.
Device credentials: Zoom OAuth issues a short-lived,
single-use desktop exchange ticket (two minutes), which is exchanged for
a 90-day revocable uv1_ device credential.
Only the SHA-256 digest of that credential is stored
server-side: the relay cannot reproduce your token. On your Mac it is stored as a
this-device-only Keychain item. The app's interface never displays
it.
Retention: completed relay sessions are deleted after
RTMS_RETENTION_HOURS, which
defaults to 24 hours, enforced by an hourly sweep. The
relay is staging, not storage. The relay will not accept Zoom media
until a storage encryption key (RTMS_DATA_ENCRYPTION_KEY)
is configured. While a meeting is live its files are written to the
relay's volume as they arrive; when the meeting ends, its files are
encrypted at rest with AES-256-GCM. Session-level bookkeeping metadata
is kept in the clear so retention and deletion can operate.
Deletion on request: deleting a meeting in the app (Move to Trash) deletes the owner-scoped relay session first, then the local copy. The local artifacts go to Finder's Trash so an accidental deletion is recoverable by you.
Integrity before visibility: the app verifies byte counts and SHA-256 digests of the transcript and every cited frame before a synced session becomes visible. An incomplete or corrupt relay session is skipped and never creates a meeting.
What runs on a timer once you connect Zoom. Connecting is a deliberate action, but what it starts is continuous, so it belongs in this policy rather than in a footnote. The app's privacy screen says: "If you connect Zoom, finished meetings download from Undervid's relay every 30 seconds while the app is open."
Concretely, these outbound requests happen without a per-meeting action:
-
The analysis-policy fetch. One credential-free
GET {relay}/policy/analysisat every launch, and again if you press Try again under Settings › API keys. It carries no query string, no body, no cookies and aUser-Agent: Undervidwith no version in it, and it fetches a public, signed document that is identical for every install; nothing about you or this Mac is sent. This relay request runs before Zoom is connected. -
The update check. At most once every 24 hours while
the app is open, one plain
GET https://undervid.rackmind.ai/release.jsonfrom the website (not the relay). No query string, no body, no cookies, no credential, and the same versionlessUser-Agent. The version comparison and the signature check happen on the Mac, and Undervid never installs anything by itself. Turn it off with Check for updates under Settings › Privacy. -
The readiness check. One credential-free
GET {relay}/readywhen you choose Connect for Zoom, before any browser window opens, asking whether that relay is set up for Zoom sign-in. It carries no body, no credential and nothing about any meeting; if the relay says no, Undervid refuses with a sentence naming the host and opens nothing. -
The credential exchange. One
POST {relay}/auth/exchangeafter Zoom sign-in, carrying the one-time ticket, the sign-in verifier described below, and a device label, and returning theuv1_credential. The label is deliberately not your machine's name, which on a personal Mac is usually a person's name: it isUndervid for Macplus four characters drawn once from this device's random generator, such asUndervid for Mac (a3f9), so you can tell two of your own devices apart and nobody else learns anything from it. -
The session-sync poll. A
GETto the relay's session list every 30 seconds while the app is running, and when you press Check now under Settings › Zoom. It carries your device credential in anAuthorizationheader, plus downloads of the artifacts of any completed session. It transmits no meeting content from your Mac; it is a request for content the relay already holds. Before Zoom is connected there is no credential, and no request is made.
The undervid:// callback is bound to a flow you
started
Zoom sign-in finishes in your browser and returns to the app through a
undervid://zoom-connected link. That link is only acted on
when it carries the
connect code the app generated when you pressed Connect: 256 bits from the system random generator, kept in memory, valid for
ten minutes, and usable once. A callback with no code, an unknown code,
an expired code, or a code that has already been used is refused
before any request is constructed, so a link from a web page,
an email, or a chat message cannot make Undervid contact the relay or
adopt a credential. The relay carries that code sealed inside its own
OAuth state, so it is never handed to Zoom in the clear.
The sign-in is also bound to the app that started it (PKCE, RFC 8252).
The app keeps a one-time secret verifier and sends only its SHA-256 hash
when sign-in starts. The relay seals that hash into the exchange ticket
and refuses to exchange the ticket unless the same verifier is
presented. A wrong or missing verifier does not use up the ticket. So
another app that intercepts the undervid:// link cannot
turn it into a credential for your Zoom account.
Live meeting transcript
While a Zoom meeting is being captured, the relay can stream its
transcript as it happens to a Mac holding your device credential:
GET {relay}/sessions/live lists your meetings that are live
now, and
GET {relay}/sessions/<stream-id>/live streams their
transcript lines. Both are owner-scoped like every other session route,
and a revoked credential ends the stream. Only the MCP connector calls
them, and only while you or your coding agent runs it (§7). On that path
the transcript flows from the relay to your Mac; the request carries
your credential, the stream id, and on a reconnect the id of the last
line received, and nothing about the meeting is sent up.
Deleting a meeting also calls the relay, to remove the owner-scoped server copy before the local one. If this build has no relay host configured, or you never connect Zoom, none of the credentialed requests in this section is ever constructed.
7. The MCP connector and your coding agent
Undervid ships a local MCP server, undervid-mcp, so a
coding agent (Claude Code, Codex) can search your meeting library,
retrieve a compact context pack, inspect a cited screenshot, and expand
a transcript range. Those library tools run on your machine and read
local files. They do not upload any meeting. Whatever
your agent then does with the context it receives is governed by that
agent's own provider and its privacy terms.
Connecting an agent edits your agent's configuration.
Settings › Agents › Connect runs that agent's own
command (claude mcp add or codex mcp add) to
register undervid-mcp in your user configuration. For
Claude Code it also installs the /undervid-live skill at
~/.claude/skills/undervid-live/.
Disconnect removes both. Nothing else in your
agent's configuration is touched.
Following a live meeting. If Zoom is connected,
undervid-mcp tail --live (which the
/undervid-live skill arms for you) follows the meeting the
relay is capturing and prints one line per transcript segment for your
agent to read. With --write it also saves the transcript to
a file you name, created readable only by you (by default the skill uses
~/Undervid/live/<date>.jsonl). An MCP tool,
live_sessions, lists which meetings are live. The connector
only contacts the relay while that command runs or that tool is called,
never in the background, and it uses the requests described in §6.
Requesting screen context. The
read_live_screen MCP tool and the connector's
screen --stream … --timestamp-ms … --out … command retrieve
up to three captured screen-share images within five seconds of a
requested Zoom transcript timestamp. They run only when called. The
request to
GET
{relay}/sessions/<stream-id>/screen-context?timestampMs=<timestamp>
carries the device credential, stream ID, and requested timestamp.
Images flow from the owner-scoped relay capture to your Mac; no image is
uploaded to an analysis provider by this command. The MCP tool returns
images to your connected coding agent, whose provider terms govern its
use of them. The CLI saves images privately in the output directory you
specify; those local copies remain until you delete them. Following the
transcript alone does not request images, and the connector does not
automatically interpret phrases such as “what is that?” as permission to
send images.
Optional: the live meeting filter, off until you turn it on.
With
tail --live --watch "<what matters to you>", the connector sends rolling windows of the live transcript (the lines
being judged, up to twelve earlier lines for context, and your own
description of what matters)
from this Mac straight to Anthropic
(api.anthropic.com, model claude-haiku-4-5),
signed with your own Anthropic key and billed to you, and prints only
the moments it flags. No audio, no frames, and no Undervid relay in that
path. It runs only when all four of these are true, checked on every
run: --watch is on the command line; you turned on
Live meeting filter under
Settings › API keys (stored as
ai.undervid.liveWatch.route, off on every fresh install; a
stored key is not consent); the signed policy, fetched and verified on
that run, is byok and allows Anthropic; and your Anthropic
key is installed. If any is missing, the command says which and follows
the meeting unfiltered.
How the connector reads secrets. To follow a live
meeting it reads the device credential from the Keychain, and with
--watch it also reads your Anthropic key. It reads them in
its own process through Security.framework, never by running
/usr/bin/security, and never prints them. Only the compiled
undervid-mcp binary inside the app can read the Keychain;
the first time, macOS asks you to allow undervid-mcp. A
release build of the connector talks only to
undervid-relay.rackmind.ai and ignores the
UNDERVID_RTMS_URL override, so another program cannot point
it, and your credential, at a different server.
8. Diagnostics
If you export diagnostics (Settings › Privacy › Export diagnostics), the file contains only:
- schema version and creation timestamp
- app version and operating system platform
- whether capture is available, and the current pipeline stage
- the count of recent meetings
- whether Zoom is connected and available in this build, and the last Zoom sync error message if there was one
It contains
no tokens or credentials, no transcript text, no screenshots, and no
meeting titles.
It is written with owner-only file permissions (0600), and
it is written to a location you choose. Undervid does not transmit it:
you decide whether to send it to us.
9. Accounts and payments: neither exists
Undervid has no account system and no payments. There
is no sign-up, no subscription, no plan, no entitlement, no quota tied
to a plan, and no paywall. There is no payment processor: the code
contains no Stripe integration and no billing code of any kind, and the
relay never answers 402 or 403. Under
bring-your-own-key, your analysis provider bills you directly under your
own account with them; Undervid never sees or handles that billing.
The only identity in the product is the Zoom account you connect for the relay, and the only identifier derived from it is a SHA-256 digest of your Zoom account and user IDs, used server-side to key the hosted daily spend ceiling in §5.0 so that reissuing a device credential does not reset it.
If Undervid is ever sold, this section and §10 must be rewritten in the same commit as the code that implements it, not before.
10. Sub-processors and other recipients
Listed by when your data reaches them. Under the live bring-your-own-key policy, analysis goes from your Mac to the provider you chose, and no Undervid server is in that path.
| Recipient | Purpose | What it can see | Retention | When |
|---|---|---|---|---|
| Your analysis provider: Anthropic, Google (Gemini API) or OpenAI (your choice, your account) | Runs the model for evidence analysis and the meeting summary; Anthropic also runs the live meeting filter | Selected frames + aligned transcript window, or the full transcript text on the summary pass, plus your Words list; for the live filter, rolling windows of live transcript text. Sent directly from your Mac | Per that provider's terms, under your own account |
Only after you approve an analysis, or while
tail --live --watch runs with the filter turned on
|
| Undervid relay (first party, operated by us) | Zoom RTMS capture and sync, the live transcript stream, the analysis policy, and hosted transcription | Zoom meetings it receives (audio, transcript, shared-screen frames); complete audio tracks on the hosted transcription path, in memory only; request metadata such as IP address |
Zoom meetings: up to RTMS_RETENTION_HOURS, default
24 h. Transcription: in memory for one request
|
Policy fetch at every launch; everything else only if you connect Zoom or turn on Speaker labels |
| Railway | Hosts the relay | The same content as the relay, as its infrastructure provider; relay files at rest, encrypted with AES-256-GCM once a meeting ends | Same as the relay | Whenever the relay is used |
| ElevenLabs | Runs Scribe v2 for speaker-labelled transcription | The session's complete audio tracks, forwarded by the relay | Per ElevenLabs' terms | Only after the persisted Speaker labels opt-in in §4 |
| Zoom | Connected RTMS capture | The meeting it already hosts, plus the RTMS stream it originates | Per Zoom's terms | Only if you enable connected Zoom capture |
| Cloudflare | Hosts the website, the app download, and the update file | Standard web request metadata (IP address, user agent, the file requested). No meeting content and no credential | Per Cloudflare's terms | When you visit the site or download the app, and on the daily update check |
| Google (Gemini API), through Undervid (hosted mode only) |
Would run the model if the policy were switched to
hosted (§5.0)
|
Selected frames + aligned transcript window, or the full transcript text, forwarded by Undervid's relay with Undervid's key | Per Google's API terms | Not active under the live policy |
If you never connect Zoom, never turn on Speaker labels, never approve an analysis, and never run the live filter, no one but you sees any part of your meeting.
Undervid's operator can technically read what passes through the
relay; the guarantee is that analysis and transcription content is not
stored, not logged, and not used for anything but the one request.
Before the policy is ever switched to hosted, the
GEMINI_API_KEY the relay would use must sit on a tier whose
terms exclude training on submitted content, because that content would
flow through Undervid's account rather than each user's.
We will update this table before adding a recipient that can see customer content.
11. What we do not do
- We do not maintain a cloud copy of your recordings.
- We do not use your meeting media, transcripts, or evidence bundles to train models, ours or anyone else's.
- We do not sell or rent your data, and we do not share it with advertisers or data brokers.
- We do not silently upload media or an evidence bundle. Every outbound content flow in §4, §5, §6 and §7 is behind a deliberate user action or a persisted opt-in.
- We do not use meeting audio for voice cloning or synthesis.
- We do not market to you, profile you, or run analytics, telemetry, or crash reporting anywhere in Undervid, including the website.
12. Your responsibility: participant consent
You are responsible for the legality of your recordings. Undervid records people who are speaking to you, which in many jurisdictions requires the informed consent of every participant, not just yours. Some jurisdictions require all-party ("two-party") consent as a matter of criminal law.
Before you record, you must:
- tell every participant that the call is being recorded and transcribed, and obtain their consent;
- comply with the recording-consent law of every jurisdiction the participants are in;
- honour a participant's request to stop recording or to delete a recording; and
- have a lawful basis for sending any part of a meeting to an analysis provider under §5 or §7, or to ElevenLabs under §4, when that meeting contains someone else's personal data.
Undervid asks you to confirm that everyone knows before each recording (unless you chose "Don't ask again") and saves that confirmation, but it cannot verify consent for you, and enabling a feature in Undervid is not a substitute for obtaining it. See the Terms of Service §4.
13. Your rights over your data
Because Undervid is local-first, most data rights are exercised directly by you:
-
Access and portability: every artifact is a plain
file (
session.json,transcript.json,evidence.json,feedback.json,feedback.md,meeting-summary.json,implementation-brief.md,consent.json, JPEG frames, MP4). Copy the directory. -
Deletion: delete a meeting in the app, or delete the
directory. For a relay session, the in-app deletion removes the
server-side copy first; relay sessions also expire automatically
within the retention window. Remove an API key under
Settings › API keys. A live transcript file written
with
--writeis yours to delete. - Restriction: revoke Screen Recording, Microphone, or Speech Recognition permission in macOS System Settings; turn off Speaker labels, the Live meeting filter, or the update check in Settings; disconnect a coding agent; revoke the Zoom app authorization in Zoom.
- Device credential: it expires after 90 days. Settings › Zoom › Disconnect revokes it on the relay and removes it from this Mac; meetings already downloaded stay. If the relay can't be reached, the app still removes it here and tells you so, and you can ask us at the address below to revoke it.
- Relay-side data: for a session held in relay staging, deletion in the app removes it immediately; otherwise it expires within the retention window. There is no account record to request, because there is no account (§9).
Where the GDPR, UK GDPR, CCPA/CPRA, or a comparable law applies to you, we will assist you as processor with requests concerning meeting content you control. We hold no controller-side account data to answer for.
14. Security
Credentials and API keys are held in the macOS Keychain and are never
written to source, .env files, or logs. Requests that carry
your device credential or a provider key refuse HTTP redirects, so the
secret is never replayed to another host. Zoom webhooks are accepted
only when freshly signed. Relay artifacts are integrity-checked by
SHA-256 before a session becomes visible. The relay is reached only over
HTTPS and sends Strict-Transport-Security,
Cache-Control: no-store,
X-Content-Type-Options: nosniff and
Cross-Origin-Resource-Policy: same-origin on every
response. Recordings, extracted frames, and analysis exports are
excluded from source control.
To report a vulnerability, email
krish@rackmind.ai. Our disclosure policy is SECURITY.md.
15. Changes and contact
We will update the "Last updated" date above when this policy changes, and will publish a material change alongside the build that makes it true.
Privacy and security contact: krish@rackmind.ai
This policy describes the behaviour of Undervid's code as of the date above. If you find a place where the app and this document disagree, that is a bug in one of them. Please report it.