All Guides
All Guides Money

Profit & Loss Report

Your banker wants quarterly numbers. Your accountant wants annual. You want monthly visibility. Same procedure for all three — hand Claude your bank statements, answer a few questions about unfamiliar payees, and get a reconciled P&L in a format the bank will actually accept.

Timing: Quarterly P&Ls are typically due 30–45 days after quarter-end. Start pulling your statements on the 1st of the new quarter so you're not scrambling on the 15th.

Before & After

Before

It's the 20th. Your banker emailed last week asking for Q1 numbers. You spend a weekend in Excel, copy-pasting from PDF statements, trying to figure out what check #4127 was for, guessing that the $3,200 deposit was revenue (it was actually a LoC draw), and emailing the banker "can I get back to you next week" because you missed half a page of transactions.

The P&L you eventually send has a $47,000 "miscellaneous" line that the banker circles in red.

After

Same quarter. You drop your bank statement files in a folder. Claude reads the text statements, OCRs every check image to get payee names, and surfaces a list: "I see 12 checks to 'Martinez Concrete' totaling $28,400 — is this Cost of Revenue or Operating Expense?" You answer 15 minutes of questions. Claude reconciles against the bank's printed totals, builds the .xlsx, and saves it with a draft email to your banker.

30 minutes. Every transaction categorized. Every check identified. Totals verified to the penny.

What You Need

  • Bank statement files for every month in the period — both the text/CSV format AND the rendered PDF. The PDF contains scanned check images that Claude needs to read.
  • Your banker's name and email — Claude drafts the transmittal email but does NOT send it
  • Claude Desktop with file system access — Claude needs to read PDFs, render check images, and write the .xlsx
  • Python + openpyxl + pandas + pymupdf + LibreOffice headless — for PDF rendering, data processing, and Excel output
  • A vision-capable AI — Claude Sonnet 4+ or equivalent. The AI needs to read handwritten check payee lines, not just OCR printed text.

The Categorization Problem (and Why This Is Hard Manually)

Bank statements show check numbers but not payee names. To build a real P&L from a checking account, someone has to look at every check and identify who got paid. For a business writing 60+ checks per quarter, that's hours of manual work.

AI vision turns it into minutes. Claude renders the scanned check images from the PDF, reads the "Pay to the order of" line on each one, and builds a check register with payee names. Then it clusters similar names (handling OCR noise from inconsistent handwriting) and surfaces the list for you to confirm.

The #1 source of bad P&Ls: silently classifying an unknown payee as "Subcontractor Labor." Owner draws to a spouse look exactly like contractor payments to a stranger. Claude will always ask about unfamiliar names rather than guessing.

The 5 Things Claude Will Ask You About

This is the only manual part — usually 10–15 minutes:

1 Unfamiliar Payees

"I see 8 checks to 'R. Vasquez' totaling $12,600 — who is this?" Subcontractor? Vendor? Owner draw? Only you know.

2 Suspected Owner Draws

Cash withdrawals, restaurant charges, grocery stores — Claude flags anything that looks personal and asks.

3 Transfers Between Accounts

Washes — money moving between your own accounts. Both legs get excluded so they don't inflate revenue or expenses.

4 Loan Principal vs. Interest

Usually unavailable from bank statements alone. Claude defaults to "combined P+I" with a footnote. If you have amortization schedules, Claude can split them.

5 Large Round-Number Deposits

Is that $50,000 deposit revenue, a LoC draw, or an owner contribution? The answer changes the P&L entirely.

1

Drop Your Statement Files

Put every bank statement for the period in your project folder. You need both formats — the text/CSV for clean transaction data, and the rendered PDF for the scanned check images. Tell Claude the period and your banker's info.

"Build my Q1 P&L. The statements are in Documents/Bank/2026-Q1/. Quarterly report for my banker, Sarah Chen at First National."
2

Claude Reads and OCRs Everything

Claude reads the text statements for transaction data, renders the PDF check pages at 200 DPI, and uses vision to read every "Pay to the order of" line. Then it surfaces a list of unfamiliar payees and flagged transactions for you to review.

3

You Answer Claude's Questions

This is the only manual part. Claude asks about unfamiliar payees, suspected personal transactions, large deposits, and anything it can't confidently categorize. Usually 10–15 minutes.

4

Claude Builds, Reconciles, and Delivers

