Paths are relative to the app’s root. With APP_BASE_PATH set (for example /app), every path starts with that prefix. Every path needs sign-in except the icons listed under Install files. Where a page takes month, the value is YYYY-MM and defaults to the current month (UTC).
Main navigation
Every page has the same Add button and four links, each with an icon. On a wide screen (880 pixels or more) they are in a sidebar, with Add first, above the links. On a narrow screen they are in a tab bar fixed to the bottom of the screen, with Add as the round button in the middle: Home, Receipts, Add, Bank, Settings. The link for the page you are on is marked.
| Link | Path | Badge | Marked on |
|---|---|---|---|
| Add | /add, or /add?kind=sales from Invoices |
Add | |
| Home | / |
Home and a file page | |
| Receipts | /receipts |
Number of items in Receipts To do, mail from new senders included | Receipts To do, Invoices, and a receipt or invoice |
| Bank | /payments |
Number of payments missing a receipt | Bank and the bank statement import |
| Settings | /settings |
Settings |
In Access mode the header also shows Sign out, which goes to /cdn-cgi/access/logout. On a phone, Sign out is at the top of Settings.
Every page ends with a short notice: check every figure, it is not tax or accounting advice, there is no warranty, and the app is not affiliated with Cloudflare or with any bank.
Bank has a To do | All switch at the top, with the count of each. To do is the default: what needs you, open items first. All is every payment in the month. Receipts keeps To do as its work queue; browsing every document is on Home, and old Receipts All links open there.
Quick find opens on every page with Cmd+K (Ctrl+K off a Mac), or / on a page without its own search field. It lists the first matches from /search.json as you type. ? shows every keyboard shortcut; see Keyboard shortcuts.
Month screens (Home’s month strip, Bank and Invoices) use the month as their title, between links to its neighbours: ‹ Aug September 2026 Oct ›.
Pages
| Path | Title | Query parameters | What it shows |
|---|---|---|---|
/ |
Home, or “Welcome” on first run | in (the folder: year:2026, vendor:<name>, client:<name>, kind:expense, kind:sales, kind:other, kind:statement, kind:package, tag:<tag>, starred or recent), q (the search), before (the cursor for older rows), open (the document shown in the preview pane), show, month, anyway, undated, changes, sent, upload, wait |
First a search field, Seller, amount, date or any word, with Save search. Then the month as a strip of three steps, described below. Then the archive: on a screen 1100 pixels wide or more, the drawer of folders (Everything, Starred, Recently opened, Saved searches, the years with their months, Kinds, Sellers, Clients, Tags, Opened lately), the list, 50 rows per page with older rows behind a cursor, and the preview pane for open, with the document’s viewer, its details, Star, its tags with Add a tag, and Note. Narrower, the list, then Folders; an opened document fills the screen with Back to the list. A year, seller or client folder starts with its overview: total in EUR, Files, Without a euro amount, Payments missing a receipt and 12 monthly bars. Download folder gets the folder or search as a ZIP. The month strip: until setup is done, the checklist Finish setting up (“1 of 5 done”): business name, Email Routing, accountant, bank account and first bank statement, each linking to where it is done, and the link “New here? See what the words mean.” to Help. On first run, the title is Welcome and the page holds the checklist and the same form as /add. Otherwise three rows, Check, Match and Send, each marked Done, Next or To do with a short status such as “1 to check, 1 undated”, “All checked”, “1 missing”, “No statement”, “All matched”, “Ready” or “Sent 24 Oct”, and one primary button for the next step: Add receipt, Start checking, Import statement or Start matching. When the month is ready, the total spent, Download ZIP (with its size), CSV and, under “Did you send it?”, Mark September as sent (with the month’s name). Before that, the same are under Download anyway, with the total spent, a box to add undated receipts, a CSV link, In the ZIP and By part. After sending, On to October ›, Download again and CSV; if the month changed since, Download changes and Download all. An alert links to overdue invoices or unverified emails, and a last line such as “2 receipts, 1 invoice dated September ›” opens Home’s list for the month. |
/month |
any | Redirects (temporarily, 302) to / with the same query string. |
|
/more |
Redirects (temporarily, 302) to /settings. |
||
/review, /review/merge |
any | Redirect (302) to Receipts To do, keeping month. |
|
/invoices |
any | Redirects (302) to Invoices (/receipts?view=all&kind=sales), keeping month. |
|
/receipts (To do, the default) |
“N to do”, or “All checked” | view=todo, month (receipts dated in the month plus every undated one), upto (rows shown, 50 more each time, up to 500), done (result banners) |
Mail from new senders first, each with Allow and Ignore (Ignore asks first). Then receipts that need a required fact and sales invoices past their due date, undated first, then the oldest, under a header such as “50 of 132 to do” with the page’s one primary, Start checking. Each row has the name, amount, date and one status. Show 50 more adds the next rows. With nothing open, “All checked” and the month’s next step. |
/receipts?view=all |
month, q, show, before |
Redirects (302) to Home with the same filter. With kind=sales, it is Invoices (below). |
|
/files/<key> |
The file’s title or name | A file that is not a receipt or invoice: an other document (its viewer, Download, and its title and date to edit), a bank statement (the PDF in the viewer when it was kept, then The rows imported as a table, and Download PDF or Download CSV), or a sent month package (The index as sent, Download the ZIP as sent, or Download the month as it is now for a month sent before v2.0.0). | |
/receipts/<id> |
The document’s seller or file name | from (todo or all), month, q: the list it was opened from; done (result banners) |
The original beside the fields. The crumb leads back to the list it came from (‹ To do, ‹ Home or ‹ Invoices). While it needs you, a Needs you stamp, the fields to fill first, and a bar at the bottom with its place (“1 of 2 to check”), Skip, Discard, More and Approve receipt (Approve invoice for a sales invoice). On a phone the bar stays above the keyboard. Approve receipt saves and opens the next open item of the same list and month; after the last, the list. Save for a ready document, with Next to check › when one waits, and Read it for an email that could not be verified. Payment? lists likely bank payments, each with Match and, when the pair is not exact, its reason. A discarded document shows Discarded, the crumb ‹ Discarded and Restore. More has two groups: the document (Read again, Move to invoices or Move to receipts, the original, Always file as) and its status. Move asks first, since it clears facts. A sales invoice shows its money in, with Paid another way?, instead of Payment?. |
/add |
Add receipts, invoices or documents | kind: sales or other (which kind is picked); added, failed (result counts); shared=1 (files shared from another app) |
One form for up to 10 files at once. What are these? picks Receipts and bills, Invoices you sent or Other documents, then a drop area and Upload. Other documents are kept and searchable on Home, named after the file with no date, and never read for amounts, matched or sent. Below the form, the email addresses to forward to, when they are set. |
/payments |
The month | month, view: todo (the default) or all, upto (To do rows shown, 50 more each time, up to 500), done (result banners, including the import’s) |
Bank rows booked in the month from completed imports, under a line for the whole month such as “4 out, 2 matched, 1 not a purchase, 1 missing”. To do lists money out with no receipt, oldest first, with a count such as “50 of 60 to do”, the page’s one primary, Start matching, and Show 50 more; with nothing open, “Every payment has a receipt.” and the month’s next step. All lists the whole month. Each row has the name, amount, date and one status: Missing, Matched with a Receipt or Invoice link, “Transfer to <account>” or “Transfer from <account>”, Not a purchase, or money in. A missing payment shows its likely receipt with Match (and the reason when the pair is not exact), a search for another receipt, and Not a purchase. Exact likely pairs are offered together with Match all. Each row’s More holds Unmatch, Needs a receipt, the account and payment ID and, on unmatched money out, the own-account pairing form. “Also missing: August (2)” links to other months. |
/import |
Import a bank statement | The bank import: a file field and Import statement. It asks which account only when it cannot tell. | |
/import/anyway |
Import anyway | import |
Adds the payments skipped as already imported, as extra payments. |
/imports/csv, /imports/csv/preview (POST) |
The column editor | Opens only when the file cannot be read automatically: rows read, problems, the mapping editor and the import button. | |
/receipts?view=all&kind=sales |
The month, or “Unpaid” or “Overdue” | month, show: review, unpaid, overdue, paid |
Sales invoices dated in the month, with Add invoice, the line “Invoiced EUR X, received EUR Y” and chips for the states that have any. Each row has the client, amount, number and one status: Needs you, Overdue, Paid or Unpaid. CSV sits next to “Check every row before sending this to your accountant.” |
/settings |
Settings | open, done (result banners) |
The sections listed below, with one Save for the page. |
/help |
Help | The words on screen, the status words, the keyboard shortcuts and every flag, each with an anchor such as /help#status-missing. |
|
/undo (POST) |
at, op and the list state |
Puts back what the action in the banner changed, and returns to the first row it brought back. |
Settings sections
In page order. Each section is a fold, closed by default, with a one-line summary next to its title. A link to /settings#<anchor> opens that section. The page has one Save at the bottom for every section.
| Section | Anchor | Summary | Contains |
|---|---|---|---|
| Business | #business |
Business name, and the number of parts once there are two | App name, business names, payment terms, new account currency, the parts of the business (Add a part), and Vendor rules (#rules). |
#email |
Receipt address, or “Off”, and the number of allowed senders | Receipt address, invoice address, forward copy address, and Email senders (#senders): allowed senders with Remove, an address box with Add, ignored senders with Stop ignoring, and Mail we didn’t keep (#mail), the latest 50 emails that were not read, with Allow. |
|
| Bank | #bank |
Number of accounts | Bank accounts with bank and currency, and Add account. |
| Sending | #sending |
Accountant name | Accountant, export file name, the note under the month download, and OneDrive when MS_CLIENT_ID is set (Connect, the folder, and Disconnect, which asks first). |
| Advanced | #advanced |
Search: how many older files are not yet searchable by their words, with Index older files (N left), 25 per press. The review and matching thresholds, the source code link, read-only deploy values, the change history, and About (#about): the no-warranty notice, the data line, the licence and the trademark lines. |
Each field is a label and an input; its help is the field’s tooltip. The line under it names the value’s source: Set in the app, Set when deployed or Built-in default. Reset shows next to a value set in the app. See Configuration.
Select several
Receipts To do, Home’s list, Invoices, Bank and the sender lists in Settings > Email have a tick box on every row, on every screen size. Ticking a row shows a bar with the count (“3 selected”), Clear and the list’s actions. Approve asks first and takes a reason. Move and the senders’ Remove ask first too.
Shift-click ticks a range, x ticks the focused row (Shift+x ticks a range), Cmd+A (Ctrl+A off a Mac) ticks every row on the page, and Esc clears. Select all N ticks every row under the list’s filter and month, across pages; above 500 it reads Select the first 500, in the list’s order. These need JavaScript; without it, the boxes and the bar work for the rows on the page.
| List | Actions |
|---|---|
| Receipts To do | Approve (receipts missing a required fact are skipped), Discard |
| Home’s list (receipts only) | Discard, Read again, Move to invoices or Move to receipts. Under Discarded, only Restore. |
| Invoices | Mark paid, Discard, Read again |
| Bank | Match (only payments with an exact likely receipt), Not a purchase, Needs a receipt, Unmatch |
| Settings > Email senders | Remove for allowed senders, Stop ignoring for ignored ones |
The banner says how many changed and how many were skipped, and offers Undo. The rows that changed leave the list, and the next open ones move up. Read again and Move call the reading model in chunks and have no Undo. See Limits for the caps.
Downloads
| Path | Query parameters | Returns |
|---|---|---|
/export.csv |
month |
Receipts CSV for the month. |
/export-sales.csv |
month |
Sales CSV for the month. |
/month/package.zip |
month, anyway, undated, changes |
Month package ZIP. |
/originals/<id> |
variant=email: the source email instead of the document. view=inline: show a PNG, JPEG or WebP image in the browser. view=raw: the PDF or picture itself, for the PDF viewer, never an email; supports Range and ETag. |
The original, as a download unless view=inline or view=raw. Never cached. |
/files.zip |
The Home folder and search: in, q, month, show |
The receipts, invoices and other documents it shows, in Year/Month folders, with 00-index.csv. Up to 900 files; a bigger folder is refused with a message to narrow it. |
/files/<key>/original |
view=raw for the viewer |
The file behind a file page. |
/files/<key>/package.zip |
The month package as it was sent. | |
/search.json |
q |
The first matches for quick find. |
Form actions
Each form posts to one of these paths and then redirects (303).
| Path | Does | Goes back to |
|---|---|---|
/accounts, /accounts/<id> |
Add or rename a bank account. | /settings#accounts |
/transfers, /transfers/<id>/undo |
Pair or undo an own-account transfer. | Bank for the month the money left, #transfers |
/receipts/bulk, /payments/bulk, /senders/bulk |
Run one bulk action on the ticked rows, or with all=1 on every row the list’s filter matches. A post without its list state is refused with 400. |
The list it came from, at the next open row, with a result banner and Undo |
/upload |
Add the files from Add, as kind expense, sales or other. One file opens its page; several go back to /add with the counts. |
The receipt, invoice or file page, or /add |
/documents |
Add another finance document with a title and a date. No page posts to it now. | Its file page |
/files/<key> |
Change an other document’s title or date. | Its file page |
/marks/star, /marks/tag, /marks/untag, /marks/note |
Star or unstar, add or remove a tag, or save a note on any document. Star and tag changes offer Undo. | Home as it was, with the document open |
/searches, /searches/<id>/delete |
Save or remove a saved search. | Home |
/settings/index |
Index the words of the next 25 older files. | /settings |
/rules |
Add a vendor rule. | The receipt it was made from, else /settings#rules |
/rules/<id>, /rules/<id>/delete |
Change or delete a vendor rule. Unknown IDs return 404; a rule with the same seller and context text returns 409. | /settings#rules |
Install files
These make the app installable. See Install the app.
| Path | Sign-in | Returns |
|---|---|---|
/manifest.webmanifest |
No | The web app manifest: APP_NAME, a short name of at most 16 characters for the home screen, the icons, an Add a receipt shortcut to /add, and the share target. It holds no data. |
/sw.js |
Yes | The service worker. It answers only two requests: a page opened while the device is offline gets the offline page, and a share to /share is stashed for /add. It caches no app data. |
/share (POST) |
Yes | The share target. The service worker normally takes the share; if it does not, the Worker redirects to /add and stores nothing. |
/favicon.svg, /apple-touch-icon.png, /icons/icon-192.png, /icons/icon-512.png, /icons/icon-maskable-512.png |
No | The app icons. They hold no data. |
Sign-in and OneDrive routes
| Path | Purpose |
|---|---|
/settings/onedrive/connect |
Starts the Microsoft sign-in. |
/settings/onedrive/callback |
Microsoft returns here after sign-in. This is the redirect URI to register in Microsoft Entra, prefixed with the app’s origin and APP_BASE_PATH. |
Responses without sign-in
| Mode | Response |
|---|---|
| Password (HTTP Basic) | 401 with a Basic challenge whose realm is APP_NAME. Sign-in also fails over plain http except on localhost, 127.0.0.1 and [::1]. |
| Cloudflare Access | 403 “Sign in through Cloudflare Access to use this app.” |
Every form post must carry an Origin header equal to the app’s origin, or it is refused with 403. Unknown paths return 404.