Privacy Policy
Last updated
FullFi is a ledger for your money, so we've designed it to know as little about you as possible. We protect what it does keep as carefully as we can. This policy explains what we store, why we store it, and the choices you have.
The short version
- We don't ask for your email address, your name, or your private keys to sign you in.
- The descriptive parts of your records are encrypted with a key unique to your workspace. That covers names, descriptions, merchants, notes, imported files, and the receipts and documents you upload.
- FullFi is read-only. It never moves money and never needs access that would let it.
- We don't sell your data, show ads, or use advertising or analytics trackers.
- You can download a copy of your data, and delete your workspace and account, yourself in Settings.
What we collect
To sign you in
- Google or GitHub: the account identifier the provider gives us. We request no email or profile access, so the provider shares neither.
- Ethereum wallet: your public wallet address. Signing in asks your wallet to sign a message. That signature never sends a transaction, and we never see your private key.
- When each sign-in method was linked and last used.
To keep you signed in
A session record with a hashed version of your session token, when it started, its expiry, and when it was last used, to the nearest hour or so. We never store the token itself, so the database alone can't be used to sign in as you.
So you can tell your devices apart in Settings, each session also keeps the kind of browser (such as Firefox) and operating system (such as Windows) it signed in from, read from what your browser sends. We keep only those two words: no browser or system versions, no device model, and not the rest of what the browser sends. We don't store your IP address or your location. From Settings you can sign out any other device, or all of them.
Activity history
A record of security and bookkeeping actions, so you can see what happened to your account and your ledger. It covers signing in and out (with the kind of browser and operating system, as above), adding or removing a sign-in method, signing out another device or all of them, importing or undoing a file, pointing a file at another account before importing it, changing a transaction's category or status, voiding or restoring a transaction, adding or changing a transaction's note, linking or unlinking a transfer, linking, unlinking, or setting aside a bridge between your wallets, adding or removing a filing rule, recording an exchange rate, fetching exchange rates, turning fetched rates and prices or the daily sync on or off, asking for a wallet sync or a rate fetch to run in the background, linking an imported row or receipt to a transaction you already had, unlinking it, or keeping them separate, creating, renaming, archiving, adding, or removing a tag, creating, renaming, or archiving a project or department, putting a transaction or part of a split in one or taking it out, turning expense approvals on, off, or changing them, submitting an expense for approval, approving or rejecting it, uploading, attaching, detaching, or archiving a document, tracking, syncing, or no longer tracking a wallet, reconciling an account against a statement or undoing it, changing who owns an account or how much of it is yours, marking a category essential or discretionary, setting or clearing what an investment cost, creating or revoking an invite link, joining a workspace, changing a member's role, removing a member or leaving, changing how much FullFi does on its own, and downloading an export of your data. Each entry holds only the kind of action, when it happened, who did it, and internal identifiers and counts. It never holds amounts, descriptions, notes, wallet addresses, file names, or file contents. Entries can't be edited once written, and are only erased when you delete your account. Settings shows your recent sign-in activity.
What you put in FullFi
Accounts (with who owns each one, how much of it is yours, and from which day), tracked wallets, transactions, categories (and whether you mark them essential or discretionary), tags, projects and departments and which transactions (or parts of a split) are in them, expense approvals (who submitted each expense, who approved or rejected it and when, and any comment they left, which is encrypted like your other text), budgets, goals and reserved amounts, filing rules, what you tell FullFi an investment cost, exchange rates and crypto prices you enter or that FullFi fetches for you, files you import, such as bank CSV exports and OFX, QFX, or QIF statements, and documents you upload, such as receipts, invoices, statements, and emails (PDF, image, or plain text files). We store this to show you your ledger, and for no other purpose. What-if scenarios on the forecast are not stored: they live only in the page address in your browser.
- Encrypted: names, descriptions, merchants, notes, account details, the legal owner, beneficial owner, and custodian you name for an account, the files you upload, and each row imported from them. Uploaded documents are encrypted whole, file name included. They're encrypted before they reach the database, with a key that belongs to your workspace. When you change a note, its earlier wording is kept, encrypted the same way, so you can see what it said before.
- Searching your transactions: FullFi decrypts them on our servers only while it answers the search. It keeps no copy of your search words and no searchable version of your text. The words are part of the page address, so your browser keeps them in its history like any other search.
- Readable by our servers about a document: its file type, its size, and when it was uploaded. To spot the same file uploaded twice, we also keep a fingerprint computed with your workspace's key. It can't be compared with the same file in another workspace, or checked against a known file without that key.
- Readable by our servers about your records: amounts (including the cost you set for an investment), your share of an account and the day it starts, currencies, exchange rates and prices, dates, and whether something is settled, pending, or expected. Keeping these readable lets FullFi calculate totals, balances, and reports. On their own they aren't linked to any readable description.
- Suggested recurring items: FullFi looks for bills and income that repeat in your transactions and suggests them on the Recurring page. This happens on our servers each time you open it, and the suggestions aren't stored. If you dismiss one, we keep a fingerprint computed with your workspace's key so it doesn't come back. It doesn't contain the merchant or the amount.
- Needs attention: FullFi lists what in your ledger is worth a look, such as transactions to file or a budget over its limit. The list is worked out from your ledger on our servers each time it's shown, and isn't stored. If you dismiss or snooze an item, we keep which kind of item it was, when, and fingerprints computed with your workspace's key, so it stays hidden until something about it changes. They don't contain names or amounts. Everyone in the workspace sees the same hidden items.
- Statement reconciliations: when you check an account against a statement, we keep the statement's dates and balances, which transactions you marked as cleared, and any adjustment you chose to post. Like your other amounts and dates, these are readable by our servers and aren't linked to any readable description. Undoing a reconciliation keeps it in the history.
- Statement accounts: an OFX or QFX statement names the bank account or card it's for. That number stays inside the encrypted file. To suggest which of your accounts the next statement for it goes into, we keep a fingerprint of it computed with your workspace's key, which can't be turned back into the number.
- Matched sources: when an imported row or a receipt looks like a transaction you already have, we keep which transaction it matched, how sure the match was (a number from 0 to 1), short codes for why (such as "same amount" or "same day"), and whether it was linked, kept separate, or unlinked. Merchant names are compared in memory and never stored with the match.
- Workspace settings: your base currency and timezone, how much FullFi does on its own (whether it links matches itself or asks first), and whether AI import, fetched rates and prices, and the daily sync are on. The workspace name is encrypted.
- Background work: while a wallet sync or a rate fetch runs in the background, we keep what it is working on (by internal identifier), how far it has got (block numbers or a count of requests), how many times it was tried, and a short error code if it failed. It never holds an amount, a description, or a wallet address. Each one is reused the next time the same work runs, and it is erased with the workspace.
- Your preferences: where you are in first-time setup, which tips you've dismissed, and which sections you've chosen to show. These belong to you rather than a workspace, hold nothing about your money, and are deleted with your account.
- Quick entry: the line you type is read in your browser, and only the transaction it describes is sent when you press Record, like the full form. The text itself isn't kept.
Shared workspaces
A workspace can have more than one member, such as a household. An owner or admin invites someone by sending them a link; FullFi sends nothing itself, and matches no email address, because it has none.
- Invite links: the link holds a random secret. We keep only a hashed version of it, so the database alone can't be used to join. A link works once, for 48 hours, and can be revoked. We keep each invite's role, who created it, when it expires, and whether it was used or revoked, as the record of who invited whom.
- Members: each member's role and when they joined. The name the inviter gave them, if any, is encrypted with the workspace key. Members see each other's names and roles, and everything in the workspace.
- Removing a member, or leaving, ends their access. What they recorded stays in the workspace, and still shows who recorded it.
AI import
AI import is off until someone in your workspace turns it on in Settings. While it's off, nothing is sent to an AI provider.
When it's on and you import a PDF, photo, screenshot, or text, FullFi sends that file to OpenRouter, which passes it to the AI model shown in Settings to read the transactions in it. To suggest categories, FullFi also sends each found transaction's description and your category names. FullFi asks OpenRouter to use only providers that don't keep your data to train models, and, by default, only those that don't keep it at all. Nothing is added to your ledger until you review it.
- Encrypted: what the AI read from the document, and the descriptions you confirm.
- Readable by our servers: which model read the document and when, how sure it was, the dates and amounts it found, and whether you added, edited, or set aside each one. Like your other amounts and dates, these aren't linked to any readable description.
Wallets you track
You can track a crypto wallet by pasting its public address. Tracking needs no signature and no private key, and it's separate from signing in with a wallet. A sign-in wallet is tracked only if you choose to.
- Encrypted: the wallet address and its name.
- A keyed fingerprint of the address: it lets FullFi stop you from tracking the same wallet twice. Without your workspace key, it reveals nothing about the address.
- Readable by our servers: the network, the balances read from it, and the block number and time of each reading, like other amounts and dates.
- Each balance reading is kept unchanged, encrypted, as the source of the ledger entry it created.
- Solana transactions: for a Solana wallet, each transaction that changed what it holds is kept unchanged and encrypted, with its signature, slot, fee and who paid it, the programs it called, and every address's change in SOL and tokens. Its amounts, slot, and finality are readable by our servers, like other amounts and dates. A keyed fingerprint of the signature stops it from being counted twice. FullFi creates an expense category for network fees the first time it needs one.
- Token transfers to or from the wallet: each one is kept unchanged and encrypted, with its transaction hash, block, token contract, the other address, and the amount. Its amount, token, block number, and finality are readable by our servers, like other amounts and dates. A keyed fingerprint of the transaction stops it from being counted twice.
- Uniswap liquidity positions the wallet holds: each position's id, pool, tokens, and price range are encrypted, with a keyed fingerprint that stops it from being tracked twice. Each reading of a position and each deposit, withdrawal, or fee collection is kept unchanged and encrypted, with its block and transaction. What the position holds, its uncollected and collected fees, the pool's price, whether it was in range, and the block number and time are readable by our servers, like other amounts and dates.
- Aave lending positions the wallet holds: for each asset the wallet supplies or borrows on Aave, the market and token contracts are encrypted, with a keyed fingerprint that stops it from being tracked twice. Each reading and each supply, withdrawal, borrow, repayment, or liquidation is kept unchanged and encrypted, with its block and transaction. What is supplied and borrowed, the interest in it, the market's rates and price, your health factor, and the block number and time are readable by our servers, like other amounts and dates.
- Staking rewards: when a staking token such as Lido's stETH grows in the wallet, the growth is recorded as income from its balance reading. FullFi creates income and expense categories for lending interest, borrowing interest, staking rewards, and bridge fees the first time it needs them, and remembers which ones they are.
- Wraps: when the wallet wraps a network's own coin into its wrapped token (ETH into WETH, BNB into WBNB, AVAX into WAVAX, xDAI into WXDAI), or stETH into wstETH, or unwraps it, the conversion is recorded with its two assets, amounts, block, and time, readable by our servers like other amounts and dates. The log it came from is kept unchanged and encrypted, with its transaction, and a keyed fingerprint stops it from being counted twice. On Arbitrum, zkSync Era, and Scroll, FullFi also asks the network who sent a transaction that created WETH, to tell your own wrap from a bridge.
- Bridges: when the wallet sends a listed token to a known bridge contract, FullFi records that it is in transit: which bridge, the token, the amount, the block, and the time. When the same token arrives in another of your wallets on another network, FullFi records the match: the arrival, its amount, the fee the bridge kept, how sure the match is, and whether you or FullFi made it. These are readable by our servers, like other amounts and dates. A keyed fingerprint of the transaction stops it from being counted twice.
To read balances, token transfers, wraps, liquidity positions, and lending positions, FullFi sends the address to a blockchain data provider (an RPC endpoint) for that network: one provider per network FullFi reads (Ethereum, Base, Arbitrum One, OP Mainnet, Polygon, zkSync Era, BNB Smart Chain, Avalanche C-Chain, Linea, Scroll, Gnosis, and Solana), and only for the network the wallet is on. Blockchain data is public, but the provider can see which addresses FullFi asks about. FullFi reads the chain only when you press Sync now, right after you add a wallet, or once a day if someone in your workspace turned on the daily sync in Settings.
If this server is set up with an Etherscan API key, FullFi also reads transfers of a network's own coin (such as ETH) and the gas fees each transaction paid from Etherscan, a block explorer. For that, it sends the address of each EVM wallet you track to Etherscan, with the network and a range of blocks, from our servers. It never sends an amount, a name, or anything else about you. The Wallets page says when this is on.
Exchange rates and prices FullFi fetches
Fetching exchange rates and crypto prices is off until someone in your workspace turns it on in Settings, once for exchange rates and once for crypto prices. While it's off, FullFi asks no one for rates.
When it's on and a report needs a rate you haven't entered, you press Fetch missing rates, or the daily sync runs (if turned on), FullFi's servers ask for it: exchange rates from Frankfurter, which serves the European Central Bank's reference rates, and crypto prices from CoinGecko. Each request names only currency or asset codes, such as USD and CAD or a token's chain and contract, and a range of dates. It never includes an amount, a balance, an account, a wallet address, or anything about you, and it comes from our servers, not your browser. The provider can still tell that someone uses those currencies or holds those assets on those dates, which is why it's your choice.
- Readable by our servers: each fetched rate, its date, where it came from, and how sure FullFi is of it, like the rates you enter. A fetched rate is kept unchanged, so reports that used it don't move, and a rate you enter for the same day takes its place.
When you contact us
If you use the contact form or email us, we receive your name (if you give it), your email address, and your message. We use them only to reply.
Technical data
Like any website, our hosting provider processes technical information, such as IP addresses and request details, to deliver pages and protect the service from abuse. We don't use it to profile you.
To slow down automated abuse, we count attempts to sign in and to send the contact form. Each count is filed under a keyed hash of your IP address, never the address itself, and is deleted within two days.
What we don't collect
- Bank or card login credentials. FullFi doesn't connect to your bank with your password.
- Private keys or recovery phrases. Never.
- Advertising identifiers, analytics trackers, or data from other websites.
How your data is protected
- Encryption in transit: every connection to FullFi uses HTTPS.
- Encryption at rest: besides database-level encryption, descriptive data is encrypted by the application with a key unique to your workspace. Workspace keys are themselves encrypted with a master key that is stored separately from the database. Each encrypted value is bound to the exact record it belongs to, so it can't be copied elsewhere and decrypted.
- Access control: every request is checked on the server against your membership of the workspace it touches and what your role there allows. Viewers and auditors can't change anything.
- Logs: our logs record internal identifiers and error codes. They never record amounts, balances, descriptions, or the contents of your files.
No system is perfectly secure. If we learn of a breach that affects your data, we'll tell you without undue delay.
Cookies
FullFi uses only the cookies it needs to work:
- Session: keeps you signed in. It lasts 30 days and renews while you use FullFi.
- Sign-in state: protects Google and GitHub sign-in from forgery. It lasts 10 minutes.
- Theme: remembers whether you chose light or dark. It's set only if you pick one.
- Open workspace: remembers which of your workspaces is open, if you belong to more than one. Your membership is checked on every request, so it can't open anyone else's. It's removed when you sign out.
- Invite: if you open an invite link while signed out, it keeps the link for 15 minutes so you come back to it after signing in.
- Quick entry account: remembers which account you last used in quick entry, so you don't have to name it every time. It holds only an internal identifier, never the account's name.
There are no advertising or analytics cookies.
On your device
FullFi can be installed as an app. To make that work, your browser runs a small FullFi service worker. It stores FullFi's own code and an offline screen on your device, so the app loads quickly and can tell you when you've lost your connection. It never stores your records, balances, pages you've viewed, or anything you've entered. You can remove it by uninstalling the app or clearing site data for fullfi.app in your browser.
Who else processes your data
We use a small number of providers to run FullFi. Each one processes data only to provide its service to us.
- Neon: hosts our database.
- Netlify: hosts the application and serves its pages.
- Resend: delivers messages sent through the contact form.
- Google and GitHub: only if you choose them to sign in.
- Blockchain RPC providers: receive the public addresses of wallets you track, to read their balances, token transfers, liquidity positions, and lending positions. For a Solana wallet, the Solana RPC provider this server is set up with also receives the addresses of the wallet's token accounts and the signatures of its transactions, to read them. Uncollected fees are read with a simulated call that the provider runs and discards: nothing is signed or sent.
- Etherscan: only if this server is set up with an Etherscan API key. It receives the public addresses of EVM wallets you track, to read their native coin transfers and gas fees.
- OpenRouter and the AI model providers it routes to: only if you turn on AI import, and only for the files you import with it, as described above.
- Frankfurter and CoinGecko: only if you turn on fetched exchange rates or crypto prices, and only currency or asset codes and dates, as described above.
FullFi sends nothing else to AI providers.
We don't sell, rent, or trade your data. We disclose it only if the law requires us to, and only as much as it requires.
How long we keep it
We keep your data while your account exists. To protect your history, normal use never erases financial records. Archiving, voiding, and excluding keep the record and mark it. An archived document stays stored, encrypted, until your account is deleted. The activity history is kept for as long as your account exists. Sessions expire on their own, and sign-in nonces are single-use and short-lived. Contact messages stay in our inbox as long as we need them to help you.
Getting a copy of your data
The owner or an admin of a workspace can download a copy of everything in it from Settings, under Export your data, at any time:
- The data export: one spreadsheet-ready CSV file for each kind of record (accounts and categories, who owns each account, transactions and their ledger lines, tags, projects and departments and what's in them, expense approvals and their comments, budgets, goals and reserved amounts, recurring items, filing rules, exchange rates, tracked wallets, their readings, wraps, bridges, and their liquidity and lending positions, imported rows and other sources, documents and what AI read from them, members and invite links, and the activity history), plus a file that describes them for other apps. It also holds your own account records, which belong to you rather than the workspace: your interface preferences, which kinds of sign-in you use, and your sessions with their browser and operating system. Session secrets and the account ids from Google, GitHub, or your wallet are left out.
- Your files: the documents you uploaded and the original files you imported, under their own names. They come as a separate download, split into parts of up to 4 MB when there are many.
Your data is decrypted on our servers with your workspace key and sent straight to your browser as it's read. The decrypted copy is never stored on our side. Each download is recorded in the activity history, without its contents. Once it's on your device, the copy is no longer encrypted, so keep it somewhere safe.
Deleting your account
You can delete your workspace and account at any time from the bottom of Settings. If other people belong to your workspace, remove them under Members first, so nobody loses a shared ledger without notice. If you belong to someone else's workspace, leave it first. You type your workspace's name to confirm, and then:
- Your workspace's encryption key is destroyed first. From that moment, nothing encrypted with it can be read again.
- Everything in your workspace is erased, in one step: accounts and their ownership history, transactions and their history, imported files and every row from them, uploaded documents, tracked wallets with their balance readings, wraps, bridges, and liquidity and lending positions, budgets, goals, tags, projects and departments, expense approvals, filing rules, exchange rates, and the activity history.
- Your account is erased: your sign-in methods, sessions, and sign-in history.
It happens at once and can't be undone. You're signed out, and signing in again starts a new, empty account.
If you were a member of a workspace you left, its records may still show that you recorded them. Those records belong to its other members, so they stay. What stays of you is an anonymous identifier with no sign-in methods, which can't be used to sign in.
We don't keep a record of the deletion. Any such record would have to identify you, which would defeat the point. Our database provider keeps a short recovery history of the database. Copies of your data in it are encrypted and leave it as that history expires, and we never restore them to bring an account back.
Your choices
You can download a copy of your data yourself, as described above. You can also ask us to:
- correct something you can't fix yourself in FullFi,
- explain how your data is used.
You can delete your account and its data yourself, as described above. For anything else, email hello@fullfi.app. Because we don't know your email address, we'll ask you to confirm the request while signed in, so nobody else can make it on your behalf.
Children
FullFi isn't intended for anyone under 16, and we don't knowingly collect their data.
Changes to this policy
If we change this policy, we'll update the date at the top. If a change affects how your data is used, we'll tell you in FullFi before it takes effect.
Contact
Questions about privacy: hello@fullfi.app.