Privacy

What aiTTS sees, and what it doesn't

Last updated: September 20, 2026

aiTTS is a local-first macOS app. The text you narrate and the audio you dictate are processed entirely on your Mac unless you explicitly opt in to a cloud voice. This page lists exactly what we collect, what we never collect, and what choices you have.

What we never collect

The following never leaves your machine, unless you explicitly send us a diagnostics bundle (see Diagnostics you choose to send, below):

  • Text you ask aiTTS to read out loud (assistant transcripts, files, web pages, clipboard contents).
  • Microphone audio captured by push-to-talk dictation, or any derived transcripts.
  • Conversation contents from any of the agent harnesses (Claude Code, Codex CLI, Gemini CLI, OpenCode, Cline, Aider). aiTTS reads these locally to narrate them; nothing is sent to us.
  • Synthesized audio from local Kokoro narration.
  • Any application content from apps you Speak with TTS into.

What we collect, and why

Account

  • Email address — collected at checkout and used to send the magic-link sign-in. Stored in our database (Supabase) and shared with Stripe for the transaction.
  • Magic-link sessions — we store a hashed session token (15-minute expiry on the link, longer on the resulting session) so you can return to the portal without re-typing your email.
  • IP address — used transiently for rate-limiting across the site's endpoints, so that one machine cannot flood sign-in links, activations, checkouts or page counts. Not associated with your account beyond the request itself. The rate-limit counters hold a one-way hash of the address, not the address, and are swept weekly.

Payment

Payments are processed by Stripe. We receive your email, the transaction id, and the line items you purchased. We do not see your card number, CVV, or billing address — those stay with Stripe.

License activation

When the app activates a license on your Mac, we record:

  • License id and the email it belongs to.
  • A hashed machine identifier derived from your hardware UUID. We never store the raw UUID; only a one-way hash that lets us recognize the same machine on repeat activations and enforce the 3-device cap.
  • App version (e.g. 1.3.1) and macOS version.
  • Activation timestamp and last-seen timestamp (refreshed on app launch).

You can revoke a device any time from the portal.

Update checks

The app checks for new versions daily via Sparkle against https://aitts.dev/appcast.xml. The check sends standard HTTP headers (User-Agent including your app and macOS version, IP address) but no personal information.

Diagnostics you choose to send

If you hit a problem, you can send us a diagnostics bundle from the app menu or with tts diag --send. This is always opt-in. Nothing is ever sent automatically.

A bundle contains:

  • App logs, system info (macOS and app version, hardware model), and your settings file with secrets removed.
  • License keys, tokens, and pairing codes are masked. Email addresses keep only their domain.
  • Log entries about text that was narrated or dictated are reduced to a length, a hash, and the first 40 characters of the text. Those 40 characters can include fragments of your content, so review before sending.

To see exactly what would be uploaded, use Export Diagnostics in the app menu first: it writes the identical bundle to disk without sending anything. Bundles you do send are stored in our Supabase storage, used only to debug your issue, and deleted once the issue is resolved.

Optional cloud features

Two cloud features are opt-in and disabled by default:

  • Gemini cloud TTS — if you pass --gemini, the text you're narrating is sent to Google's Gemini API using your GOOGLE_API_KEY. We don't see it; Google does, under their terms.
  • Image description fallback — when you Speak with TTS on an image and on-device OCR finds no text, aiTTS falls back to Gemini or Anthropic for a 2-3 sentence description. Same as above: routed through your API key, not ours.

Both off by default. Both controllable per invocation.

iPhone companion

If you pair the aiTTS iPhone app, the Mac and iPhone discover each other on your local network via Bonjour. The handoff uses a bearer token you generate in-app. The phone receives speech events (text + audio metadata) over Server-Sent Events and renders them locally. Nothing flows through our servers.

