Snowball Penguin

Privacy Policy

Last updated: October 6, 2026 ("Restore purchase" now emails you a sign-in link instead of taking an email on trust, so restoring signs you in; server logs no longer hold your email address or your checkout session ID, only a short fingerprint of the email made with a secret key, and whether the session was a live or test one; September 24: saving the monthly check-in reminder to your calendar is a logged event, and crash reports are sent when the app breaks)

Short version: the app runs in your browser. By default, your debt data stays on your device. If you sign in to enable cross-device sync, a copy of your plan is stored in our database so you can pick it back up on another device — scoped to your account, never shared, and deletable at any time.

1. What we don't collect

2. What we do collect

Anonymous page-view analytics (Vercel Analytics) Every time someone loads the site, our hosting provider (Vercel) records: which page was loaded, referring URL, country, device type, browser. No cookies, no IP address storage, no personal identifiers. We use this to see how many people visit and whether the site is growing.
Anonymous product analytics (Vercel Analytics) Beyond page views, the app sends anonymous events as you use it, so we can see where the product helps and where people get stuck. These fire for everyone, including free users who never sign in. They record that something happened and a small amount of context:

What happened: finishing onboarding, switching tabs, viewing your first projected payoff, marking a payment done, updating balances, clearing your first debt, exporting a PDF or CSV, downloading your plan as a Google-Sheets workbook, copying a share message or saving the monthly check-in reminder to your calendar, seeing or clicking the upgrade prompt, starting checkout, signing in, syncing to the cloud, attempting a restore, the free-month offer being shown, accepted, declined, used, expiring, or converting, and — on the do-it-yourself page — viewing it, copying one of its three prompts, or clicking through to the planner.

Context attached: your chosen strategy (avalanche/snowball), how many debts are in your plan, how many months the plan or first payoff runs, months saved versus the minimum-payment baseline, which feature was used, which plan you bought, which of the three do-it-yourself prompts was copied, and any utm_* campaign tags from the link you arrived on.

What is never in these events: your debt balances, debt names, payment amounts, interest rates, your email address, your account ID, or anything that identifies you. The numbers above are plan shape, not your figures — but they are derived from what you entered, which is why they are disclosed here rather than filed under page views.
Crash reports If the app breaks while you're using it, your browser sends us a crash report so we can fix it: the error message, the place in our code where it happened, the page path (without any query string), the app version, and your browser's user-agent string. Email addresses are stripped from the text before it leaves your device. A report never includes your debt balances, debt names, payment amounts, rates, your email address, your account ID, or your IP address (the server uses it only in memory, to limit how many reports one device can send). Reports show up briefly in our hosting provider's server logs, and are kept in our database (Supabase) for 90 days, then deleted automatically.
Connected Google Sheet (optional) If you use "Connect your sheet" to pull balances back from a Google-Sheets workbook you downloaded from us, the link you paste is sent to our server, which fetches that sheet's published CSV from Google and returns it to your browser. The server is a pass-through: it stores nothing — not the link, not the sheet's contents — and processes both only for the moment of that request. The link itself is saved in your browser's localStorage so you can re-sync with one click. The anonymous analytics event for a sync records only how many debts were updated or unmatched — never the sheet's figures. If you never connect a sheet, none of this applies.
Payment information When Pro is enabled, payment is processed by Stripe — we never see or store your card details. Stripe shares the email you used at checkout (so we can verify a purchase on restore) and a confirmation that payment succeeded. That's it.
Account email and plan data (signed-in users only) If you sign in — to enable cross-device sync, or by restoring a purchase, which emails you a sign-in link — our database provider (Supabase) stores your email address (for magic-link login) and a copy of your plan state — debt balances, payment amounts, APRs, strategy choice, snowflakes, your monthly check-in record (which months you marked paid and the balances you logged), and similar planner fields. Cloud sync runs only while Pro is active (a paid plan or the earned free month); signing in alone does not copy your plan anywhere. Every row is scoped to your user ID with Row-Level Security so only you can read or write it. We use this exclusively to hydrate your plan when you sign in on a new device. If you never sign in, none of this applies — we hold no account and no copy of your plan, and your debt figures never leave your browser (the anonymous events in the product-analytics box above are the only thing that does).
Purchase and subscription records (paid users only) Lifetime purchase ($49): when you complete checkout, we record the checkout session ID, the email used at checkout, the amount paid, and the timestamp. We use this to turn Pro on when you sign in with that email on another device ("Restore purchase" emails you the sign-in link) and to honor refunds.

