SEO Services
Accounting & Bookkeeping / Technical Guide
Automate Month-End Close & Transaction Categorization with n8n + Claude Step-by-Step Guide
A complete walkthrough for building an n8n + Claude pipeline that pulls bank feeds and ledger data from QuickBooks or Xero, categorizes every transaction against your chart of accounts, reconciles balances, flags anomalies, drafts journal entries, and ships a SOC 2-ready close package in two days instead of eight.
Bank feed ingest (Plaid)
QuickBooks / Xero pull
Claude categorization (COA-aware)
Reconciliation engine
Anomaly detection + JE drafts
Close-package PDF
Slack distribution + S3 archive
1. The Problem — Why Month-End Close Still Takes 8 Business Days
Every accounting team that has scaled past two entities and one currency hits the same wall: the close keeps growing in calendar days even after you’ve added another senior accountant. The bottleneck is no longer “we have too few people.” It’s that 60% of close work is mechanical — categorizing transactions, tying out balances, hunting for anomalies, drafting recurring journal entries — but it’s also high-stakes enough that nobody trusts a rule-based bot to do it cleanly. So the senior team does it manually, every single month.
Real numbers from a 200-person SaaS finance team (3 entities, 2 currencies)
| Close cycle (calendar days) | 8 days |
| Transactions reviewed manually per close | ~4,200 |
| Misclassifications caught in audit (rolling 12 mo) | 37 |
| Senior accountant hours / month on close | 120 |
| % of JE workpapers without a clear support trail | 22% |
The brutal asymmetry: roughly 85% of bank-feed transactions are repeat vendors with predictable categorization (AWS, Stripe fees, payroll, rent). They consume a disproportionate share of senior-accountant time even though the answer is the same one they gave last month. Meanwhile the 15% that genuinely need judgment — unusual vendor, mixed-purpose invoice, accrual cutoff — get the same shallow review as the easy 85% because the team is rushing.
What “automated close” actually means
It is not a rules engine that learns your COA over time and slowly improves. It’s a deterministic pipeline that does five things every cycle:
- Categorize: every transaction gets a GL account, class, and confidence score before a human looks at the ledger.
- Reconcile: bank balance vs ledger balance vs subledger balance reconcile to the cent, with breaks isolated for review.
- Flag anomalies: unusual amount, unknown vendor, duplicate invoice, period cutoff issue.
- Draft accruals & JEs: recurring entries pre-populated with calculations and source docs attached.
- Package & ship: close binder PDF generated from templates, archived to S3 with hash, distributed to controller and audit committee.
2. System Architecture
Seven components, each replaceable. The orchestration layer is self-hosted n8n so the auditor can inspect every API call that touches financial data. Postgres is the system of record for raw transactions, categorization decisions, the audit log, and approval state — the GL itself stays in QuickBooks or Xero.
The stack
Cost estimate (4,200 transactions/month, 3 entities)
| Claude Sonnet (650 hard categorizations + JE drafts) | ~$78 |
| Claude Haiku (3,550 repeat-vendor matches with cache) | ~$14 |
| Plaid (3 entities, dev tier with batched syncs) | ~$120 |
| VM (n8n + Postgres on Hetzner CCX23) | ~$48 |
| S3 + KMS (close binders, 7-year retention) | ~$22 |
| Monitoring (Grafana Cloud + Healthchecks) | ~$24 |
| Total / month | ~$306 |
A senior accountant who reclaims 80 hours per month is worth roughly $6k of fully-loaded cost. The pipeline pays for itself inside the first close, and the cumulative ROI is dominated by what the team does with those reclaimed hours — typically FP&A, board reporting, and SOC 2 evidence collection. The same orchestration layer slots into our broader AI automation services.
Bank & Ledger Ingest
Three sources feed the pipeline every night: the bank/credit-card feed via Plaid, the unreconciled transaction list from QuickBooks or Xero, and the vendor master plus chart of accounts (read once per day, cached locally). Plaid is the safety net — it catches transactions that hit the bank but never landed in QBO because of a feed glitch, which is the single most common cause of “missing $4,800” mysteries on close day.
Webhook & poll sources
- Plaid Transactions: nightly
/transactions/syncper institution. Cursor-based, idempotent. - QuickBooks Online: daily query of
Purchase,JournalEntry,Bill,CreditCardPaymentvia the v3 API. - Xero: equivalent through
BankTransactions+ManualJournalswithIf-Modified-Since. - COA + Vendors: pulled once per day, normalized into a flat lookup table the Claude prompt can reference cheaply.
Normalized transaction schema
All four sources are normalized into one row shape before they hit categorization. The source_hash is the dedupe key — same source + same external_id = same row, regardless of how many times the workflow re-runs.
source + external_id + amount + posted_at — and treat any same-day same-amount pair from the same vendor as a single match candidate, not two transactions.Claude Categorization (COA-aware)
A traditional rules-based categorizer breaks the moment marketing spins up a new SaaS subscription or HR adds a benefits vendor. Claude reads the transaction plus the chart of accounts, the vendor history, and the prior-month decision for the same counterparty, and returns a structured JSON with confidence and reasoning. High-confidence rows post automatically; low-confidence rows go to the exception queue.
The 4 categorization dimensions
Specific COA account (e.g. 6310 — Software Subscriptions).
For multi-class books — Eng, GTM, G&A, Customer Success.
Equipment, capitalized software, and threshold rules from the policy.
Service period spans month-end? Needs prepaid or accrual entry.
Categorization system prompt
The COA, class list, and capitalization policy are injected into the prompt context every run. Vendor history is supplied as the most recent five categorizations for the same counterparty — this is what gives Claude its memory and what lets the team override past decisions cleanly.
n8n HTTP Request to Claude
Vendor memory (the cheap-but-critical bit)
Repeat vendors don’t need full Sonnet calls. A small Postgres lookup + Haiku verification handles ~85% of monthly volume at a tenth of the cost.
Reconciliation Engine
Reconciliation is mechanical: bank balance from Plaid must equal the GL cash account balance per QBO/Xero, less in-flight items (uncleared checks, deposits in transit). The pipeline computes both sides, surfaces every break with its likely cause, and only escalates the breaks that don’t auto-resolve. Most months, the human only sees breaks worth seeing.
Three-way recon contract
- Bank-side: Plaid balance at month-end close cutoff (T+1, 4am UTC).
- Ledger-side: QBO/Xero cash account balance as of month-end, with all approved transactions posted.
- Subledger-side: uncleared checks + deposits in transit + pending wires from the n8n staging table.
If bank = ledger + subledger, post the close-ready flag for that account and move on. Otherwise, drop into break analysis.
Auto-resolved break patterns
| Pattern | Auto-resolve | Action |
|---|---|---|
| Timing — bank cleared, ledger pending | Yes | Add to deposits-in-transit, recon to subledger. |
| FX revaluation gap (multi-currency) | Yes | Compute FX adj at month-end rate, draft JE. |
| Bank fee not in ledger | Yes | Auto-categorize via vendor memory, post. |
| Duplicate deposit | No | Flag, escalate to controller, do not post. |
| Unknown gap > $500 | No | Escalate, attach 3-day surrounding context. |
Break SQL
Anomaly Detection
Anomaly detection runs after categorization but before close. Three layers: a deterministic statistical layer (cheap, catches most things), a duplicate-payment hash check, and a Claude pass over the suspect set with full vendor and seasonality context. The goal is not “find every weird transaction” — it’s “produce a small, ranked queue the controller can clear in 30 minutes.”
Statistical layer
- Vendor amount z-score: any transaction more than 3 standard deviations from the trailing 12-month median for that vendor.
- New vendor > threshold: first-time counterparty with amount above $5,000.
- GL spike: account balance up >30% MoM with no expected driver flagged.
- Round-number cluster: 3+ identical round-amount payments same week to same vendor (a classic kiting signal).
- Period cutoff drift: service-period dates straddle the month boundary without an accrual.
Duplicate payment hash
Claude triage of the suspect set
The statistical layer typically produces 80–150 candidates per close. Claude reads each one with full vendor context (last 12 months, average cadence, prior anomaly outcomes) and ranks them by audit risk. The top 20 land in the controller’s queue with a one-paragraph summary of what’s unusual. The rest get a “low-risk, monitoring only” tag and roll forward.
Accruals & Journal Entry Drafting
Recurring accruals are the lowest-judgment, highest-volume part of close — exactly where Claude earns its monthly cost. The pipeline reads the accrual policy, the prior-month JE register, and the current month’s posted activity, then drafts every JE the controller would have drafted by hand. The controller still has to approve each one; nothing posts to the GL automatically.
JEs the pipeline drafts
- Prepaid amortization: annual SaaS contracts, insurance, audit retainer.
- Accrued expenses: services received but not yet invoiced (legal, contractors, AWS partial-month).
- Deferred revenue release: recognize revenue per ASC 606 schedule, by contract.
- Depreciation: straight-line on the fixed-asset register.
- FX revaluation: month-end translation for foreign-currency cash and AR/AP.
- Bonus accrual: based on quarterly attainment vs target — controller signs off on the rate.
JE draft payload (QuickBooks)
Close-Package PDF Generation
The close package is what the controller signs, the audit committee reads, and the SOC 2 auditor inspects 18 months later. Generating it from a deterministic template (instead of a half-formatted Google Doc reassembled each month) means the format is consistent, the workpapers are linked, and the binder hashes verifiably match the GL state at signing time.
Binder structure
- Cover & sign-off — period, entity, preparer, reviewer, controller, hash of the GL snapshot.
- Financial statements — P&L, BS, cash flow, with prior-period and budget comparison.
- Reconciliations — every cash, AR, AP, and payroll account, three-way recon attached.
- Journal entry register — every JE this period with workpaper link.
- Anomaly resolutions — what was flagged, who approved, what the resolution was.
- Variance commentary — Claude-drafted MoM and YoY commentary, controller-edited.
- Audit log — every API call, model version, prompt hash, and human action timestamp.
Variance commentary prompt
PDF render + immutable archive
The binder is rendered with a headless Chromium n8n node from a versioned HTML template. The output PDF is hashed (SHA-256), uploaded to S3 with object lock enabled, and the hash is written to the audit table. Re-generating the binder for the same period produces a different file (different timestamps) but the underlying GL snapshot hash stays identical — that’s the integrity check the auditor cares about.
Distribution & Approval Workflow
Once the binder is generated, distribution is mechanical and time-bound. The controller gets a Slack DM with the binder link and the exception queue. The CFO gets an email summary plus the PDF. The audit committee gets a read-only S3 share with versioned access. Every step writes to the audit log with a timestamp.
Approval state machine
| State | Owner | SLA | Next state |
|---|---|---|---|
| draft | Pipeline | T+0 day | review_pending |
| review_pending | Senior accountant | T+1 day | controller_pending or back to draft |
| controller_pending | Controller | T+2 day | cfo_pending or back to review |
| cfo_pending | CFO | T+2 day | signed |
| signed | — | — | archived (immutable) |
A signed binder is hashed once more, archived to S3 with object lock, and the JEs that were in draft_pending_approval are batched into a single posting transaction to QBO/Xero. The pattern keeps the GL clean — nothing posts before sign-off, nothing posts after sign-off without a documented amendment. The same handoff pattern shows up in our work for consulting industry automations where partners need irrevocable sign-off on client deliverables.
Common Failures & Fixes
Three failure modes show up in nearly every accounting deployment. Plan for them on day one — they are cheap to design around and expensive to retrofit.
Failure 1: Over-confident categorization on edge vendors
Symptom: A new SaaS vendor whose name resembles an existing one (e.g. “Notion” vs “Notion AI”) gets auto-categorized at 0.93 confidence and posted under the wrong department.
Fix: Cap auto-post confidence at 0.95 and require two prior agreeing decisions for the exact normalized vendor string before any auto-post. New vendors always need human review on first appearance, regardless of how confident the model sounds.
Failure 2: Plaid feed reconnect erases prior cursor
Symptom: An entity re-authenticates Plaid (rotating MFA), the cursor resets, and the next sync re-ingests three months of transactions as new — Claude re-categorizes everything and the audit trail looks like the team posted the period twice.
Fix: Always dedupe in the staging table on source_hash first. Skip Claude entirely for any transaction whose source_hash already has an approved categorization decision in the last 18 months — short-circuit to the prior decision and log the fact.
Failure 3: JE draft posts before approval (dev-mode oops)
Symptom: A workflow change is deployed without the right environment flag and Claude-drafted JEs post directly to the live QBO instead of staying in draft_pending_approval.
Fix: The QBO/Xero credential used by the pipeline must be a service account whose role explicitly forbids posting JEs without the approved_by field set. Configure permissions at the integration layer, not just in workflow code — code can ship broken; permissions can’t.
Compliance: SOC 2, Audit Trail & Segregation of Duties
An accounting pipeline that writes to the GL or even drafts JEs is in scope for SOC 2 Type 2 from day one if you’re a SaaS vendor, and for the financial statement audit if you’re a portfolio company over the materiality threshold. Treat compliance as a design constraint, not a checklist at the end.
What Claude sees (and doesn’t)
- Sees: transaction descriptions, amounts, vendor names, GL account list, class list, vendor history (last 5 decisions), capitalization policy, ASC 606 schedules.
- Doesn’t see: bank account numbers, payment card data, employee SSNs, customer PII beyond company name, raw bank login credentials, file attachments outside whitelisted PDF/CSV types.
SOC 2 Type 2 controls this satisfies
- CC7.2 / CC8.1 audit trail: every categorization, JE draft, anomaly resolution, and approval recorded with reviewer, timestamp, model version, and prompt hash.
- CC6.1 access controls: service-account-only writes to QBO/Xero, role-based n8n credentials, no shared API keys per human, vault-backed secrets.
- CC8.1 change management: n8n workflows live in git, CI deploys with approval, no point-and-click prod edits, prompt versions tagged.
- A1.2 / PI1.4 data integrity: close-binder hash chain, S3 object lock, partition retention 7 years, immutable workpapers.
Segregation of duties
The pipeline never closes the loop on its own work. The same identity that drafted a JE cannot approve it; the same identity that approved a JE cannot sign the binder. Senior accountant approves categorizations and JE drafts; controller approves anomaly resolutions and the binder; CFO signs. Three identities, three actions — encoded as a hard constraint in the approval state machine, not as a policy you remember to follow.
Measured Results — 6 Closes In
Numbers from a real implementation at a 200-person SaaS finance team (3 entities, 2 currencies, ~4,200 transactions/month) after six full close cycles on the new pipeline. No change in chart of accounts or close calendar — the lift comes entirely from automation depth and exception-based review.
The headline metric inside the controller’s office is the auto-acceptance rate on categorizations: 93% of high-confidence rows posted without edit, with a measured error rate below 0.4% on a sampled audit. That’s the number that lets finance leadership trust the pipeline enough to actually change behavior — and it’s the number the SOC 2 auditor asked for first.
Implementation Timeline & Cost
- n8n self-host + queue mode + git/CI: 8–12 hrs
- Plaid + QBO/Xero ingest + dedupe: 12–16 hrs
- COA + vendor master sync + memory table: 6–10 hrs
- Claude categorization prompt + backtest 6 mo of GL: 16–24 hrs
- Three-way recon + break analysis: 10–14 hrs
- Anomaly statistical layer + Claude triage: 10–14 hrs
- JE drafting + workpaper PDFs: 8–12 hrs
- Close-binder template + S3 object lock: 6–10 hrs
- Approval state machine + Slack/email: 6–10 hrs
- SOC 2 evidence wiring + auditor walkthrough: 4–8 hrs
- Week 1: Map COA + capitalization policy + 6-month GL backtest
- Week 2: Wire Plaid/QBO/Xero + categorization prompt
- Week 3: Recon engine + anomaly detection + JE drafting
- Week 4: Close-binder template + approval state machine
- Week 5: Soft close on parallel period + tuning + auditor walkthrough
- Includes: prompt tuning, SOC 2 evidence pack, monthly precision report
FAQ
gl_account against the live COA before any write — if it doesn’t match exactly, the row is rerouted to the human queue regardless of confidence. Combined, we’ve seen zero hallucinated accounts post in the trailing six closes.Want this built for your monthly close?
SEOKRU deploys this exact system in 5 weeks. We backtest categorization against your last 6 months of GL, wire Plaid/QBO/Xero, build the recon engine, train your senior accountants and controller on the new flow, and deliver a SOC 2 evidence pack ready for your auditor. You keep ownership of every component — workflows, prompts, Postgres, the lot.
Talk to an accounting automation engineer