PRIVACY local by default cloud only if you opt in no telemetry

By default, your voice never leaves your Mac.

Hold Speak is built local-first on purpose. Microphone audio is captured, transcribed, and inserted entirely on your machine. No servers see it. No analytics log it. There is no account to create and nothing to sign in to. The one exception is opt-in: if you switch the engine to Gemini or OpenAI, each dictation's audio is sent to that provider — details below.

Audio
On-device by default. Sent to Google or OpenAI only if you pick their engine.
Transcripts
Stored locally in your home folder.
Telemetry
None. No analytics, no crash SDK.
Accounts
None. No sign-in. An API key only if you pick Gemini or OpenAI.
01

Short version

Hold the hotkey, speak, release. With the local engines — Parakeet Ultra (the default on macOS 14+) or Whisper Turbo — the entire pipeline — microphone capture, transcription, text insertion — runs in a single process on your Mac. Nothing is sent to Anthropic, OpenAI, or any other third party. Nothing is sent to me. Nothing is sent anywhere during dictation.

Whisper runs on your GPU via WhisperKit (Apple's CoreML). On macOS 14+ with Apple Silicon the default is NVIDIA Parakeet Ultra instead, which runs on the Neural Engine via FluidAudio. Either model's weights are downloaded once from Hugging Face on first use, then all inference is offline.

Parakeet Ultra by moondream, based on NVIDIA Parakeet TDT 0.6B v3, CC-BY-4.0; Core ML build by FluidInference (FluidAudio).

You can instead choose a cloud engine with your own API key: Gemini by Google (since v0.3.0) or OpenAI (since v0.4.0). Neither is on unless you pick it, and while one is on, your audio goes to that provider. See Optional cloud engines.

02

What happens when you hold the key

  on-device
  ┌───────────┐    PCM     ┌─────────────┐   text    ┌──────────────┐
  │ microphone│ ─────────▶ │ local model │ ────────▶ │ focused field│
  └───────────┘  in-memory │  (GPU/ANE)  │  CGEvent  └──────────────┘
                           └─────────────┘
                                 │
                                 ▼
                        history.sqlite  (recent, in ~/Library)

  cloud upload   analytics   crash reporting   remote logging
  1. Capture. Audio is read from the mic into a memory buffer. It is never written to disk as a file.
  2. Transcribe. The buffer is passed to WhisperKit (Whisper) or FluidAudio (Parakeet), which run CoreML on the Apple Neural Engine / GPU. No network socket is opened. (If you selected Gemini or OpenAI, this step is an HTTPS request to that provider instead — see below.)
  3. Insert. The resulting text is typed into the focused input via CGEventKeyboardSetUnicodeString. Password fields are detected and skipped.
  4. Forget. The audio buffer is released. Only the final text is kept, and only if you want history.
03

What's stored on disk, and where

Everything Hold Speak keeps lives under your user's Application Support directory. You own these files; delete them anytime.

  • ~/Library/Application Support/holdspeak/history.sqlite — the last transcriptions shown in the menu bar popover, plus metrics (dictations per day, 7-day avg WPM). Text only — no audio.
  • ~/Library/Application Support/HoldSpeak/models/ — downloaded model weights: OpenAI Whisper Turbo and, if you chose it, NVIDIA Parakeet Ultra (in models/parakeet-ultra).
  • ~/Library/Application Support/holdspeak/terminology/<lang>.json — your terminology dictionary (canonical terms and variants).
  • ~/Library/Preferences/…holdspeak.plist — app preferences (hotkey, model, HUD position, etc.) via standard UserDefaults.
  • macOS Keychain, item com.timmal.push-to-talk / api-keys — your Gemini and OpenAI API keys, only if you saved any. Never written to preferences or logs.
  • ~/Library/Logs/holdspeak.log — diagnostic log (levels, RMS values, language-detection decisions). Does not contain transcript text.

To wipe history and reset metrics: Preferences → History → Clear history. To nuke everything the app has ever stored, quit the app and delete the folders above.

04

The only times the app touches the network

With the local engines (Parakeet Ultra or Whisper Turbo), dictation itself is fully offline. Three optional, clearly-bounded operations do reach the network — and none of them ever send your voice or your transcripts. The only thing that does is an opt-in cloud engine, described in the next section.

  • Model download (once). On first use of a given Whisper model, weights are fetched from huggingface.co/argmaxinc. This is a plain HTTPS download of a public file. You can also point the app at an existing local WhisperKit models folder (e.g. from MacWhisper) and skip the download entirely. If you choose NVIDIA Parakeet Ultra, its weights (~610 MB) are fetched once the same way from huggingface.co/FluidInference; a copy already downloaded by another FluidAudio app is reused.
  • Update check. The app periodically hits the GitHub Releases API for timmal/HoldSpeak to see if a newer version exists. This is a single anonymous HTTPS request — GitHub's standard server logs apply. You can trigger it manually via Preferences → General → Check for updates, and ignore the banner if you don't want it.
  • Links you click. Buttons like "Download", "View source", or the Support tab open URLs in your default browser. Nothing the app initiates on its own.
If you want verifiable offline operation, stay on Whisper or Parakeet and use Little Snitch / LuLu to deny all outbound traffic to the app after the model is downloaded. Dictation will continue to work indefinitely with zero network access.
05

Optional cloud engines: Gemini and OpenAI

The default is a local model: NVIDIA Parakeet Ultra on macOS 14+, OpenAI Whisper Turbo on macOS 13. If you choose a Gemini or OpenAI model — in onboarding or in Preferences → Audio → Model — the data flow changes:

  • What is sent. After you release the hotkey, the recording (silence trimmed, as a WAV clip) is sent over HTTPS together with your primary language and the canonical terms from your terminology dictionary as spelling hints — to Google's Gemini API at generativelanguage.googleapis.com or to OpenAI's transcription API at api.openai.com. The provider returns the transcript.
  • Whose account. Requests use your own API key, so they fall under that provider's terms and your account there. Gemini: Google's Gemini API terms; on keys without billing (the free tier) Google may use the data to improve its products. OpenAI: per OpenAI's API data policy, API data isn't used for training unless you opt in, and may be kept up to 30 days for abuse monitoring. Nothing passes through any server of mine.
  • The keys. Stored in the macOS Keychain. Saving a key makes one request to that provider to check it.
  • Fallback (off by default). The app switches engines on its own only if you turn on Preferences → Audio → Fallback. Then a dictation the selected engine couldn't transcribe goes to the other cloud engine — only if you saved its key, so audio meant for OpenAI may reach Google and the other way round — and then to the local model you picked last on your Mac (OpenAI Whisper Turbo or NVIDIA Parakeet Ultra). Without internet it goes straight to the local model.
  • Everything else stays the same. Audio is still never written to disk, history stays local, and there is still no telemetry. Switch back to Whisper or Parakeet and the app is fully offline again.
06

Permissions the app asks for — and why

macOS gates each permission individually. Hold Speak only uses what it strictly needs:

  • Microphone — to capture audio while you hold the hotkey. Not used at any other time.
  • Accessibility — to insert the transcribed text into the focused input via the synthetic-key API.
  • Input Monitoring — to detect the push-to-talk key press globally (e.g. Right Option / Right Cmd).

The app does not request Full Disk Access, Screen Recording, Contacts, Calendars, Reminders, Photos, or Automation.

07

Security posture

  • Password fields are skipped. When the focused input is marked secure, the app refuses to insert text — your passwords never end up in a transcript.
  • No clipboard detour. Text is typed directly as Unicode key events, so your clipboard is not overwritten and clipboard managers don't capture what you dictate.
  • Audio is never written to disk. Capture happens in a RAM buffer that is discarded after transcription.
  • Logs redact content. ~/Library/Logs/holdspeak.log records levels, durations, and decisions — not what you said.
  • No background listening. The microphone is only opened while the hotkey is held; the mic indicator in the menu bar confirms this.
  • Open source, inspectable. The full pipeline is auditable at github.com/timmal/HoldSpeak. If you don't trust this page, read the code — or build your own DMG from source.
  • Runs in the user sandbox. Standard macOS TCC gates every sensitive API; revoke any permission in System Settings → Privacy & Security and the corresponding feature simply stops working.
08

What we do not do

  • No accounts, no sign-up, no email.
  • No analytics SDK (no Mixpanel, PostHog, Amplitude, Segment, Firebase, etc.).
  • No crash-reporting SDK (no Sentry, Crashlytics, Bugsnag).
  • No ads, no ad identifiers, no fingerprinting.
  • No cloud sync. Your history and terminology dictionary live only on this Mac.
  • No third-party transcription by default — WhisperKit (or FluidAudio for Parakeet) runs locally. Audio goes to Google or OpenAI only if you yourself pick their engine with your own key; nothing is ever sent to Anthropic or me.
  • No selling, sharing, renting, or "aggregating" anything. There is nothing to sell.
09

Your data, your control

  • Inspect — open the files under ~/Library/Application Support/holdspeak/ with any SQLite or text editor.
  • Export — your terminology dictionary is plain JSON; commit it to a dotfiles repo if you want.
  • Delete — Preferences → History → Clear history, or remove the folder. There is no "server" to ask.
  • Revoke — remove Microphone / Accessibility / Input Monitoring in System Settings → Privacy & Security at any time.
10

Changes to this policy

This page is versioned in the same Git repository as the app. Any change is a commit you can inspect, diff, and blame. If the app's behavior ever changes in a way that affects privacy, the release notes will call it out.

  • 18 October 2026 · v0.5.2 — onboarding now preselects NVIDIA Parakeet Ultra (local) on macOS 14+ instead of OpenAI Whisper Turbo. Nothing changes in what leaves your Mac.
  • 18 October 2026 · v0.5.0 — added Parakeet Ultra as a second local engine (macOS 14+, Apple Silicon). It works offline like Whisper; choosing it adds a one-time model download from huggingface.co/FluidInference. Whisper Tiny and Small were removed.
  • 14 October 2026 · v0.4.0 — added the optional OpenAI cloud engine (off by default; audio goes to OpenAI with your own API key) and an opt-in Fallback that can hand a failed dictation to another engine; see Optional cloud engines. API keys now share one Keychain item, api-keys.
  • 2 October 2026 · v0.3.0 — added the optional Gemini cloud engine (off by default). When you choose it, dictation audio is sent to Google with your own API key; see Optional cloud engine. With Whisper nothing changed.

Questions or concerns: open an issue at github.com/timmal/HoldSpeak/issues.

Privacy · v1.2 · local by default github.com/timmal/HoldSpeak ↗