Why I Built ClaimForge Instead of Buying Claim Software

Why I Built ClaimForge Instead of Buying Claim Software

By Farough Darakhshan

My main job is writing final invoices for water-damage jobs and then defending those invoices when insurance adjusters try to cut them down. Everything else I build exists to make that one job faster.

At any time there are 500 to 600 open claims. Each one moves through six stages: track it, invoice it, send it, defend it, collect on it, and, when nothing else works, hand it to counsel for collections. One person cannot do that by hand for hundreds of files. So I needed software.

ClaimForge is the software. This post explains what it does and why I wrote it to my own rules rather than adapting a general-purpose tool.

Two earlier attempts that never stuck

ClaimForge is not my first try. I built, or tried to build, several earlier invoice engines. None of them reached daily use.

ClaimForge is built around three rules. Each one is about an invoice an adjuster can check rather than pick apart.

Rule 1: prices come from the contract, not the price list

Most people assume a restoration invoice is priced straight from the Xactimate list. Mine are not. Most of the time the list price gets adjusted to match our market, and the prices we use most are written into Attachment A of our customer contract.

That Attachment A has 161 items. Each has a price, a contract price range, and a flag for whether overhead and profit applies.

So ClaimForge prices every line in a fixed order:

  1. The contract's Attachment A.
  2. My own billed market rate for that line, taken from past invoices.
  3. The Xactimate list, used only for codes, descriptions, and lines with no other price.

When I checked on 09/30/2026, 25% of my invoice lines differed from the January 2023 list, mostly because of my own rates. A tool that defaults to list price would be wrong on one line in four. Every price in ClaimForge says which of the three sources it came from.

Rule 2: line names never drift from Xactimate

The price is mine. The line name is not.

Every invoice line carries the exact Xactimate code, name, and description. I never paraphrase one, even when a shorter name would read better to a homeowner.

The reason is the defense step. When an adjuster disagrees with an invoice, they usually send back a comparative estimate as a PDF. If my line names match theirs exactly, the two documents can be lined up line by line. That match shows two things: what was cut outright and what was reduced in quantity or price.

In testing, the parser read 113 of 116 carrier comparatives into line items. Each cut or reduction then maps to a rebuttal card, a short written answer to one specific kind of reduction. There are about 78 of those cards today. The reply to the adjuster gets drafted from the cards that match.

All of that depends on the names. If one side calls a line something slightly different, the match breaks, and the comparative goes back to being read by hand.

Rule 3: what the field recorded never changes

This is the rule I care about most.

ClaimForge starts from the ScopeSheet, the approved scope record for the job. It shows that scope for review, writes a native invoice in Invoice Ninja, keeps my notes separate, and records every catalog, rate, or manual decision explicitly. It renders the PDF and builds a private review package for the file.

Inside the system, the source quantities and units from the ScopeSheet are immutable. The invoice math sits beside them, separately. So do the project manager's evidence and any change the review proposes.

That separation means a reviewer, or I, can always see three things apart: what the crew recorded, what the invoice charges, and what someone suggested changing. Nothing silently overwrites the field record. When an adjuster asks why a quantity is what it is, the answer starts from a number nobody edited.

Tests that tell the truth about what they ran

ClaimForge is PHP with the bcmath extension, Python, and Node with TypeScript. It extends Invoice Ninja, so the parts derived from Invoice Ninja keep their Elastic License 2.0 terms.

The test runner was built with one rule: never report a pass it did not earn.

One command runs every suite. It first lists which prerequisites are present. Then it prints PASS, SKIP, or FAIL for each script. A missing prerequisite, such as the bcmath extension or a private fixture, is always a SKIP with its reason printed. It is never counted as a pass and never as a failure. Continuous integration runs the same script.

That matters because the real price catalogs and customer files are private and are not in the repository. The public test fixtures are synthetic and contain no customer data. A suite that needs the private catalog says plainly that it skipped. I would rather see "SKIP: catalog absent" than a green check that tested nothing.

Where it stands

I want to be precise here, because this is a working note, not an announcement.

The source is integrated and tested. Acceptance of the installed release is still open. The repository is private, because the catalogs, rates, and job records it works from are business records.

So ClaimForge is not yet the thing I run every invoice through. It is the version built on the three rules above.

Three questions for any claim tool

Whether you build or buy, these are the questions I would ask of any invoicing tool:

  • Can it price from your contract before it ever touches a list price, and show which source each price came from?
  • Does it keep exact Xactimate line names, so an adjuster's comparative can be matched line for line?
  • Does it keep the field record separate from what the invoice charges and what a reviewer proposes?

Those three answers are why ClaimForge exists in the form it does.


Farough (Frank) Darakhshan writes the final invoices for water-damage jobs in Northern Virginia and builds the software that helps him do it. More of his systems are on the projects page.