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

  1. First run

    huggingface.co a download, about 4.7 GB, once

    models.saykeep.app a download, ~30 MB, once, if speaker labels are on

  2. 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)

  3. 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

  4. When you install an update

    dl.saykeep.app the signed update file, when you click Install Update

  5. 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

huggingface.co and its download servers
WhenThe first time each speech model is needed: at first run, and later when you pick a model or engine in Settings that isn’t on your Mac yet. If a Hugging Face token was added (none is by default), also each time speaker labels are made without the downloaded model.
What is sentA standard download request for the speech models (about 4.7 GB in all); with a token you added, the token too. The request header can name the versions of the download library, of Python and of torch (see Bundled libraries). Since 0.4.1, a model already on disk loads with no request. Like any web request, the server sees your IP address.
Contains your data?No. These are downloads to your Mac; no audio or transcript is sent.
Avoidable?Not on a first install. A model on disk is not downloaded again.
models.saykeep.app
WhenOnce: at first run, or the next time Saykeep starts after you first switch speaker labels on (they are on by default).
What is sentAn anonymous download of the ~30 MB speaker-label model, checked against its checksum before it is installed. Like any web request, the server sees your IP address.
Contains your data?No. Nothing about you or your Mac is sent.
Avoidable?Yes: switch speaker labels off in Settings ▸ Transcription ▸ Speaker labels. Once installed, the model is not downloaded again.
saykeep.app
WhenAt most once a day, if you said yes at setup (Yes is pre-selected).
What is sentA request for a small signed file that lists the current version. It carries a User-Agent naming the app and its version (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.
Contains your data?Your Saykeep version, and that a copy is checking. Nothing else about you.
Avoidable?Yes: say No at setup, or switch it off in Settings ▸ App & Updates ▸ Updates. Check for Updates… in the menu then asks only when you choose it.
dl.saykeep.app
WhenWhen you install an update: you click Install Update.
What is sentA download of the signed update the check found. Like any web request, the server sees your IP address.
Contains your data?No. This is a download to your Mac.
Avoidable?Yes: don’t install the update.
Your summary endpoint
WhenOnly once you set one (none is set by default): each time you open the menu-bar panel or press Test, and whenever a summary is made.
What is sentA model-list request, carrying your API key if you stored one; and, when a summary is made, the meeting’s transcript text and, if you filled them in, your name and “about you” note. Like any web request, the server sees your IP address.
Contains your data?Yes: the transcript text, plus your name and “about you” note if you filled them in, only to the endpoint you chose. Point it at a server on your own Mac and it all goes only there.
Avoidable?Yes: leave the endpoint unset. Recording, transcription and speaker labels work in full.
download.pytorch.orgWindows onlySaykeep for Windows is not offered yet.
WhenNever by default: only if you click Download under Settings ▸ Transcription ▸ NVIDIA GPU support for speaker labels.
What is sentTwo pinned files (the CUDA builds of torch and torchaudio), each checked against its sha256. Like any web request, the server sees your IP address.
Contains your data?No. Nothing about you or your PC is sent.
Avoidable?Yes: never click Download; speaker labels then run on the processor.

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

  1. Install a network monitor. LuLu (free) or Little Snitch shows every connection an app makes, host by host.
  2. Use Saykeep for a day. Dictate, record a call, and make a summary if you have set an endpoint.
  3. 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)
Codename note: the document below is Saykeep’s in-repo trust artifact, reproduced verbatim, so there is one source of truth. It refers to the app by its internal codename, “Whisperer” — that is the same application as Saykeep. Every socket, host, and guarantee below applies to Saykeep exactly as written.
# 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.