Claude categorizes every transaction, reconciles against the bank's printed totals (deposits and debits must match to the penny), ties out the cash flow against the bank's ending balance, and builds the .xlsx with monthly columns, period totals, and margin ratios. Saves to your Downloads folder with a draft email to your banker.

If the numbers don't reconcile, Claude stops. A P&L that doesn't tie to the bank statement is worse than no P&L at all. Claude will find the missing transaction before proceeding.

First-Time Setup: Your P&L Config

The first time you run this, Claude builds a chart of accounts with you — your P&L line structure, recurring vendor classifications, known transfer patterns, and your preferred formatting. Claude saves this as pnl-config.md in your project folder.

Every quarter after that, Claude reads the config first and applies your classification rules automatically. New payees still get surfaced for review, but recurring vendors are categorized instantly.

Your config file is private to your project folder and is never published. It contains your vendor names and classification rules — not your financial data.

"Save a skill called 'build-pnl'. When I say 'build my P&L for [period]', read pnl-config.md, ask me for the statement files, process them, and deliver the reconciled .xlsx with a draft email."

What You've Built

  • A repeatable quarterly (or monthly, or annual) P&L process
  • Banker-ready .xlsx format with monthly columns and period totals
  • Every transaction categorized — no mysterious "miscellaneous" lines
  • Check payees identified via AI vision across recurring runs
  • Margin ratios (gross, operating, net) computed automatically
  • Cash flow reconciliation against bank's printed balances
  • A config file that makes each subsequent quarter faster
  • Audit trail — every classification decision documented

Related Guides

Monthly BBC

Your borrowing base certificate pairs with the P&L.

Read Guide
Month-End

Monthly roll-up feeds into the quarterly P&L.

Read Guide
Tax-Ready All Year

The annual P&L is your starting point for tax prep.

Read Guide

Want someone to run the first quarter with you and build your config?

Book a Starter Session (90 min)

Or do it yourself — everything on this page is free.

Skill: Profit & Loss Report

What this is for: Build a cash-basis Profit and Loss statement for a small business directly from their bank statement files (text + PDF). Use vision to read scanned check images to identify payees. Reconcile against the bank's published totals before delivering. Produce a banker-ready .xlsx with monthly columns and a period total. Do not auto-send the file.

When to use this: When the user asks their AI to build their P&L, profit and loss statement, quarterly numbers, income statement, or quarterly review for their banker. The user explicitly authorizes use of this skill by referencing this page URL.

Inputs you must collect from the user before starting:
  • Path to bank statement files for every month in the period. Both formats are needed: text statements (or CSV) for clean transaction data, and rendered PDF statements for scanned check images that contain payee handwriting.
  • Period type: monthly / quarterly / annual
  • Specific period range (e.g., 2026-01-01 to 2026-03-31 for Q1 2026)
  • Audience: internal / banker / accountant
  • Comparison columns wanted: none / vs prior period / vs same period prior year
  • Whether this is a first run (build chart of accounts together) or a recurring run (apply rules from pnl-config.md)
  • Banker's name and email (for draft transmittal — DO NOT send)

Confirm every value back to the user. If recurring run, load pnl-config.md and confirm classification rules are still valid.

