Privacy Policy

Last updated: 2026-05-04 · Plain English. No dark patterns.

The short version

  • We do not store your PDF, your password, your extracted text, or your transactions on any server.
  • We do not use cookies, localStorage, analytics, or trackers for your financial data.
  • We do send the sanitized text of your statement to Google's Gemini API so it can categorize transactions. You should know about this — see below.
  • When you close the browser tab, every piece of your data is gone.

What happens to your PDF, step by step

  1. You drop a PDF and (optionally) type a password. Both stay in your browser's memory. Neither is uploaded anywhere at this stage.
  2. The PDF is decrypted in your browser using pdf.js. The password is used only to unlock the file locally and is then dropped. It never reaches our server and it never reaches Google.
  3. Text is extracted from the PDF, also in your browser. The original PDF bytes are released from memory immediately afterward.
  4. The text is sanitized in your browser. Before anything leaves your device, regex patterns strip:
    • 16-digit card numbers and 15-digit Amex card numbers
    • US SSN-shaped strings
    • Long digit runs (16+ digits)
    • Account numbers near the words “account”, “acct”, “a/c”
    • Names near the words “name”, “cardholder”, “holder”
    These are replaced with placeholders like [CARD_REDACTED].
  5. The sanitized text is POSTed to our serverless function at /api/parse. This is the first time anything leaves your device.
  6. Our server forwards that text to Google's Gemini API (model: gemini-2.5-flash-lite). Google parses it into structured transactions and returns the JSON.
  7. Our server runs a second PII scrub on the merchant strings Google returns, then sends the result back to your browser.
  8. The dashboard is built and rendered in your browser. Nothing about this session is written to any database, log file, or storage anywhere.

About Google Gemini — be transparent with yourself

For the AI categorization to work, the sanitized text of your statement is sent to Google's Generative AI API. We do not control what Google does with that data on their side. You should read Google's own terms before using this app:

At the time of writing, Google's paid Gemini API tier states that prompts and responses are not used to improve their models, while the free tier may be used for that purpose. Verify the current terms yourself — they can change.

The sanitizer in this app is a regex layer, not a guarantee. It catches common PII patterns but cannot perfectly identify every piece of personal information that might appear in a statement. If your bank includes unusual identifiers in the document text, those may pass through.

What we don't do

  • No accounts. No login. No email collection.
  • No database. No object storage. No file uploads to S3 or similar.
  • No analytics for your statement data. No Google Analytics, no Mixpanel, no Segment.
  • No third-party scripts that could read your transactions in the browser.
  • No advertising trackers. No fingerprinting on financial data.
  • No server-side logging of request bodies, response bodies, passwords, or extracted text.

The only data the hosting infrastructure (Vercel) sees in normal operation is standard request metadata: your IP address, the timestamp of the request, and the response status code. We do not add any logging on top of that.

Local browser storage

We store one tiny preference in localStorage: your dark/light theme choice (key: ccsa-theme). That is the only thing this app writes to your browser. No cookies, no session storage, no IndexedDB.

Open source

You shouldn't have to take our word for any of this. The full source code is available — read it, audit it, run it yourself with your own Google API key. Specifically:

  • src/lib/pdf-extractor.ts — PDF decryption and text extraction (browser-only).
  • src/lib/sanitizer.ts — PII scrubbing patterns.
  • src/app/api/parse/route.ts — the only server-side code path. The Gemini call lives here.

Changes to this policy

If we change how data flows through the app, we update this page and the “Last updated” date. Material changes — for example, switching AI providers, or adding any form of persistence — will be called out here.