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.