Documentation
Privacy & your data
Financial data is personal, so it's worth knowing exactly where yours lives. The short version: as a guest, on the server only fleetingly and in your own browser durably; with an account, durably on the server under your login; with the desktop app, on your own disk and nowhere else.
Using the app as a guest
Everything works without an account. Guest mode is not a limited trial — uploads, all analytics, the assistant, favourites, manual assets and settings all behave identically. Signing up changes only where data is stored, never what you can do.
As a guest on the hosted app, your data lives in two places:
- A private server session. Your browser gets an anonymous session cookie, and everything you upload belongs to that session alone — visitors can never see each other's data. The session is ephemeral: after 12 hours of inactivity (on the deployed app) it is swept from the server, and a server restart clears it too.
- A local backup in your own browser. Your browser keeps a mirror (in IndexedDB) of what you've put in: the uploaded CSV files, your settings, manual assets and favourites. When you come back and the server session has meanwhile expired, the app notices the empty session and silently replays the backup — so a refresh, a redeploy or a week away never loses your work. One deliberate exception: API keys are never mirrored to the browser — they live only encrypted on the server.
Practically, that means:
- Same browser, same device → your portfolio is there when you return, even after long breaks.
- Different device or browser (or after clearing site data) → it isn't. The backup lives in the browser you used; nothing durable on the server identifies you as a guest.
What creating an account changes
An optional email + password account (the Account tab in ⚙ Settings, hosted app only) moves the durable copy of your data to the server:
- Your sources, settings, manual assets, favourites and encrypted API keys are stored in the server database under your account — independent of any browser, surviving browser changes and following you to any device you sign in on.
- Your password is stored only as an argon2id hash. Signing in sets an HttpOnly cookie holding a server-issued random token — the server keeps only a hash of that token, so even a leaked database couldn't impersonate you. The login lasts 30 days by default.
- While signed in, the browser mirror is not used — the server's copy is the source of truth on every device.
- Deleting the account (password-confirmed, in the same tab) permanently removes every row it owns — sources, settings, API keys, manual assets and favourites.
Starting as a guest, signing up later
You lose nothing by trying the app first: your first sign-in from a browser claims what you built there as a guest.
The story in order:
- You open the app as a guest, upload your exports, star favourites, tune settings.
- Later you create an account (or sign in for the first time) from that same browser. If the account is still empty and your guest session has data, everything the guest session owns — sources with their transactions, settings, API keys, manual assets, favourites — is moved to the account in one step, all-or-nothing.
- Any other device you sign in on now sees the same portfolio, served from the server.
Two edges worth knowing, exactly as implemented:
- The claim happens only into an empty account. If the account already has data of its own, the guest data stays with the guest session (and eventually expires) rather than being merged — nothing is overwritten.
- Signing out returns that browser to guest mode with a fresh, empty session. Your account's data stays on the server, untouched, and is there when you sign back in. The browser's own local backup from your guest days also remains in that browser and replays into the new guest session — so the machine you originally uploaded on keeps working even signed out.
API keys
LLM API keys entered in Settings are encrypted at rest on the server and are never stored in the browser — not in localStorage, not in the IndexedDB backup. They belong to your session or account and are wiped with it. If you run the app yourself, keys can also come from the server's own .env (OPENAI_API_KEY / OPENROUTER_API_KEY).
And if you'd rather not send portfolio context to any cloud model: run the assistant on Ollama or LM Studio and it never leaves your machine.
What reaches an LLM provider
Nothing, until you connect one. The hosted app deliberately configures no server-wide LLM key — every assistant feature stays inert until you enter your own API key (or point at a local model) in ⚙ Settings → Assistant. The dashboard itself — uploads, charts, performance, risk, allocation — never involves any LLM.
Once you have connected a provider and use an assistant feature (chat, the one-click reports, AI insights, smart search), the app sends your question plus the portfolio context the answer needs — holdings with weights and values, performance and risk figures, recent trades, your strategy text, and what's currently on your screen — to the provider you chose, under your key (OpenAI or OpenRouter for cloud models). Your raw CSV files are never sent — only the derived portfolio the dashboard shows. What those providers do with request data is governed by their terms, which is exactly why the choice of provider — including a fully local one — is yours.
The desktop app
Fortunest also ships as a native Mac & Windows app (the Desktop app section of the site tracks the public download). It is not a thin window onto the cloud: the complete engine — import, valuation, analytics, the assistant — runs inside the app on your computer, which makes the privacy story short. The app never sends your portfolio to the Fortunest server: what it reads from the server is market data (see the first item below — ticker symbols go out, prices come back), and the one thing it can upload is opt-in and yours to control: Social sharing, which sends only the relative-value snapshot sections you explicitly ticked (see the list below and Social & friends).
Where your data lives
Everything the app knows sits in its own data folder on your disk: a SQLite database with your transactions, sources, settings, manual assets and favourites; the local encryption key protecting any API keys you enter; and the market-data caches. On macOS that folder is ~/Library/Application Support/Fortunest, on Windows %APPDATA%\Fortunest. Back it up and you've backed up the app; delete it and everything is gone — there is no copy anywhere else.
What leaves your machine, and why
- Market data requests — tickers only. Prices, FX rates, fundamentals, news and search answers come from the Fortunest server's shared, licensed market-data cache (the server fetches from its providers and pools the result for everyone) and are cached again locally on your machine. Those requests carry ticker symbols, date ranges and your licence sign-in — a free account is enough — and nothing more: never quantities, values, or anything about your portfolio's composition beyond the symbols you look at. The server answers from its cache and stores nothing about you.
- The assistant — only where you point it. With LM Studio or Ollama the model runs on
localhostand portfolio context never leaves the machine. If you instead configure a cloud provider under your own key, the same rules as the hosted app apply — see What reaches an LLM provider. - Interest rates & macro data. The desktop build answers from a data snapshot bundled with the app — it makes no calls to external rate services.
- Social sharing — only if, and only while, you tick a section. When you tick a sharing box on the Social tab, the app uploads to the Fortunest server exactly the snapshot sections you ticked in ⚙ Settings → Social — relative values only (names, weights and percentages), never amounts — plus any posts you write there, so the friends who accepted your request can read them. Beyond the ticked sections and your posts a snapshot carries one more thing, and only when it applies: a
demo: trueflag saying the figures were computed over the built-in demo data (see Social & friends). With every sharing box off — which is how every account starts — nothing Social-related leaves the machine at all. The Social tab being available by default lets people find you and send you a friend request; it uploads nothing, and accepting a friend uploads nothing either. - Nothing else. The desktop build ships with no analytics at all — no Umami, and the anonymous usage counters the hosted app keeps are written only to the local database, where they stay. A future Pro licence will add exactly two narrow, licence-related exceptions: an occasional refresh of the signed licence token, and — for the Taxes tab, whose computation engine deliberately isn't included in the app — sending the tax inputs to the server, which computes the answer statelessly and stores nothing.
What works offline
Essentially all of it: the dashboard, performance, allocation, risk, dividends, correlations, simulations, trade recommendations, Explore, and the assistant on a local model. Price history is cached for a day; when the network is away the app simply keeps serving the last cached prices (and quietly retries in the background), so charts show the world as of your last online session. The one thing an offline session can't do is price a symbol it has never fetched before — so a fresh install wants one online session to warm its cache, and after that you can work on a plane.
Social & friends
The Social tab is the one place data of yours can become visible to other people — and only ever the people you approved, only ever the sections you ticked, and only ever relative figures. The rules, exactly as built:
- Available by default; sharing nothing by default. The tab works out of the box — you have an @handle, people can find you by it, and you can send and accept friend requests. Not one of the sharing checkboxes is ticked for you, so a new account publishes nothing at all: there is no snapshot on the server to read, and a friend you accept sees an empty profile until you decide otherwise. Being findable and being readable are two different things, and only the second one is ever on by your own hand.
- Consent is request + accept. Nobody sees anything of yours until you and they have both agreed: one side sends a friend request, the other approves it. Accepting a request is the consent to share; either side can unfriend at any time, which ends visibility in both directions immediately, and a block list is there for stronger cases.
- What friends can see: exactly the sections you ticked in ⚙ Settings → Social — each one off by default — as relative values: asset names with portfolio weights and gains in %, return curves, allocation and risk percentages, targets and drift. Plus the posts you write, your @handle and avatar, and (unless you turn its toggle off) an online dot with a last-seen time.
- One flag rides no toggle, because it is a disclaimer: a portfolio built (partly) from the built-in demo data publishes
demo: true, so friends see a "uses demo data" label beside your @handle. It qualifies the shared figures rather than adding to them, and names no file, source or amount. That flag and the ticked sections are the whole of a snapshot. - What friends can never see: amounts, currency values or quantities — no toggle shares an absolute number; your raw transactions, CSV files, account balances, API keys, chat history or settings. Sections you didn't tick are not just hidden — they are never uploaded in the first place: the shared snapshot is built on your device from the ticked sections only.
- Opting out is instant. Untick a section and friends stop seeing it immediately — every read is filtered by your current settings, not by what was last uploaded. Turning Social off entirely makes you unfindable and unreadable.
- Deletion is real. The "Delete shared data" button in ⚙ Settings → Social removes your published snapshot from the server on the spot; you can delete any post of yours (automatic trade events included). Deleting your account removes everything Social ever stored about you — profile, friendships, blocks, snapshot, posts, images and reactions.
Usage analytics & feedback
The hosted app records anonymous, cookieless usage events (which features are used, how large portfolios are as counts). Only generic values travel — never file names, tickers, amounts, queries, chat or strategy text, or emails. The same anonymous counts are mirrored into cookieless Umami page analytics; this website uses the same cookieless Umami counter and nothing else.
One exception exists, and you type it yourself: a message sent through the in-app Feedback button is stored as written (with the email field only if you fill it in), tied to nothing more than the same anonymous session id.