Data handling
A complete inventory of every external service Haven contacts, what is sent, and why.
The short version: Haven contains no analytics, no crash reporting, no advertising, no attribution and no remote configuration. Every network call in the app belongs to one of the five entries below.
Every external call#
1. Blocklist distribution — Haven's own endpoint#
| When | Roughly every twelve hours in the background, and when the user taps "sync now" |
| Sent | Only the blocklist version number currently applied. Nothing else |
| Received | A signed, versioned rule delta |
| Contains no | Hostnames visited, account, device identifier, installed apps, IP-derived profile |
The endpoint is never told what the user browses, so it cannot learn it. See Blocklist distribution.
2. Account-created email — Haven's own endpoint#
| When | Once, when an account is created |
| Sent | The email address, and the name if one is known |
| Received | An acknowledgement |
Fire-and-forget: every failure is swallowed, because the account exists regardless. The address leaves the device for this single purpose.
The message itself is delivered by a third-party transactional email provider on the backend's side, never from the device.
3. Accounts backend (Supabase) — only if the user creates an account#
| Operation | Sent |
|---|---|
| Sign up | Email, password, and the separate marketing-consent choice |
| Sign in | Email and password, or a Google ID token |
| Session refresh | The refresh token |
| Password reset | The email address |
| Password change | The current and new password, via a re-authentication |
| Profile update | Chosen language and notification preference |
| Read entitlements | The access token only |
| Claim daily streak | The access token only |
| Sync cosmetic unlocks | The access token only |
| Delete account | The access token only |
Every call is scoped to the caller by the token, server-side. Row-level security means a user can only ever read or write their own row.
A user who never creates an account never contacts this backend at all, and loses none of the gambling protection.
4. Subscriptions (RevenueCat) — only if a subscription is configured and used#
| When | App start, purchase, restore, and on renewal or expiry events |
| Sent | The account identifier (so the payment webhook can map a purchase to the right account), and the purchase and receipt data the billing SDK handles |
| Received | The current entitlement state |
Purchases reach Haven's backend through a server-to-server webhook, never from the device. See Accounts and entitlements.
5. Google sign-in — only if the user chooses it#
| When | The user taps "continue with Google" |
| Sent | A standard Google sign-in through the system account picker |
| Also fetched | Google's public signing keys, so the returned token can be verified on the device before it is trusted |
6. DNS resolution — the upstream resolver#
Allowed hostnames are forwarded to a public resolver. This has its own page, because it is the largest flow in the app: DNS resolution.
What never leaves the device#
| Data | Where it lives |
|---|---|
| Browsing history | Not collected at all. Only blocked hostnames are logged, locally |
| The block log | On-device database |
| Page text read during a content scan | Held in memory during the scan, then discarded. Never stored, never transmitted |
| Address-bar text | Compared on-device, then dropped |
| The list of installed apps | On-device only |
| App-check results and released apps | On-device only |
| Personal filters and learned sites | On-device only |
| The accountability partner's name and email | On-device only |
| Accountability event history | On-device only |
| Financial pause log and guarded app list | On-device only |
| Budget, balance and expense entries | On-device only |
| PIN | Only as a salted hash, on-device |
| Sam's treats, growth and equipped cosmetics | On-device only |
allowBackup is false, so Android's own backup does not carry this off the device either.
Accountability emails#
Partner invitations and event notifications are composed on the device and handed to the user's own email app. They are sent from the user's own account and never touch Haven's servers. The partner's address is never uploaded.
Third parties named in the privacy policy#
Google (sign-in and Play billing), RevenueCat (subscription management), Supabase (accounts and progression) and the transactional email provider used for account emails. Each is linked to its own privacy policy from the published policy.
Deletion#
| The user wants to | Route |
|---|---|
| Delete on-device data | Uninstall Haven, or clear individual items in the app |
| Delete the account and its server-side data | In the app, or from the account-deletion page on the public site if the app is no longer installed, or by contacting the address in the privacy policy |
Deleting the account does not turn protection off.
Design position#
Every one of the reliability compromises in this app points the same way. Accountability emails go through the user's mail app rather than a server, which is less reliable but means Haven holds no list of who its users are accountable to. The blocklist endpoint is told only a version number, which rules out server-side personalisation but also rules out a browsing profile. Page text is discarded rather than uploaded for classification, which caps how clever the detection can get.
For an app whose users are, by definition, in a vulnerable position, holding less data is worth more than being cleverer.