Every connection Saykeep can make.
Saykeep is closed-source, so the promise is not “read the code”. It is one you can check on the wire: this page lists every host the app can contact, when it does, and what it sends. Run a network monitor on your own Mac and compare.
Saykeep sends no telemetry, analytics or crash reports, and has none of its own. On the Mac, some of the open-source libraries it bundles can report usage. The speaker-label library (pyannote) has it on by default, and Saykeep switches it off before loading it. The model-download library (huggingface_hub) has a usage flag Saykeep does not yet switch off: nothing in Saykeep calls its reporting helper, but the model-download requests it makes to huggingface.co can carry version numbers in a header (its own, Python’s and torch’s). The list below names each library and what the version you download does about it.
When does it connect?
Each wire is a host from the list below, labelled with what goes over it. Pick a moment, and only the ones Saykeep talks to right then light up.
Your MacRecording needs no connection
First run
huggingface.co a download, about 4.7 GB, once
models.saykeep.app a download, ~30 MB, once, if speaker labels are on
Once a day, if you said yes
saykeep.app your version, at most once a day; only if you said yes at setup (Yes is pre-selected)
After a call, if you set a summary endpoint
your summary endpoint transcript text, and your name and “about you” note if you filled them in
When you install an update
dl.saykeep.app the signed update file, when you click Install Update
While it records
No connection is needed to record, and your audio is never sent. While a meeting records, no update check is made — not even Check for Updates… in the menu. With the models downloaded, only what you set up or ask for goes out meanwhile — for example an earlier call’s transcript text, sent to your endpoint for its summary (with your name and “about you” note, if you filled them in), or the request made when you open the panel or press Test or Install Update.
The list
Saykeep/<version> Sparkle/2.9.6): no machine id, account, licence key or cookie. The same host serves this website. Like any web request, the server sees your IP address.The first five rows are the whole list on the Mac; the last one exists only in the Windows build. If you see a connection that isn’t here, that’s a bug — tell us.
Bundled libraries that can report usage
Saykeep is built on open-source libraries, and a few of them have usage reporting of their own. Here is each one, per platform, and what Saykeep 0.4.3 does about it.
pyannote.audioMac and Windows · speaker labels
Its usage metrics are on by default. Saykeep switches them off before the library loads.
huggingface_hubMac and Windows · model downloads
Its usage flag is not switched off in 0.4.3: Saykeep does not yet set that switch. Nothing in Saykeep calls its reporting helper, but the model-download requests it makes to huggingface.co can carry version numbers in their request header: its own, Python’s and torch’s.
ONNX RuntimeMac and Windows · reports only on Windows
On the Mac, the speaker-label library loads it. Its own documentation says its usage reporting exists only in its Windows builds, and is on by default in the official ones; Saykeep does not yet switch it off. Saykeep for Windows is not offered yet.
How to verify
- Install a network monitor. LuLu (free) or Little Snitch shows every connection an app makes, host by host.
- Use Saykeep for a day. Dictate, record a call, and make a summary if you have set an endpoint.
- Compare. Every host your monitor shows for Saykeep should be in the list above. If you see one that isn’t here, that’s a bug — tell us.
The source document, reproduced verbatim
Show the source document (English, verbatim)
# NETWORK.md — every connection Whisperer can make Whisperer is a **local-first** application. Your audio, recordings and transcripts are processed on your machine. This document is an exhaustive, behavior-verifiable inventory of **every** network connection the app is capable of making. You do not have to take our word for it: run a network monitor (Little Snitch on macOS, a firewall log on Windows) and confirm the app opens only the connections listed here. *This file is kept in sync with the code. If you find an outbound connection not listed here, that is a bug — please report it.* ## The complete list | # | Host | When | What is sent | Contains your data? | Avoidable? | |---|------|------|--------------|---------------------|------------| | 1 | **The LLM endpoint you configure** (`llm.endpoint_url`; **no default** — until you set one, summaries are off and nothing is sent) | When a meeting summary is generated, and a `/models` request each time you open the menu-bar panel (0.4.3) or press Test in Settings ▸ Summaries & AI — carrying your API key if you stored one, nothing else | The meeting **transcript text** (for summarization) or a models list request (for the probe) — plus your name and “about you” note, if you filled them in | **Yes — transcript text, plus your name and “about you” note if you filled them in.** It goes only to the endpoint *you* set. Out of the box no endpoint is set, so nothing is sent at all; point it at a server on your own Mac and it all goes only there. If you point it at a cloud API, your transcript goes there **by your choice** | Yes — disable summaries / leave the endpoint unset. Meetings still record and transcribe fully locally | | 2 | **huggingface.co** and its download servers (the Hub's CDN) | First time a model is needed: the Whisper-family speech-to-text models, and — only if you opt in to the Parakeet engine in Settings ▸ Transcription — the Parakeet-TDT-0.6B-v3 weights from the Hub repos `mlx-community/parakeet-tdt-0.6b-v3` (macOS) or `istupakov/parakeet-tdt-0.6b-v3-onnx` plus the `istupakov/silero-vad-onnx` segmenter it needs for long audio (Windows), each pinned to a fixed revision; and, only if you choose the graphics-card Whisper runtime on Windows, the GGML Whisper weights from `ggerganov/whisper.cpp` and the Silero voice-detection model from `ggml-org/whisper-vad`, each pinned to a fixed revision and checked against its sha256. Diarization models come from here **only if you added a Hugging Face token** (optional fallback — the default path is row 5) | A standard model **download** request; for the diarization models, your Hugging Face **token** in an `Authorization` header (only if you provide one) | No — these are downloads *to* your machine. Your token authenticates the download; no audio or transcript is sent | Partly — once models are cached locally they are not re-downloaded. Diarization is optional | | 3 | **huggingface.co/api** (token check) | Only when you click "Test" on the optional Hugging Face token field in Settings ▸ Diarization | Your HF token in an `Authorization` header, to verify it can access the diarization model | No | Yes — it only runs when you test the token | | 4 | **saykeep.app** (the update appcast) | At most once a day, if you said yes at first run (Yes is pre-selected). Never while a meeting is recording, a dictation key is held or a transcript is still being made: a check that falls due then is not made (the update engine's delegate refuses it), and no update installs then either. | A GET of a static XML file. The request carries a standard User-Agent naming the app and its version — `Saykeep/<version> Sparkle/2.9.6` — and nothing else: no machine id, no account, no licence key, no cookie, no identifier that could single you out or link two requests together, beyond the IP address any web request shows. The update itself downloads from **dl.saykeep.app** (the signed DMG, row 4a), only when you click **Install Update** | Your Saykeep version, and that a copy of Saykeep is checking. Nothing else about you or your machine | Turn it off in Settings ▸ App & Updates ▸ Updates and no request is made, unless you choose **Check for Updates…** in the menu yourself | | 4a | **dl.saykeep.app** (the update download) | Only when you install an update: you click **Install Update** on an update that row 4 found | A download request for the signed update file (the DMG the appcast names) | No — this is a download *to* your machine; no audio, transcript or identifier is sent | Yes — never install an update and no request is made | | 5 | **models.saykeep.app** (the speaker-label model mirror) | Once, only if speaker labels (diarization) are enabled and the model is not yet on disk — shown in the "Getting Saykeep ready" download window | An anonymous GET of a static ~30 MB tarball (`diarization-v1.tar.gz`) — no machine id, account, token, or any identifier (the request carries only a generic HTTP-client name). The file is checksum-verified before it is installed | Nothing about you or your machine is sent | Yes — turn speaker labels off (Settings ▸ Transcription ▸ Speaker labels) and no request is ever made; once installed it is never re-downloaded | | 6 | **download.pytorch.org** (the PyTorch project's wheel index) — **Windows only** | Only when you click **Download** under Settings ▸ Transcription ▸ NVIDIA GPU support for speaker labels (Windows, on a PC with an NVIDIA card) — never automatically | Two anonymous GETs of pinned files: the CUDA 12.8 build of torch 2.11.0 (2.75 GB) and of torchaudio (1.7 MB) — no machine id, account, token or any identifier (the request carries only a generic HTTP-client name). Each file is checked against its pinned sha256 and tested on your card before it is installed | Nothing about you or your machine is sent | Yes — never click Download and no request is ever made; speaker labels keep running on the CPU. Once installed it is never re-downloaded | *Row 2 note (2026-09-05): 0.4.0 also made one small metadata request to huggingface.co each time a cached Whisper model loaded (when the app started, when the meeting model loaded, and on every switch between the two) — the loader was handed a Hub repo name instead of the on-disk path. Found and proved on the wire while fact-checking the website, disclosed here the same day, and **fixed in 0.4.1**: a cached model now loads from its local snapshot with no request (wire proof: three requests → none across load → meeting → dictation). It carried no token and no identifier. If you are still on 0.4.0, update, or block huggingface.co — the model loads from disk either way.* *Row 4 note: say No at first run, or switch it off later, and no request is made — the menu's **Check for Updates…** asks only when you choose it.* *Row 4 honesty note (corrected 2026-08-30): this row previously claimed the check sends "no version string". That was wrong — the update engine (Sparkle) sends its standard User-Agent, which names the app version, and nothing in the app overrides it. The row now states what actually goes over the wire. Verify it yourself with Little Snitch or `tcpdump` per the "watch it live" section below — that is the point of this document.* *Row 5 note: this is the token-free replacement for the Hugging Face diarization download (rows 2–3). Those two rows now apply only if you chose to add a token yourself.* *Row 6 note: the files come straight from the PyTorch project, pinned by exact version and sha256, and install into Saykeep's own app-data folder (never the install folder). Remove them from the same Settings row.* That is the entire list. ## What Whisperer **never** does - **Saykeep sends no telemetry, analytics or crash reports, and has none of its own.** On the Mac, some of the open-source libraries it bundles can report usage. The speaker-label library (pyannote) has it on by default, and Saykeep switches it off before loading it. The model-download library (huggingface_hub) has a usage flag Saykeep does not yet switch off: nothing in Saykeep calls its reporting helper, but the model-download requests it makes to huggingface.co can carry version numbers in a header (its own, Python’s and torch’s). saykeep.app/network lists each library and what the version you download does about it. - **No accounts, no login.** There is no Whisperer server that receives your files. - **Your recordings, transcripts, and summaries are never sent anywhere** except the transcript text (with your name and “about you” note, if you filled them in) to the LLM endpoint *you* configured (row 1). - **No license phone-home.** License keys are verified **offline** against a compiled-in public key — no activation server, no network call. - **The diagnostics export** (Settings ▸ App & Updates ▸ Diagnostics) writes a **local file** you choose whether to share; it makes no network call, and it redacts secrets. ## Local helpers are not network connections Whisperer runs some local subprocesses — the bundled `whisperer-syscapture` (macOS system audio), `osascript`/`caffeinate` (macOS), and your OS's file-reveal command. These are **on-device** and open no network sockets. **Neither is the system web view.** The Settings, Recordings and meeting-saved windows are local HTML that the app hands to the web view built into your operating system — WKWebView on macOS, WebView2 on Windows — **as a string**, not fetched from anywhere. Rendering them makes no network request: the pages carry their own CSS and JavaScript, and a test pins that they reference **no remote resource** at all (on Windows that test is load-bearing, because the page is loaded with no origin to resolve a remote reference against). The **Microsoft Edge WebView2 runtime** on Windows is a Windows component maintained by Microsoft's Edge Update — Saykeep neither installs, downloads nor updates it, and if it is absent Saykeep simply opens its older windows instead. ## How to verify 1. **Watch it live:** macOS → Little Snitch; Windows → Resource Monitor / firewall log. With summaries pointed at a local endpoint and models already cached, the only connection you will see during normal use is the **update check** — at most one request a day to the Saykeep appcast, and only if you said yes to it at first run (row 4). You will see your Saykeep version in that request's User-Agent, and nothing else identifying. The one other connection you may see is a **single** download of the speaker-label model the first time you open Saykeep with speaker labels enabled (row 5); it never repeats once the model is on disk. Whatever you have switched on, the only connections you will see are the ones in the table; compare what your monitor shows with the rows above. 2. **Inspect your config:** Settings ▸ App & Updates ▸ Diagnostics ▸ "Export diagnostics…" shows your resolved `llm.endpoint_url` (credentials redacted) so you can confirm where summaries would go. 3. **Hold us to the contract:** Whisperer is closed-source, so instead of "read the code," this file *is* the auditable surface — the only things that ever open a socket are the rows above. If you ever observe a connection that is not listed here, that is a bug; report it and we will treat it as one.