n8n portfolio · workflow 3 of 3

AI Accounts Payable Autopilot

An accounts-payable clerk that never sleeps: it reads every emailed invoice with Claude vision, checks it against the vendor master and purchase orders, stops bank-detail fraud before money moves, gets the right approver's decision in Slack and posts the bill to QuickBooks. Built for finance teams re-keying invoices by hand.

Nodes
38 + canvas notes
Entry points
Gmail · weekday schedule · setup
AI
Claude Opus 5 via the Messages API
Integrations
Gmail · Postgres · Google Drive · QuickBooks Online · Slack
File
03-ai-accounts-payable-autopilot.json ↓

Architecture

Every attachment becomes one item with a SHA-256 fingerprint, so a re-sent invoice is skipped before any AI spend.

① Capture → understand → decideno AI spend on files already seen② Route → approve → post → paystrictest rule wins③ Morning digestemaildecisionpostyesno / timeoutdigestGMAIL · 5 MIN POLLAP inboxPDFs and photosSCHEDULEWeekdays 8 AMmorning digestSET + SWITCHConfig & routerlimits · tolerancesQuickBooks realmCODESplit attachmentsskips signature logosCRYPTOSHA-256 fingerprintidempotency keyPOSTGRES + MERGESeen before?drop repeats earlyGOOGLE DRIVEArchive originalaudit trailCLAUDE · MESSAGES APIVision extractionPDF / photo → JSON schemaCODERe-check the mathslines · totals · dates · termsPOSTGRES · PG_TRGMMatch vendor + POgoods receipts · historyCODEDecision enginefraud + 3-way matchPOSTGRESRecord invoiceunique on file hashSWITCH · 6 OUTPUTSRoute decisionsee the ladder belowPOSTGRESAuto-approveclean match or low riskSLACK · SEND AND WAITApprover decidesbuttons · 48 h timeoutSLACKAP reviewflags + document linkSLACK · @HEREFraud holdnever replies to senderGMAILDuplicate noticealready on filenot an invoice → kept in the audit table, no actionIFApproved?POSTGRES + SLACKDeclinedlogged, AP toldQUICKBOOKS APIPost billGL-coded linesPOSTGRESSchedule paymenton discount deadlineGMAIL + SLACKConfirmvendor · labelAP logQuickBooks error → Slack,invoice stays approvedPOSTGRESAP snapshotCODEFormat digestSLACKCash out · discounts · queue
Lane ① ends by recording the invoice and its decision; lane ② picks it up along the gap between the lanes. A QuickBooks failure goes to Slack and leaves the invoice approved but unposted, never silently lost.

The decision ladder

Checks run in this order and the first match wins, so a fraud signal always beats a convenient auto-approval.

yesyesnoyesnoyesnoyesnoyesnoelseINPUTSInvoice + vendor + POre-checked extractionvendor master, goods receiptsduplicate historyCHECK 1Not an invoice?quote, statement or receiptOUTCOMEIgnorekept in the audit tableCHECK 2Any critical flag?bank account differs from vendor masterblocked vendor · PO belongs to another vendorOUTCOMEFraud holdSlack @here · never reply to senderCHECK 3Invoice number already on file?same vendor, same numberOUTCOMEReject duplicatepolite reply to the vendorCHECK 4Any high or medium flag?new vendor · sender domain mismatch · AI-spotted pressureprice off the PO by more than 2% · qty above goods receivedmaths or date error · extraction confidence below 0.8OUTCOMEAP reviewflags + document in SlackCHECK 5PO found and every line matched?by SKU or fuzzy description, within toleranceOUTCOMEAuto-approveclean 3-way match → QuickBooksCHECK 6No PO, known vendor, total ≤ 2,500?at least one earlier invoice from this vendorOUTCOMEAuto-approvelow-risk spend → QuickBooksOUTCOMEApprover decidesSlack buttons · 48 h timeoutAPPROVAL MATRIXBy amount0–5k: AP manager5k–25k: finance director25k and up: CFO
The 2% price tolerance, the received-quantity rule, the 2,500 auto-approve limit and the approval bands are the workflow's real defaults, editable in the config node and the approval_matrix table.

Engineering decisions

Why it is built this way.