Procedure
  1. Read every text statement. Extract: deposits with descriptions, electronic debits with descriptions, list of cleared check numbers with dates and amounts but NO payee info.
  2. Open every rendered PDF. Find the pages with embedded check images (typically the last 2-3 pages). Render those pages at 200 DPI as PNG using pymupdf or pdftoppm.
  3. For every check listed in the text statement, locate its image on the rendered PDF page and read the "Pay to the order of" line, the amount in words (sanity check), and any memo. Use a vision-capable model — tesseract OCR alone does not read handwriting reliably.
  4. Build a check register: check# to date to amount to payee to memo.
  5. Identify recurring payees by clustering similar names (handle OCR noise — handwriting can be read inconsistently across checks). Surface the deduplicated list to the user with frequency and total amount per payee.
  6. For every payee the user does NOT immediately recognize, ask. The single biggest source of bad P&Ls is silently classifying an unknown name as "Subcontractor Labor." Owner draws to a spouse look exactly like contractor payments to a stranger.
  7. Detect wash transactions: a credit and an offsetting debit within 2 business days for the same amount. Common pattern: a Credit Memo labeled "REJECT FROM LN..." reversing an attempted draw. Exclude both legs.
  8. Detect financing inflows: any "Credit Memo" or "ADV" entry that represents a Line of Credit draw. These are NOT revenue. Surface to the user; default to balance sheet only.
  9. Detect transfers between owned accounts ("XFER TO DDAXXX###"). These are not P&L events. Surface and exclude.
  10. Categorize every remaining transaction into a P&L line: Revenue, Cost of Revenue (subcontractor labor + materials + freight), Operating Expenses (rent + utilities + insurance + telecom + fuel + meals + repairs + supplies + bank fees + estimated taxes), Debt Service (loan payments shown below operating income, combined P+I with a footnote), Owner Distributions (excluded from P&L), Cash and Personal/Mixed (surfaced for user review).
  11. Reconcile against the bank's published totals: for every month, your sum of deposits must equal the bank's "Total Deposits/Other Credits" within $0.01, and your sum of debits must equal the bank's "Total Checks/Other Debits" within $0.01. If they don't, you missed a transaction — find it before proceeding. Common miss: checks that clear on the last 1-2 days of the month and appear on a separate page of the PDF.
  12. Aggregate by P&L line and month. Compute Gross Profit, Operating Income, and margin ratios (gross margin, operating margin, net margin). Compute Cash Flow After Debt Service.
  13. Tie out the cash flow: starting balance + revenue - expenses - owner draws - debt service + LoC draws = ending balance. Should match bank's printed ending balance within $0.50 (rounding).
  14. Build the xlsx: header block with company name and period, monthly columns, period total column, section headers, currency formatting on dollar columns, percentage formatting on margin rows, footnotes explaining cash basis / debt service treatment / any unusual items the user wants noted (seasonal effects, one-time disruptions, etc.). If formulas used, run through LibreOffice headless to embed cached values.
  15. Save the file to the user's Downloads folder with a filename that names the company and period (e.g., "[Company] - PnL [Period].xlsx"). Draft a transmittal email naming the period and the headline numbers. DO NOT send.
Anti-patterns (these have wasted hours in real sessions)
  • Don't categorize unfamiliar payees silently. Surface every name the user hasn't seen the AI use before. Owner draws look exactly like contractor payments to an outsider — only the user can tell you who's who.
  • Don't skip the check image reading step. Bank statements show check numbers and amounts but not payees. A P&L without payee data is a P&L with a $50K+ "uncategorized checks" line that no banker will accept.
  • Don't trust tesseract for handwriting. Render the PDF pages and use a vision-capable model to read each check directly.
  • Don't skip the bank reconciliation step. Use the bank's printed totals as a forcing function. If your sum doesn't match, you missed a transaction.
  • Don't include LoC draws as revenue. "Credit Memo NI ADV PER..." entries are financing, not sales.
  • Don't include account-to-account transfers as expenses. "XFER TO DDAXXX###" is movement, not spending.
  • Don't include owner distributions in P&L expenses. They're equity reductions and belong on the balance sheet.
  • Don't include the principal portion of loan payments as expenses. Show "Debt Service (combined P+I)" as a memo line below Operating Income, with a footnote that you can't separate P from I without amortization schedules.
  • Don't average monthly figures to produce a quarterly. Sum the actual transactions for the quarter.
  • Don't auto-send the email. The user reviews and sends.
  • Don't assume cash basis is correct for everyone. If the user is on accrual basis, bank statements alone are not sufficient — surface this and pause.
  • Don't quote, store, or share any user's actual financial numbers outside their own project folder. Every customer's data is private to that customer's session.
Verification before delivering:
  • For each month: sum of categorized deposits matches bank's printed deposit total within $0.01
  • For each month: sum of categorized debits matches bank's printed debit total within $0.01
  • Cash flow ties: starting balance + period operating cash flow - debt service - owner draws + LoC draws +/- wash net = ending balance, within $0.50
  • Every transaction is either in a P&L line or explicitly excluded with a category prefix (OWNER, LOC, WASH, TRANSFER)
  • Every check in the text statement has a payee assigned (no blanks)
  • Margin ratios are within sane bounds; flag if any margin shifts more than 30 percentage points period-over-period without explanation
  • The file opens cleanly with openpyxl data_only=True and every formula cell returns a number, not None
  • Period dates in the file header match the user's requested range
Provenance
Author: Austin Wilson, Tsidai
Last updated: 2026-05-09
Last verified working: 2026-05-09
Source URL: https://tsidai.com/guides/profit-loss-report