The short version
- Everything works with no account and no network. On a phone that has never signed in, nothing you type leaves the device at all.
- An account is optional. It exists so that losing the phone does not lose the books, and so a second device can pick them up.
- Three things leave the phone, and each only when you press a button that says so: a picture you ask to have read, a recording you ask to have transcribed, and, if you have an account, your books and receipt photographs.
- Screen and touch autocapture and session replay are off. The app sends crash diagnostics, fixed product milestones and subscription events to PostHog. Configured builds use Meta install and activation measurement and RevenueCat subscription conversions to measure our advertising. Advertising identifiers are used subject to platform permission and advertising-limit settings. This website counts page views and funnel actions with PostHog without cookies, and stores an identifier for PostHog and Google Analytics only once you have said yes.
- You can delete your account, and everything in it, from inside the app.
What is kept on your phone
Your businesses, clients, invoices, estimates, line items, payments, expenses, time entries, jobs and saved rates are stored on the device, in the app's own storage. Receipt photographs and job attachments are stored as files beside them. None of this is readable by other apps.
Deleting the app removes all of it. Settings has a way to empty the books without deleting the app, and it says plainly that it cannot be undone.
If you sign in
An account is optional and off until you create one. Signing in uses Apple, Google, or a link or code sent to your email address. There is no password; the app never holds one.
The account holds:
- Your email address and a user id, so the books can be given back to the right person.
- A copy of your books, as one document, which is whatever is on your phone at the time it was last saved.
- Your receipt photographs and job attachments, in private storage. They are readable only through a link the app signs for you, which expires; there is no public address for any of them.
This is hosted on Supabase, in the United States. Rules on the database restrict every row and every file to the account that owns it.
Signing out of a phone leaves the books on it and leaves the account alone. Deleting the account removes the cloud copy and the photographs with it. See Leaving.
Reading a photograph
The receipt scanner and “Read a photo” send one picture to a vision model so that the figures on it can be filled in for you. This happens only when you press the button that says it will read the picture. Nothing is sent in the background, nothing is sent on a timer, and no screen sends a photograph you have not seen.
The picture goes to a server run for this app, which passes it to DeepSeek and returns the text. The picture is not stored on that server. What DeepSeek does with a request is governed by their own terms; at the time of writing, API traffic is not used to train their models.
The scanner keeps the photograph on your phone either way. The reading is a convenience on top of the evidence, not a replacement for it, and a build with no reader configured simply asks you to type the figures.
Speaking an invoice
The voice screen records only while your finger is on the button that says it is recording. When you press the button that says it will read it, the recording is sent to a transcription service and the words come back; you are then shown a draft to check before anything is written. The recording is not kept after that.
Reading a document
Settings › Ask about a document reads a PDF or text file on the phone and shows you the words it found before anything is sent. Only those extracted words and your question go to the model. The file itself never leaves the device.
Permissions, and what each one is for
- Camera
- Photographing receipts, and reading the words off a job sheet or delivery note.
- Photo library
- Your business logo, receipts you file as expenses, and pictures you ask the app to read.
- Microphone
- The voice screen, and only while you hold the button.
- Contacts
- Filling a client's name, email and phone from a card you pick, instead of typing it again. The app reads the card you choose; it does not read or upload your address book.
- Notifications
- Reminding you about invoices that have gone overdue. These are made on the phone. Nothing is sent to a server to produce them.
Each of these is asked for at the moment it is first needed, and the app works without any of them.
Sending an invoice to a client
Invoices and estimates are sent using your phone's own mail app or share sheet. The document is handed to the app you choose and goes from your own address. Invoice Koi does not send email on your behalf and does not keep a copy of what you sent or of who you sent it to, beyond the record in your own books.
Leaving
Settings › Account › Delete my account removes your receipt photographs from storage, then deletes the account itself. Your invoices, clients, expenses and everything else in the cloud copy go with it. It is immediate and cannot be undone.
The books on your phone are not touched by this, and keep working without an account. If you want those gone too, delete the app, or use the option in Settings to empty it.
Settings › Import and export writes the whole book to a file first, if you want to keep a copy.
Measuring Meta app-install ads
In builds configured for Meta measurement, the Meta SDK sends app-install and activation signals so we can understand which ads bring subscribers. These signals can include a pseudonymous Meta identifier, device and app information, network information and an advertising identifier where the platform permits it. On iOS, Koi starts this measurement only after you grant the system tracking permission. You can change that choice in Settings. On Android, Koi checks whether an advertising identifier is available and respects the device's advertising-limit setting.
RevenueCat receives the matching identifiers and sends production trial, purchase and renewal events, including subscription value, to Meta. Automatic purchase logging in the Meta SDK is disabled to avoid counting the same subscription twice. Invoice contents, client details from your books and card details are not sent through this measurement. Account email and phone number are not added as Meta matching attributes by Koi.
The mobile PostHog reporter receives a fixed measurement status, using its existing anonymous funnel identity. It does not receive advertising identifiers from the mobile Meta bridge. RevenueCat's server subscription events can include subscriber attributes; their exact delivered properties are checked separately. Meta measurement is disabled in Debug builds and in builds without the InvoiceKoi Meta configuration. Sandbox subscription conversions use separate destinations when configured.
Meta processes the signals under its Privacy Policy. This measurement does not display advertising inside Koi.
Crash reports and product milestones
The app uses PostHog for crash reporting, fixed product milestones and subscription measurement. These include whether the paywall was shown, which plan or trial option was chosen, and whether a purchase was completed, cancelled or failed. It also records the first observed app opening, trial entitlement activation, the first invoice issued, and a repeat invoice issue. Each of those four milestones is recorded at most once per local installation. Fixed-choice events also measure setup steps, document creation and sending, payment milestones, visits to named app features, document filters, report controls and currency-selection actions. Send outcomes distinguish a cancellation, unavailable service, plan requirement, failure and hand-off; duration is grouped into broad time bands. Demo use is labelled separately. These events do not include typed searches or the currency amounts in your books.
Automatic screen, touch and app-lifecycle capture are off. Session replay is off. The mobile reporter does not create person profiles, enrich IP-based location or run surveys. Product milestones use a fixed list of values and cannot contain a client name, invoice number, amount, filename or document text. A crash report can contain the error message and the names of the software components involved, so it can be diagnosed; it does not include the contents of your books by design.
RevenueCat sends production subscription events to PostHog, including trial starts and conversions, purchases, renewals, cancellations and billing adjustments. These records include pseudonymous customer and transaction identifiers, product and store information, timestamps, subscription status and revenue in US dollars. An anonymous analytics identifier links these events to the app's paywall funnel. RevenueCat can maintain subscription status on a pseudonymous analytics profile. Subscriber attributes are not enabled as person properties. No invoice contents, customer names from your books or card details are sent through this integration. Sandbox subscription events are excluded.
This website
Everything above is about the app. This site is a separate thing, and it is measured, because otherwise there is no way to know which of these pages is worth writing.
It uses two tools, and the banner's one answer covers both. PostHog counts every visit, and does it without cookies unless you accept them. Google Analytics runs too, but until you accept it stores nothing and reports nothing.
Before you answer, and after you decline, nothing from either is stored on your device. PostHog still counts the visit. To tell one visitor from another it makes a one-way hash, on its own servers, of your network address, your browser's description of itself and this site's address, mixed with a random value that PostHog deletes at the end of each day. The hash cannot be turned back into the address, and it changes every day, so the same person on two days counts as two visitors. What is sent to Google carries no identifier that would let one visit be joined to another.
If you accept, both keep an identifier on your device, so that coming back is recognised as the same reader rather than counted as a new one: Google Analytics in two cookies, PostHog in this browser's storage. If you decline, that is remembered too, and you are not asked again for six months.
What the site records, either way:
- The page you are on, and the site or search engine that sent you to
it, without anything after the "?" in either address. Campaign labels
from the link that brought you are kept; advertising click identifiers
such as
gclidandfbclidare dropped. Not what you typed into the page. - Your country, worked out by Google from your network address. PostHog does not look up your location. Neither stores the address itself.
- Whether you are on a phone, a tablet or a desktop, the browser, its language and time zone, and the screen size.
- Whether you viewed pricing, played a demo, chose a plan, followed a call to action, started the generator, opened its PDF print dialogue or joined the launch list (the phone you chose, never the address), and how you answered this banner.
PostHog processes these events in the United States, and keeps them for
one year. They reach it through this site's own address
(/pond), which passes them on to PostHog unchanged; that is
also why your browser can send this site's cookies along with them, which
PostHog does not use. Google Analytics processes its events under
Google's privacy policy.
The cookies and stored values behind that, in full:
| Name | What it is for | How long it lasts |
|---|---|---|
_ga |
A cookie set by Google Analytics, only if you accept. It tells a reader who has come back from a reader who is here for the first time. | 2 years |
_ga_SMR6KELJDM |
A cookie set by Google Analytics, only if you accept. It holds the state of the visit you are on, so that one visit is not counted as several. | 2 years |
ph_koi |
Set by PostHog, only if you accept. Not a cookie: it is kept in this browser's local storage, with a copy for the current visit in session storage. It holds a random identifier for this browser and the current visit, so a reader who comes back is recognised. | Until your answer expires after 6 months, or you decline |
ph_koi_consent |
PostHog's copy of your answer, written only once you have accepted. Kept in local storage. | Until your answer expires after 6 months, or you decline |
ph_koi_* |
Short-lived values, such as ph_koi_window_id, that PostHog uses to tell one open tab from another during a visit, only if you accept. Kept in session storage. |
Until you close the tab |
koi-consent |
Your answer to the banner, and the date you gave it, which both tools follow. Not a cookie: it is kept in this browser's local storage, is written whichever way you answer, and is never sent anywhere. | 6 months, then the banner asks again |
koi-campaign |
The campaign label from the address that brought you here, so the rest of the visit can be attributed to it. Not a cookie, and not an identifier: it is kept in session storage and holds nothing about you. | Until you close the tab |
Nothing you type into the free invoice generator is part of that. The generator runs entirely in your browser, and the invoice, your logo and your client's details stay in the page and in your browser's own storage. They are never sent to us, to PostHog or to Google. PostHog's automatic capture of clicks and text, session replay and heatmaps are all off.
Advertising features are off whichever you choose. Saying yes buys a visitor count that recognises a return visit, and nothing else: no Google Signals, no ad personalisation, and nothing collected here is used to follow you onto another site.
You can change your mind at any time: from the button below, or from "Cookie settings" at the foot of any page on this site. Declining after having accepted deletes the two Google Analytics cookies and PostHog's stored values rather than only stopping new ones. A content blocker or a browser with tracking protection may stop either tool, and the site works exactly the same either way.
The launch list
While the app is waiting for the App Store and Google Play, this site offers to email you the day it can be installed. If you leave an address for that, this is everything that happens to it.
- What is kept: the address, which phone you asked about, which of the site's two countries you signed up from, the page the form was on, and the time. Not your name, and not your network address: to stop the form being flooded, a one-way scrambled form of the network address is counted for the hour it arrives in and deleted within two.
- What it is for: one email, sent the day the app is on the store you chose. It says where to get it and nothing else.
- When it is deleted: straight after that email is sent. If you chose both phones, the address stays until the second store has it too.
- Who else sees it: nobody. It is not shared, sold or added to any other list. It is stored on Supabase, in the United States, and the one email is sent through Resend.
- Changing your mind: write to support@invoicekoi.com from that address and it is deleted without the email being sent.
Children
Invoice Koi is a tool for running a trade business. It is not directed at children and is not designed for them.
Changes
If what the app does with your information changes, this page changes with it, and the date at the top changes too. Material changes will be described in the app's release notes rather than only here.
Asking
Questions about any of this, or a request about your own data, go to support@invoicekoi.com.