Monthly subscription ($5/mo): when you subscribe, we record the Stripe subscription ID, the email used at checkout, the subscription status, and the current billing period end date. We use this to decide whether Pro is unlocked for you. We read your status when the app starts up — each time you open or reload it, and when you sign in — and, if you are signed in, again whenever you return to the tab. We do not poll continuously in the background. So a cancellation, a refund, or a failed payment is reflected promptly: on the next open or reload, or — for a signed-in tab you already have open — as soon as you come back to it. (A signed-in tab left in the background won't see the change until you return to it or reload.) This matches the refund policy: a cancelled subscription keeps Pro through the end of the billing period you already paid for, then locks at the next start-up or return to the tab.

We do not store card details for either plan.

Server logs: the verify-purchase, payment-webhook and subscription-management functions write lines about the purchase they are checking to our hosting provider's function logs (Vercel) for debugging failed unlocks and refunds. Your email address is not written there: every email address in a log line is replaced by a short fingerprint made with a secret key we hold (the first 12 characters of a keyed SHA-256 hash), or by nothing at all. With the key we can match up the lines for one purchase, and find yours if you write to us; without it, the fingerprint can't be traced back to or checked against an address. The checkout session ID is cut out of every log line too (only whether it was a live or test one remains), because that ID alone unlocks Pro. Those logs are retained by Vercel for a short rolling window and are not used for anything else.
Support emails If you email us (e.g., for a refund), we obviously have your email and whatever you wrote. We use it to respond to you and nothing else.

3. Where your plan data lives

Not signed in (default): everything you enter into the app — debt balances, payment amounts, rates, snowflakes, and your monthly check-in record — is stored in your browser's localStorage and stays on your device. Those figures don't travel to us. They don't travel anywhere. If you clear your browser data, they're gone. (The anonymous product-analytics events in §2 are the one exception to "nothing leaves the device," and they carry only plan shape — debt count, plan length — never the figures themselves.)

Signed in (optional cross-device sync): when you sign in with a magic link, the app stores a JSON copy of the same plan fields in our database (Supabase) so you can pick the plan back up on another device. Your localStorage stays the primary copy at runtime — the cloud copy is a mirror. Sync happens automatically while you're signed in. Sign out and the cloud copy stops updating; delete your account and the cloud copy is removed.

Connected Google Sheet (optional): if you keep your snowball in a Google-Sheets workbook and connect it, that spreadsheet lives in your Google account, under Google's terms — we never hold a copy. For the sync to work, the sheet (or its published Snowball tab) must be readable by "anyone with the link" or published to the web; that is a Google sharing setting you control, and it means anyone you give the link to can see the sheet. During a sync, the sheet's contents pass through our server transiently and are discarded the moment they reach your browser.

Private share: the "Private share" button copies a short text message to your clipboard — your projected payoff dates only (e.g. "First debt can be gone by [month]"). No debt names, balances, or account details are included. Nothing is sent to our servers; the text only goes where you paste it.

4. Subprocessors

We use the following services to run the app. Each is contractually limited to processing your data on our behalf:

5. Cookies

The app uses browser localStorage (technically not a cookie) to persist your settings, plan data, local Pro unlock status, free-month state, and — if you use it — the link to your connected Google Sheet. If you bought Pro on this device, it also keeps the Stripe checkout session ID, so the app can re-check that the purchase is still valid on later visits. Pro restored on a device lasts while you're signed in there, and is re-checked against your account; a device that restored by email before October 2026 keeps that email until you next sign in on it. It also uses sessionStorage to hold any utm_* campaign tags from the link you arrived on, for the length of that tab session, so a purchase can be attributed to the channel it came from. If you sign in, Supabase sets an authentication cookie/local-session token so you stay signed in between visits. We do not use tracking cookies.

6. Children

The app isn't designed for or directed at children under 13.

7. Your rights

8. Changes

If we ever start collecting something new, this page will be updated and the "last updated" date changed. We won't slip new data collection in quietly.

9. Contact

Privacy questions, data requests, or concerns: support@snowballpenguin.app