What leaves your browser

Every network request Coffer is capable of making is listed below. Account identity and session requests leave the browser only if you choose to sign in. Transactions, categories, budgets, and account balances remain in browser IndexedDB unless you explicitly enable encrypted Cloud sync.

This list is canonical. Adding a new network destination requires a PR that updates both the code (the Content Security Policy allowlist in vercel.json and public/_headers) and this page. You can verify what Coffer is doing at any time by opening your browser's Network tab.

Destination
nuvtrqnvulphceqjrkpk.supabase.co
Purpose
Coffer account signup, login, passkeys, and session refresh
Data sent or returned
Email, password or passkey assertion, and account session tokens. No financial data.
Triggered by
User chooses to sign in or manages their account
Opt-in
Yes
Destination
/api/account (same origin)
Purpose
Load account identity, Cloud entitlement, and billing availability
Data sent or returned
Account session token; account ID/email and subscription status, period, and cancellation metadata are returned.
Triggered by
A signed-in user opens the app or Cloud settings
Opt-in
Yes
Destination
/api/billing/checkout (same origin)
Purpose
Create or reuse an account-bound Coffer Cloud Checkout session
Data sent or returned
Account session token. Coffer sends account ID/email and the Cloud price to Stripe server-to-server; no card details pass through Coffer.
Triggered by
User clicks Subscribe to Coffer Cloud
Opt-in
Yes
Destination
/api/account/reconcile (same origin)
Purpose
Refresh the account's Coffer Cloud entitlement from Stripe
Data sent or returned
Account session token. Coffer reads subscription ID, status, billing period, and cancellation metadata from Stripe server-to-server; no financial workspace data is sent.
Triggered by
User returns from Checkout or clicks Check activation again or Refresh plan
Opt-in
Yes
Destination
checkout.stripe.com
Purpose
Primary account-based Stripe Checkout
Data sent or returned
Billing contact, payment, and tax details entered directly into Stripe's hosted page.
Triggered by
Coffer redirects the user after the account Checkout API succeeds
Opt-in
Yes
Destination
/api/billing/portal (same origin)
Purpose
Create an account-owned Stripe Customer Portal session
Data sent or returned
Account session token; a short-lived Stripe-hosted Portal URL is returned.
Triggered by
User clicks Manage Subscription
Opt-in
Yes
Destination
billing.stripe.com
Purpose
Stripe Customer Portal
Data sent or returned
Billing changes entered directly into Stripe's hosted page.
Triggered by
Coffer redirects the user after the Portal API succeeds
Opt-in
Yes
Destination
/api/account/claim-license (same origin)
Purpose
One-time migration of a legacy signed Cloud license to an account
Data sent or returned
Account session token and signed legacy license (email, plan, and expiry). A matching legacy encrypted blob may be copied server-side.
Triggered by
An eligible legacy subscriber chooses to claim their plan
Opt-in
Yes
Destination
/api/account/delete (same origin)
Purpose
Delete the Coffer account and server-side Cloud state
Data sent or returned
Phase one sends the account session token. After the local handoff, finalization sends a temporary opaque receipt without workspace data. The browser's local financial data is deliberately retained.
Triggered by
User confirms account deletion in Settings; finalization and retries run automatically after the local handoff
Opt-in
Yes
Destination
buy.stripe.com
Purpose
Legacy Payment Link and signed-license activation path only
Data sent or returned
Billing and payment details entered directly into Stripe's hosted page.
Triggered by
A legacy, accountless subscriber follows the old purchase path
Opt-in
Yes
Destination
/api/checkout/license (same origin)
Purpose
Verify a legacy Payment Link session and issue its signed license
Data sent or returned
Stripe Checkout session ID; a signed license is returned after server-side price and subscription checks.
Triggered by
Stripe returns an eligible legacy purchase to /activate
Opt-in
Yes
Destination
/api/cloud/blob (same origin)
Purpose
Coffer Cloud encrypted blob sync via private server-side Blob relay
Data sent or returned
Account session token (or migration-period signed license) and an encrypted AppData envelope. Coffer does not receive its passphrase or plaintext contents.
Triggered by
User enables Cloud sync in Settings → Storage
Opt-in
Yes
Destination
/api/cloud/meta (same origin)
Purpose
Check whether the encrypted Cloud copy changed before sync
Data sent or returned
Account session token (or migration-period signed license); ciphertext object existence, size, last-modified time, and ETag are returned.
Triggered by
Cloud sync checks for a newer or conflicting encrypted copy
Opt-in
Yes
Destination
/api/cloud/delete (same origin)
Purpose
Delete the encrypted Cloud copy
Data sent or returned
Account session token (or migration-period signed license). No financial plaintext is sent.
Triggered by
User explicitly removes their Cloud copy
Opt-in
Yes
Destination
huggingface.co / cdn-lfs.huggingface.co
Purpose
WebLLM model weight download
Data sent or returned
Model-file request and normal connection metadata; no transactions or category prompts.
Triggered by
User enables AI categorization in Settings
Opt-in
Yes
Destination
api.frankfurter.dev
Purpose
FX rate fetch (ECB-sourced, multi-currency display)
Data sent or returned
Requested base/quote currencies and date; no balances or transactions.
Triggered by
User selects Frankfurter in Settings → Preferences → Rate Source
Opt-in
Yes
Destination
open.er-api.com
Purpose
FX rate fetch (fallback provider, multi-currency display)
Data sent or returned
Requested base currency; no balances or transactions.
Triggered by
User selects open.er-api.com in Settings → Preferences → Rate Source
Opt-in
Yes

What still stays local

Same-origin does not mean “nothing leaves the browser.” The table lists Coffer's account, billing, entitlement, metadata, and encrypted-blob APIs explicitly. When Cloud sync is on, your browser sends an encrypted envelope to /api/cloud/blob; the server stores that ciphertext in private Vercel Blob storage. The browser does not talk directly to a public Blob URL.

Third-party analytics on the app itself (Google Analytics, Facebook Pixel, Hotjar, etc.) are not on this page because they do not exist in Coffer. The /app/* routes have no analytics scripts of any kind. The Content Security Policy keeps script execution scoped to Coffer itself.

Error tracking services (Sentry, Datadog, Bugsnag) are also absent by design. If Coffer crashes on your device, the stack trace stays on your device. We would rather fix issues based on user reports than collect them from your browser.