Privacy & data handling
Built privacy-first. The default is on-device processing; uploads are opt-in with short retention. Rule pack v2026.1; sources last verified 2026-08-13.
Data at a glance
| Data | When | Where it lives | How long |
|---|---|---|---|
| Course list you type/paste | Free preflight (default path) | Your browser only | Until you close the tab (session storage) |
| Saved “continue later” plan | Only if you press Save & continue later | Upstash Redis, anonymous random link | 60 days, automatic |
| Licensed report request (course rows + goal) | Only when a license holder consents and clicks | Server memory, computed once | Never stored, logged or cached |
| Email address | Sign-in link / confirmation email send | Resend (sender) · digest + one encrypted support copy on our servers | Encrypted copy: life of the account · Resend list: until unsubscribe/deletion request |
| Latest sign-in technical record (masked IP + approximate city/country) | Each time you verify a sign-in link | Upstash Redis · the full IP in a separate field | Full IP: max 30 days, automatic · masked record: life of the account |
| Session & device cookies | Only after you sign in | Your browser (HttpOnly, Secure, __Host-) | Session 30 days · device up to 1 year |
| License & order record | Only if you buy | Upstash Redis | Life of the license + records; deletable on request |
The rows below explain each category in plain language.
What we process
The free preflight runs entirely in your browser. Course data you type or paste is processed on-device by a deterministic rule engine and is not uploaded. We do not see your transcript. The two exceptions are opt-in: the optional “Save & continue later” button, and (for licensed accounts only) the licensed server report — described below. Nothing is uploaded unless you explicitly choose it.
Your account (magic-link sign-in)
If you create an account, you sign in with a one-time link we email you — there is no password. Your email address is never stored in plaintext: we keep a secret-keyed one-way digest (HMAC) of it, used to route the sign-in link and find your account. When you actually verify a sign-in link, we additionally store the address once in encrypted form (AES-256-GCM, with a key derived from our existing secret — no new secret is created) so support can see which address belongs to which account; it is readable only with that secret and never used for marketing without a separate opt-in. An account session is a random id, stored only as a hash; your browser holds it in a hardened cookie (HttpOnly, Secure, SameSite=Lax, __Host- prefixed). Sign-in links work once and expire within minutes; used and expired links open nothing. We register each signed-in browser as a “device” — a random device id plus a coarse label derived from your browser's user-agent string (for example “Chrome on Windows”) and two timestamps. You can list and remove devices yourself on the Account page; removing your current device signs that browser out. A display name is stored only if you choose to set one, and it is optional and deletable. Each verified sign-in also updates a single “last sign-in” record: a masked IP (the last segment is hidden), an approximate city/country derived from your IP (it can be wrong, especially behind a VPN or proxy), and the time. Anonymous visitors are never tracked.
The licensed server report
License holders may generate a server-computed report. When you press that button — after an explicit consent checkbox that lists exactly what is sent — your course rows (code, title, hours, and the optional level/term/status you set) and your selected goal are transmitted once over an encrypted connection. The evaluation runs in memory on the server using the same rule engine as your browser, and the course list is NOT stored, logged, cached or shared. No transcript file or PDF is ever uploaded — there is no upload mechanism. The response is not cached either. The free in-browser report, JSON download and print never require an account or a license and never transmit your courses.
What we store
For accounts: the email digest described above, one encrypted copy of the verified address (readable only with our secret, described above), your devices list, active session hashes, an optional display name, and one “last sign-in” record (masked IP, approximate IP-based location, and time; the full IP is kept separately for at most 30 days). For license holders: the license record itself — order id, verified purchase time, computed expiry, and status — plus the order verification records. If you buy, Lemon Squeezy acts as our Merchant of Record and handles the payment and buyer email; we store a one-way, secret-keyed HMAC of a buyer's email, never the raw address. If you ask for a beta-ending reminder, your address is held in a temporary verification record only until you click the confirmation link — at most 24 hours — and after you confirm we keep a small confirmation record (which consent text version you agreed to, which page you signed up from, and the date). If you tap “Save & continue later”, the saved course list (course codes, titles, hours, level, term and completed/planned status) is stored anonymously under a random link id with no account and no email attached; the random link is the only way to reach it.
Retention
Account sessions expire after 30 days (or instantly when you sign out or remove the device). Device registrations are kept for up to 1 year per browser, or until you remove them. The “last sign-in” record is overwritten at each verified sign-in; the full IP inside it is deleted automatically after at most 30 days, while the masked record lasts as long as the account. The encrypted copy of your verified address lives as long as the account and is deleted with it. Your beta-reminder verification record is deleted when you confirm or after 24 hours, and its confirmation record is kept for about 13 months. Email addresses remain in our Resend contact list until you unsubscribe or request deletion; inactive contacts are reviewed at least annually. Saved “continue later” lists are deleted automatically 60 days after creation. Licensed report requests are never retained — there is nothing to retain. Unsaved paste-input data never leaves your device and is cleared from this tab's session storage when you close the tab.
Your rights: export & deletion
You can export any report you generate (free or licensed) as JSON or print it. Licensed accounts can review and remove their devices and display name on the Account page at any time. Course data entered in the free preflight stays in your browser unless you save a link; saved links expire on their own after 60 days — to delete one sooner, contact us with its link id and we will remove it within 30 days. To delete your account, its devices, and its license records, contact us from your account email. No user impersonation is ever performed.
Subprocessors
Lemon Squeezy (payments & US sales tax, Merchant of Record · Ireland/US), Resend (transactional email — sign-in links and email confirmations, plus the reminder list you explicitly join · US), PostHog (product analytics · US), Vercel (hosting/CDN · US), and Upstash (Redis data store for anonymous saved plans, account sessions/devices, and license/order records · US). Analytics payloads never include course content or your email address.
Analytics & local storage
CPAPath keeps your random funnel id and in-progress course list in this tab's session storage so a checkout return does not erase your work. PostHog may use browser storage for privacy-limited analytics; the sign-in, email-confirmation and account pages are excluded from analytics entirely. We set no advertising cookies and share no course data with ad networks. The only cookies that persist beyond a tab are the ones you create by signing in (session and device cookies, described above) or the legacy unlock cookie for pre-account purchases. Closing the tab clears the session-scoped course list.
Contact & data requests
For access, export, correction, or deletion requests, email support@cpapath.app. Responsible party: CPAPath · support@cpapath.app. Deletion requests are handled within 30 days.
Breach response
If a data incident affecting account records or saved plans occurs, affected users are notified without undue delay and the incident is documented. Stored data is minimized by design: email digests and one encrypted support copy instead of plaintext addresses, hashed session ids instead of tokens, masked IPs with a 30-day full-IP ceiling, and saved plans that contain course lists only — no names, emails or accounts — and expire automatically within 60 days.
Important limitation
CPAPath is not an official determination. The Texas State Board of Public Accountancy (TSBPA) makes all final decisions, including whether specific course content counts.