Cookies and storage

  • Marketing site (aitts.dev): no third-party trackers, no advertising cookies, nothing shared with another company. The site keeps one first-party id, in a SameSite=Lax cookie and in local storage (400 days), so that two page views can be counted as one visit. It is a random number, it is not built from anything about you, and it goes to our own server and nowhere else. If you never buy, we hold no name or email to connect it to. The site also sets a session cookie after you sign in to the portal.
  • If you buy, the visit and the purchase are linked. We are saying that plainly rather than implying otherwise. The purchase record carries a one-way hash of the visit id and where the visit came from (the utm_ tag or referring site, and the page you landed on), which is how we can tell which link or post led to a sale. Stripe never receives the id itself, only the hash. Inside our own database, though, the hash sits in the same rows as the id, so we could follow a purchase back to the pages that visit saw. We do not do that for any purpose other than counting, and you can ask us to delete all of it (see Your rights), but we are not going to tell you the two are unconnected when they are.
  • Portal session: an HttpOnly, Secure, SameSite=Lax cookie holding your magic-link session id. Used to keep you signed in for ~30 days; logout clears it.
  • App local storage: the app stores its license, your preferences, and a small SQLite index of Claude Code session metadata under ~/Library/Application Support/aiTTS and ~/.claude/tts/. Nothing in there is sent off your machine.

Sub-processors

  • Stripe — payment processing. privacy policy
  • Supabase — database and storage for accounts, licenses, and diagnostics bundles you choose to send. privacy policy
  • GitHub — hosts the signed app downloads and the update feed's release data. privacy policy
  • Vercel — hosts aitts.dev and the marketing site. privacy policy
  • Resend — sends magic-link sign-in emails. privacy policy

We don't use Google Analytics, Segment, Mixpanel, Amplitude, or any third-party tracker on aitts.dev. We do count our own pages: which page was viewed, which link started a download, whether a checkout began, and the utm_ tag or referring site you arrived from. Those counts live in our own database, next to the licences.

No count row contains your name, your email, your IP address, or anything you typed: the columns include a page path, a timestamp, a country, and the random visit id. If you bought a licence, though, that visit id can be connected to your purchase, and therefore to the email on it, by us, in our own database. See “If you buy” under Cookies and storage. Nobody outside gets either half.

Your rights

We honor data-subject requests under GDPR, CCPA, and any comparable regime, regardless of where you live:

  • Access — ask for a copy of every record tied to your email, and of the page and funnel counts we can reach from it. Those counts are keyed by the random visit id rather than by your email, so what we can find is whatever your purchase links back to.
  • Deletion — we'll delete your account, license activations, stored sessions, and the page and funnel counts we can reach from your purchase. Counts we cannot link to you are not identifiable as yours; they are deleted on their own schedule (see Retention). Stripe transaction records are retained per Stripe's policy and tax law.
  • Correction — ask us to fix incorrect data.
  • Portability — export your records as JSON.

Email privacy@aitts.dev. We respond within 30 days.

Retention

  • Account email and license: kept while your license is active.
  • License-activation events: kept for 24 months for support and abuse-prevention purposes.
  • Magic-link sessions: deleted on logout or after 30 days of inactivity.
  • Diagnostics bundles: kept only while we debug your issue, then deleted.
  • Page and funnel counts: kept for 400 days, then deleted automatically. The first-party id in the cookie and in local storage also expires after 400 days.
  • Rate-limit counters (hashed, see above): swept weekly.
  • Stripe records: per Stripe's retention policy and tax-law requirements (typically 7 years).

Security

  • License keys are signed with ed25519; the app verifies them offline so your license still works without an internet connection.
  • Auto-update payloads are ed25519-signed via Sparkle. The app refuses to install an update with a missing or invalid signature.
  • Portal sessions use HttpOnly Secure cookies. Magic links expire in 15 minutes and are single-use.
  • Activation endpoints are rate-limited per IP and per email.

Children

aiTTS is not directed at children under 13 and we don't knowingly collect their data. If you believe a child has created an account, email privacy@aitts.dev and we'll delete it.

Changes to this policy

When we change this policy in a way that affects how we handle your data, we'll update the date at the top of this page. Material changes (anything that broadens what we collect or who we share it with) are also announced on the site so you can review before continuing to use the software. Trivial wording changes don't trigger a notice.

Contact

privacy@aitts.dev for anything in this document. support@aitts.dev for product help.