No. privacytracker is an independent open-source project. It reads each app’s privacy labels straight from Apple’s public App Store HTML — no API key, no auth, no partnership. When Apple changes their HTML shape, we update the parser; if Apple were ever to ask us to stop, we would.
No. The scraper targets Apple’s App Store HTML — both the modern <script id="serialized-server-data"> envelope (Nov 2025+) and the older Ember/FastBoot shoebox-media-api-cache-apps shape (Jan 2021 – Nov 2025) for archive.org captures — which is iOS-specific. Google Play has a different shape and a different label scheme (Google’s “Data safety” section vs. Apple’s “App Privacy”), so it would need a separate parser and data model. The codebase is contribution-friendly and the data layer is structured to make adding a parallel parser feasible if someone wants to take it on.
Yes. On first run, pick Try with sample data instead of adding apps — privacytracker loads 10 demo apps so you can explore the dashboard, Privacy Map, per-app timelines, and the bell before committing anything real. The sample set is session-only and disappears once you restart or start adding your own apps, so it never mixes into your data.
Four things, all opt-in or transparent:
  1. App Store HTML — fetched from apps.apple.com to read public privacy labels. Same network call your browser makes when you visit an app’s page.
  2. Privacy-policy text — fetched from the developer’s own domain when you’ve enabled AI summaries. The fetcher follows redirects and respects standard Cache-Control headers.
  3. AI provider calls — only if you’ve configured one. The policy text (chunked if necessary) is sent to OpenAI, Anthropic, or your local OpenAI-compatible endpoint. Nothing else — no app names, no usage, no telemetry.
  4. Notification webhooks — only if you’ve pasted a webhook URL. App names and change summaries are POSTed to whatever chat service you pointed it at. Off unless you set it up; see Configuration → Notification webhooks.
Beyond those, privacytracker has no analytics or telemetry of its own. The SQLite database, all settings, all your annotations stay on your machine.
It depends on the provider and how many policies you summarise:
  • OpenAI / Anthropic (hosted) — typically a fraction of a cent per summary. A privacy policy of ~20 KB summarised through gpt-4o-mini or claude-haiku-* runs around USD $0.001-0.005 per app. Re-summarisation only happens when the policy text actually changes (we hash and skip otherwise), so the long-tail cost stays low.
  • Local model (Ollama, LM Studio, llama.cpp) — free at runtime; you pay in disk space and a one-time model download. Quality varies; Llama 3.1 8B and Qwen 2.5 7B both produce usable summaries on the lens prompts.
There’s no in-app spend cap — privacytracker never sees your provider’s billing. For belt-and-braces protection, set a spending limit on the API key itself at OpenAI or Anthropic and use that key here. The hash-skip behaviour above is the other half of it: a policy that hasn’t changed is never re-summarised.
Yes. One Docker container or one self-hosted instance can track apps across several people’s devices; the import flow accepts batched .txt / .csv files from the iPhone import helper so you can ingest a family member’s app list in one pass. Record whose each device is, and the device menu at the top of every page switches between them — one person’s devices, a few, or everyone’s.That’s a view, not a wall. privacytracker has no built-in user accounts or per-user partitioning — anyone who can open it can pick any device. If family members’ data needs keeping apart, run separate instances (different ports, different data/ directories) or use the audit-bundle handoff workflow to share a curated subset.
The parser has a four-layer fallback chain (shelfMapping.privacyTypes.items → privacyHeader.seeAllAction.pageData.shelves → generic pageData.shelves → extractFromShoebox for the historical Ember/FastBoot shape, which is what lets the Wayback importer reach back to Q1 2021) so most shape changes absorb without a release. When Apple ships a fully breaking change — twice in the project’s history so far — the fix is usually 5-10 lines in lib/scraper.ts once we have a known-broken example.If you hit a parser failure, the support bundle under Settings → Admin → Deployment Diagnostics captures everything we’d need to fix it; paste it into a GitHub issue.
Only when scraping. Once data is in your local SQLite DB, every dashboard, chart, timeline, and search works offline. The 30-minute background sync ticker noops if the network is unreachable; you can also disable scheduled sync entirely in Settings → Sync and re-scrape manually.Wayback imports and AI-policy fetches obviously need internet at the time they run.
Yes:
  • Backup bundle — GET /api/backup/export produces a versioned JSON file with every app, label, snapshot, annotation, and notification. Restore it via POST /api/backup/restore; the UI adds a preview and a typed confirmation, and a bundle exported by a different install needs an explicit untrusted opt-in. See Backup & restore.
  • CSV / JSON dump — GET /api/export?format=csv|json for a flat data dump suitable for piping into a spreadsheet or another tool.
  • Audit bundle — a curated subset (apps, labels, AI summaries, exportable annotations) suitable for sharing with another household member or a regulator. Available when your focus workflow is other_handoff, or when the audit-bundle export flag is switched on.
Private annotations are unconditionally excluded from audit-bundle exports at the SQL level — there is no force-include path.
privacytracker doesn’t collect or transmit personal data, so the privacy-regulation footprint of running it is minimal. What it stores about you locally is your own data — annotations you wrote, apps you tracked, AI summaries of public policies.If you’re using the audit-bundle export to share data with someone else (a regulator, a household member), that bundle contains your annotations and verdicts, so treat it like any other personal data file — keep it on encrypted media, share via secure transfer.privacytracker is not a substitute for legal advice and we don’t claim any compliance certification.
Three reasons:
  1. Single-user app — there’s no multi-write contention to manage. WAL mode + a 5-second busy_timeout cover the rare cases where a manual scrape and a scheduled sync overlap.
  2. One file: privacy.db survives container rebuilds in its volume, copies trivially for backup, and can be inspected directly with the sqlite3 CLI. No backup server, no replication, no DBA needed.
  3. No schema migration tooling — better-sqlite3’s synchronous API plus an inline migrations array of ALTER TABLE statements is a complete schema-versioning story for the project’s complexity. Postgres would buy us nothing we’d actually use.
The trade-off: privacytracker doesn’t scale horizontally. That’s fine — it isn’t a multi-tenant SaaS, it’s a tool you run for yourself.
English (en) and Simplified Chinese (zh), both at full key parity. Switch between them under Settings → Language. The interface is built on next-intl; the active language is resolved on every server-rendered request from the NEXT_LOCALE cookie, falling back to English when it’s absent or holds an unsupported value. Adding a language is a contributor task — see Translations.
Yes. See Contributing for the workflow. Privacy-label parser fixes are typically the most welcome and the most contained — usually a 5-10 line update in lib/scraper.ts plus a regression test.
Yes. The Tauri shell (src-tauri/), the Next.js bundle, the iPhone import helper (scripts/ios-app-import/), and everything else in the repo is Apache-2.0 licensed. The signed binaries we publish on GitHub releases are built deterministically from the same source — you can build your own from develop/build-from-source if you want to verify.

Didn’t see your question?

Open an issue on GitHub — if it’s a question we hear more than once, it lands here.