SimplePractice Reports: Deep Dive into What The Reports Actually Show

simplepractice reports

SimplePractice Reports: Deep Dive into What The Reports Actually Show

SimplePractice reports look reasonably complete from inside the app right up until you actually need the data for something, an AR review, a denial pattern, a recoupment reconciliation, and then the gaps show up fast. The honest answer to “can SimplePractice do that” is almost always the same: not from inside the system. Only by getting the data out of it first.

What SimplePractice reports can’t show you at all

Denial reporting doesn’t exist in any real form. There’s no way to run a report of everything denied last month, and no way to group denials by reason, whether that’s eligibility, credentialing, or anything else. The question “how many denials did we get for this specific reason in the last six months” simply can’t be answered from inside the system, and what does appear against an individual claim isn’t a standardized denial code description. It’s plain text that can be misleading or outright wrong, which means there’s nothing meaningful to report on even if a report existed.

Transaction-level detail is missing too. Most billing systems can show, in a flat file, that a claim was paid and the money was later taken back. SimplePractice can’t distinguish billed-and-paid from not-paid from recouped in any reliable way, and recoupment letters aren’t accessible from inside the system at all. When a recoupment happens, there’s normally still an ERA, an 835 file, showing the original payment and the later offset, but without file-level access, that trail is effectively unusable. CMS requires payers to deliver exactly this kind of standardized remittance data, which makes it clear the information exists somewhere upstream. SimplePractice just doesn’t surface it.

Deleted claims compound the problem. Identifying a deleted claim is difficult at best, since only the practice owner’s own login can see the deleted-claim record, there’s no export, and each one has to be viewed individually through the interface. Federal audit control requirements under the HIPAA Security Rule call for mechanisms that record and examine system activity, and a one-at-a-time view with no export capability makes that examination step far harder than it should be for any practice trying to reconstruct what actually happened to a claim.

Reporting vs. analytics: the SimplePractice reports gap that costs real money

It’s worth separating two things the vendor language tends to blur together. Reporting spits out data. Analytics tells you what to do about it. SimplePractice is weak at the first and essentially absent on the second, and it’s the second gap that actually costs money.

The concrete version looks like this: fifty claims sitting unpaid for one payer because of a single provider’s credentialing gap don’t show up as one fixable problem. They show up as fifty separate claims, worked one at a time, forever, because there’s no way to see the pattern connecting them. The same blindness applies to eligibility and benefits issues building up across an entire patient population, invisible until patients are already carrying real balances nobody caught in time.

  • Write-offs and adjustments that shouldn’t have happened
  • Unpaid claims sitting quietly in A/R
  • Receivables that are now a year or more old
  • Denial patterns of any kind
  • Systemic issues, like one credentialing gap generating dozens of denials
  • Eligibility and benefits problems accumulating across a patient population

None of this is visible from inside the system. All of it is exactly the kind of pattern a real revenue cycle review is built to catch.

The four SimplePractice reports that actually matter for AR

Four exportable reports carry most of the usable billing data, each with real limitations.

Report What it gives you What it’s missing
Outstanding Claims Aging report of money owed by insurance, sorted by payer Summarized at the payer level only, no CPT code
Appointment Status CPT code, charge, paid, write-off, unpaid, and date of service per appointment Payer identity doesn’t clearly travel with the export
Client Invoice Aging Amounts owed out-of-pocket by clients, with aging Patient balance only, no payer or CPT detail
Unpaid Insurance Appointments Insurance balances and credits by appointment Limited payer and CPT detail in the actual export
SimplePractice Analytics Reports menu showing Income, Billing, Clients and Appointments, and Insurance report categories
The full reports menu. These four are the ones that actually carry AR data.

Appointment Status is the workhorse of the group. Toggling on “Include Insurance” adds the Charge, Paid, Write Off, Unpaid, and Details columns, and it’s the only report that reliably surfaces the CPT code per appointment alongside the date of service.

What actually survives when you export SimplePractice reports to CSV

This is the part worth testing before trusting, because the underlying research on this specific question was genuinely unresolved. The theory says a two-file join, Appointment Status plus Client Invoice Aging, should get you close to a full AR picture. A separate attempt at building that exact join for cross-practice benchmarking recorded it failing. Both findings existed side by side, which meant the honest answer required an actual export to settle it rather than a guess. Once you’ve pulled the aging report, compare it to peers with the free Mental Health AR Benchmark tool.

