The month-end pack that assembles itself: end the four rounds of "can you also send..."
Every statement, bill and payroll report filed the day it lands, and one message on the 3rd naming what is still missing, so the pack your accountant gets is complete the first time
- Your accountant's actual list of required documents, asked for once - which accounts, which reports, what the files should be called and the date they want them by
- One mailbox address that every bank, supplier, processor and payroll provider delivers to, and the willingness to change the delivery address at each of them
- The period a document covers, taken from the face of the document rather than the day it arrived, or every check is off by one month
- A machine that stays on, with about 8 GB of RAM free only if you want the optional local model for classification
- A named person who chases each row - for the portal-only bank that will never email a statement, that person is you
- A close date you are willing to hold: anything still missing on the 8th ships as a stated gap rather than delaying the pack
Version history
Every statement, bill and payroll report filed the day it lands, and one short message on the 3rd naming what is still missing — so the pack your accountant receives is complete the first time you send it.
The architecture
the same flow as text
│ one address, one scan folder
▼
[ Paperless-ngx — the archive ] OCR, type, the period it covers
│ filed as 2026 / 07 / bank-statements /
▼
[ The expected list ] one row per document you get every period
name · source · monthly or quarterly · who to chase
▼
[ n8n — the completeness check ] on the 3rd: expected against present
├─ all present → pack goes out
├─ named item absent → ONE message to you
├─ filed under wrong month → HELD, for you to correct
└─ still absent on the 8th → ships as a STATED GAP
▼
[ One expiring link ] a month, zipped, in their folder structure
plus a one-page note: what is inside, what is knowingly not
The archive files what arrives. The check is the only part that knows what didn't.
Four parts, and the valuable one is a list and a loop. Everything else is storage. The archive answers "what do I have". The check answers "what am I short". Only the second question ends the email rounds.
The problem
Your books are not late because the accounting is hard. They are late because a document is missing, and nobody knew which one until somebody went looking. A well-run month-end close on a small business takes 4–8 hours of bookkeeper time, and the working target is to have the month closed by day 10. When a close routinely runs past the 15th, the delay traces back to missing receipts and unanswered questions rather than to the bookkeeping itself.
The failure has a shape, and it is always the same shape. You send what you can find. Your accountant reviews it and asks for what was missing, plus clarification on three items. You send two of the three. They start the work, hit a specific gap, and ask again. Somewhere around the fourth round everything arrives at once in an email titled EVERYTHING, three attachments of which are duplicates of things you already sent.
Each of those rounds is an email your bookkeeper writes at their hourly rate, and each one pushes your numbers a week further from the month they describe. That is the part that actually costs you. Figures that land after the 15th are too stale to change anything except the tax return — by mid-February, January is history.
Underneath it is a vocabulary problem. When your accountant says "bank statements" they mean every account, every month, for the whole period. You hear it as the main business account, and you send six months because you could not find the rest. Neither of you is wrong. Nobody wrote the list down.
The shelf has nothing on it for this. Your accounting suite sells you a portal to upload into — it will happily accept an incomplete month and say nothing. Document management tools file what arrives, and are silent about what did not. The one question that matters, what should be here for July that is not here, is not a product. It is four parts, and if you already run a document archive you own two of them.
Tool choices — and why
Paperless-ngx (GPL-3.0, 44k stars, commit today) is the archive, and it already does three of the four jobs. Its mail rules fetch attachments straight out of a mailbox on a schedule. Its storage paths are Jinja templates, so {{ created_year }}/{{ created_month }}/{{ document_type }} produces your accountant's folder structure without you ever naming a file. And its share link bundles are the handover: select a month in the bulk editor, it builds a ZIP in the background and gives you a single public link with an optional expiry. No attachment size limit, no cloud-drive invitation for someone who does not want another login.
If you built the receipt and invoice intake blueprint, this is already running and this one hangs off it. If not, install it for this and you get the archive as a side effect.
n8n (Sustainable Use License, free for internal business use, 200k stars, commit today) is the check. On a schedule it queries the Paperless API once per expected row — document type, storage path, the month — and counts what comes back. That is the entire logic. If it feels too small to need a workflow tool, use a cron job and forty lines of Python; the point is the list, not the runner.
The expected list is the actual product, and it does not need a database. At eight to fifteen rows, a YAML file next to the workflow is enough and easier to review in a diff. Grist (Apache-2.0, 11k stars, commit today) earns its place when someone other than you maintains the list, or when you want the "who to chase" column to be a real contact rather than a note to self.
Classification: try the free one first. Paperless-ngx ships an Auto matching algorithm that learns document types and correspondents from what you have already filed by hand. Forty documents of training is usually enough for statements and payroll reports, which arrive from the same sender in the same layout every month. Only when it plateaus is a model worth adding: paperless-ai (MIT, 5.9k stars, commit today) or paperless-gpt (MIT, 2.6k stars, commit today), both pointed at a local model through Ollama (MIT, 178k stars, commit today) so your bank statements stay on your box. Keep the model in the reading role. Whether a document is present is a lookup, and a lookup does not need a language model.
Monthly cost. Software €0 across the stack. Hosting is €0 extra if this shares the box already running your archive, otherwise one VPS at roughly €5–12/month. Add about 8 GB of RAM only if you take the optional local model.
If your accountant already gives you a client portal, keep it. Upload the pack there instead of sending a link. The portal is delivery; it is not the check, because it will accept an incomplete July without a word.
Setup outline
1. Ask your accountant for the real list, once. Not a checklist off the internet — which of your accounts, which reports, what they want the files called, and the date they want them by. Ten minutes on the phone removes a whole round of email every month for the rest of the relationship.
2. Route everything to one address. Open boekhouding@ or books@yourdomain and change the delivery address at every bank, supplier, payment processor and payroll provider. Paperless fetches that mailbox. Documents that arrive somewhere else are the gap you will be fixing for the next six months, so fix delivery at the source now.
3. Storage path first, document types second. Get {{ created_year }}/{{ created_month }}/{{ document_type }} right before you tune matching. The folder structure is what your accountant sees.
4. Set the period, not the arrival date. July's bank statement lands on 4 August. If the document's created date is the day it arrived, every check is off by one month and you will be chasing documents you already have. This is the single most common way this build breaks.
5. Write the expected list. One row per document you receive every period: name, source, monthly or quarterly, how it arrives, who to chase. Include the accounts you barely use. The dormant credit card is the one that goes missing.
6. Run the check on the 3rd. One query per row against the archive for last month. Present or absent, nothing cleverer.
7. One message, named items only. "Missing for July: KBC savings statement, Stripe payout report." Not a dashboard, not a percentage. A list of two things gets acted on; a completeness score gets ignored.
8. Two nudges, then stop. Day 3 and day 6. Anything still absent on the 8th ships as a stated gap. Closing on schedule with one labelled hole beats a perfect pack that arrives on the 20th, because by then the numbers cannot change a decision.
9. Send the pack as one expiring link plus a one-page note listing what is inside and what is knowingly missing. That note is what stops round two.
10. Run it silent for one month. Compare what the check says is missing against what your accountant actually asks for. Whatever they ask for that the check did not flag is a row your list is missing. Add it, then start sending.
Pitfalls — the real ones
Verified repos
Paperless-ngx — GPL-3.0, 44k stars, commit today (13/08/2026)
n8n — Sustainable Use License (free self-hosted internal use), 200k stars, commit today
Grist — Apache-2.0, 11k stars, commit today
paperless-ai — MIT, 5.9k stars, commit today
paperless-gpt — MIT, 2.6k stars, commit today
Ollama — MIT, 178k stars, commit today
Sources: Paperless-ngx documentation (mail rules, workflow triggers, share link bundles) and advanced usage (storage paths, Auto matching) · Catalyst CPA, month-end close checklist (22/05/2026: 4–8 hours per close, close by day 10, stale after the 15th) · Chaser, monthly bookkeeping checklist (14/07/2026: closes running past the 15th trace to missing records and unanswered questions) · Accountable, Belgian retention periods (10 years since 01/01/2023, 15 years for real estate) · IRS, how long should I keep records. Repo figures verified 13/08/2026.