Data Retention & Deletion

Owner: Ivy, Founder, Koda Digital · Effective: 2026-09-03 · Updated: 2026-11-10

1. What is stored, where, and for how long

Data Location Retention Deletion mechanism
Plaid access tokens (one per linked institution) Firestore users/{uid}/plaid_tokens Until the institution is unlinked POST /remove-item calls Plaid /item/remove (revoking the token at Plaid) then deletes the document
Link metadata (Item id, institution name, link date) Firestore users/{uid}/accounts Until unlinked Deleted by POST /remove-item
Cached Plaid responses (balances, liabilities, recurring) Firestore users/{uid}/plaid_cache Served for 4–12 h; documents purged 7 days after fetch Daily scheduled job snapshotNetWorth purges expired entries; unlinking purges that Item's entries immediately
Transaction ledger (date, amount, merchant, category, account/institution), including rows imported from a Mint export The user's phone only — SQLite encrypted with SQLCipher; key in the iOS Keychain / Android Keystore (THIS_DEVICE_ONLY). On web, browser memory for the visit only. Never stored on Koda's servers — the backend passes transactions through without keeping them Until the user deletes the account or the app Kept on sign-out and when an institution is unlinked (see §2); erased with its key on account deletion; removed by uninstalling. Exportable at any time from Accounts → Export transactions
Daily net-worth totals (assets, liabilities, net worth — no account detail) Firestore users/{uid}/net_worth_history Indefinite (this is the product's history feature) Deleted on full account deletion
Manual assets entered by the user Firestore users/{uid}/manual_assets Until edited/removed by the user User action / full deletion
Bank credentials Never stored — entered only inside Plaid Link — —
Sign-in session iOS Keychain / Android Keystore (expo-secure-store), excluded from device backups Until sign-out or remote revocation Sign-out, "Sign out of every device", account deletion, or uninstall
Last net-worth summary (totals + per-account name and balance; no transactions) iOS Keychain / Android Keystore (expo-secure-store), encrypted at rest, excluded from backups Replaced on every successful load; lets the app open offline with an "as of" time Erased on sign-out and on account deletion; uninstalling removes it
Bills and balances screens Not persisted on the device; fetched on demand — —
Backend logs Google Cloud Logging 30 days (default) Automatic
Crash reports (error, stack trace, app version, device model, OS version — no account data, balances, transactions, email, screenshots or replays; IP not stored) Sentry, only when a DSN is configured Up to 90 days (Sentry plan default) Automatic expiry; can be purged from the Sentry project

Plaid's own retention of Item data is governed by Plaid's policies; revoking an Item via /item/remove ends Koda's access.

2. Deletion procedures

  • Unlink an institution: POST /remove-item { item_id } — revokes at Plaid, deletes the token and all cached data for the Item. Exposed in the app's Accounts screen. The phone keeps that bank's transactions, so spending history survives disconnecting or re-linking it; they keep the institution name they were recorded under. Deleting the account removes them.
  • Full deletion (close the account) — self-service in the app: Accounts → Delete account and all data, confirmed twice. The backend (POST /delete-account) revokes every Item at Plaid via /item/remove, deletes the entire users/{uid} document tree — tokens, link metadata, cache, net-worth history and manual assets — and then deletes the Firebase Authentication user, which ends every session on every device. The app then erases the transaction ledger and its encryption key, its on-device session and the net-worth summary. A copy of the ledger on another of the user's devices is erased when that device's app is deleted; Koda has no way to reach it. The daily snapshot finds nothing to record once the tree is gone. A Plaid revocation that fails is reported back rather than silently skipped, so data is never left linked without the user knowing.
  • Deletion by request: anyone who cannot use the app can email contact-us@kodadigital.ai; the operator performs the same deletion within 7 days.
  • Backups: Firestore is not exported or backed up elsewhere, so deletion is complete once the documents are removed. Crash reports in Sentry hold no account data and expire on their own schedule.

3. Minimisation

Only fields needed for the product are stored. The transaction ledger (on the phone) keeps the fields the Activity and Trends screens display plus the identifiers needed to reconcile updates from Plaid; of Plaid's location data only city and region are kept, never street address or coordinates. Net-worth history keeps three totals per day, never account-level detail. Crash reports are sent with sendDefaultPii off, no user identity attached, no session replay or screenshots, and breadcrumbs stripped of request bodies and URLs' query strings. The version check at launch (GET /app-config) is unauthenticated and returns only a version string; it receives no user data.