Required field Available? Where
CPT code Yes Appointment Status
Charge amount Yes Appointment Status
Insurance balance Yes Appointment Status, insurance toggle on
Patient balance Yes, separate report Client Invoice Aging
Date of service Yes Appointment Status
Aging bucket No, must be calculated Derived from DOS at analysis time
Payer name Not confirmed in this export See below
Raw SimplePractice Appointment Status CSV export opened in a spreadsheet showing columns for date of service, clinician, CPT, rate, units, client status and amounts, and insurance status and amounts, with no payer or insurance company name column present
A real Appointment Status export, insurance toggle on. Client and insurance amounts both come through cleanly. A payer name column does not.

That’s the actual finding. The exported file carries date of service, clinician, CPT, rate, and full client-side and insurance-side amount and status columns, but no field naming the actual payer, no Aetna, no Cigna, no Blue Cross. Insurance status and dollar amounts export cleanly. Which insurer those amounts belong to does not. That settles the open question in favor of the more limited reading: a CPT-level view joined to a payer name isn’t something this export supports on its own.

What that means practically: joining Appointment Status to Client Invoice Aging on client ID does produce a genuinely useful combined view, CPT, charge, insurance balance, patient balance, and date of service in one place, with the aging bucket calculated manually from DOS, since SimplePractice is the only system in this category that doesn’t pre-bucket aging at all. Payer-level detail has to come from the separate Outstanding Claims report instead, which does carry payer, but summarized at the payer level rather than down to the individual CPT line. Reconciling those two views into one true CPT-by-payer picture isn’t something SimplePractice supports in a single clean export. It takes real analytical work layered on top.

Matrix showing which AR fields are available in which SimplePractice report, with payer marked uncertain in CSV export and aging bucket marked as not available and requiring manual calculation
Two rows carry real risk: payer in the export, and aging buckets that don’t exist until you build them.
Diagram showing Appointment Status and Client Invoice Aging reports joined on client ID with aging bucket calculated from date of service to produce a combined AR aging view
What the join actually gets you: CPT, charge, and both balances in one view. Payer-level detail still requires a second, separate report.

How SimplePractice reports compare to the rest of the field

None of this is unique to one system. None of the five behavioral health platforms examined produce a single export containing CPT, payer, charge, insurance balance, patient balance, and aging bucket together in one file.

Comparison table of AR aging report capability across five behavioral health EHR systems: TherapyNotes rated best, Valant strong, SimplePractice moderate, TheraNest unverified, and ICANotes rated skip
SimplePractice lands in the middle of the pack, not at the bottom.

TherapyNotes and Valant both do better on this specific point. TherapyNotes’ Search Billing Transactions report puts payer, charge, paid amount, balance, and insurance status on one native page, no join required.

TherapyNotes Search Billing Transactions report showing payer, rate, patient amount, patient balance, insurance amount, insurance paid, and insurance status columns together in one native report
What SimplePractice makes you assemble by hand, TherapyNotes shows natively.

TheraNest carries pre-built aging buckets out of the box too, something SimplePractice doesn’t offer at all.

TheraNest Invoice Aging report showing pre-built past-due day buckets with CSV and PDF export options
Pre-built aging buckets, exportable directly. No manual calculation required.

ICANotes is genuinely worse than all of them, with no useful AR aging path and clearinghouse integration weak enough that billing data doesn’t reliably flow back into the system in the first place. The honest summary is that SimplePractice sits mid-pack. Nothing in this group is actually good at this. The real argument for moving billing off SimplePractice isn’t that a better behavioral health EHR exists somewhere. It’s that billing probably shouldn’t run entirely inside the clinical system at all, regardless of which one a practice uses.

Getting real AR visibility out of SimplePractice reports

What this actually requires is building the missing layer outside the system: periodic automated exports functioning as a real backup, scripted extraction for anything that won’t come out through a structured report at all, and reporting and analysis built entirely apart from the EHR itself. It’s less that SimplePractice refuses to provide this. It’s that the report simply hasn’t been built yet, and there’s no indication that’s changing soon.

Wondering what your own SimplePractice data would actually show if it were properly extracted and reconciled? Schedule a brief call and we’ll walk through what your reports are most likely hiding.