Which Houston Estates Actually Own a House
Reads new Harris County probate filings, finds the property the estate owns, and hands investors a contact-ready lead list.
The Problem
Harris County files dozens of new probate cases every court day. Some of those estates own a house that heirs will need to sell, but the filings are scanned PDFs, the property records live in a separate county system, and nothing links the two. Finding the good cases by hand means looking up each case, finding the PDF, reading it, pulling out the names and addresses accurately, then checking whether the deceased person owns property. The information is public, but getting it out is very slow.
What It Does
An operator picks a working date and presses a button. The app pulls that day's new Harris County probate cases and their court documents from a data feed and skips anything it has already seen. It sends the scanned PDFs to an AI model that reads them and pulls out the decedent, the executor or administrator, the heirs, and every address mentioned. It then searches Harris County appraisal records for property in the decedent's name, scores each possible match, and sorts the case into Qualified, Needs Review, or Unqualified. Ambiguous property matches wait in a review queue for a human decision instead of being guessed. Qualified leads get skip traced for phone numbers and emails, synced to Airtable, and delivered to subscribers as a spreadsheet with a summary email.
Real estate investors and wholesalers who buy inherited houses and want to reach the personal representative before the estate shows up on the lists everyone else buys.
Outcome
Between mid-May and late July 2026 it screened 1,782 Harris County probate cases and qualified 866 of them, producing 1,056 leads with the property, the responsible party, and their mailing address attached. The AI reading cost $8.58 for the whole month of June. A typical delivery is a short list; the July 16 file carried 10 leads, 6 of them with traced phones and emails.
Screenshots



How It's Built
Intake pulls the day's Harris County probate case index and document image ZIPs from an Amazon S3 feed, upserts cases, parties, and filings, and fingerprints each case (county plus case number) so re-runs never create duplicates. PDFs are downloaded to server storage under a hashed filename and reused if already present. The parse stage sends each document to OpenAI (gpt-4.1-mini, as extracted text or as the PDF itself), validates the structured result, and stores parties and address candidates with confidence scores. The full Harris County appraisal roll, about 7 million owner and account records, is imported into Postgres so the HCAD match stage can query it locally: it searches by decedent and fiduciary names, falls back to the spouse's name and to addresses lifted from the PDF, and scores every candidate parcel. The qualify stage rejects non-target case types and cases with no residential property, routes ambiguous matches to a review queue, and gives each qualified case a numeric lead score capped at 100. An enrich stage fetches HCAD detail pages for precise property class codes and assessed values. Qualified cases become leads, get skip traced through Tracerfy, and are synced to an Airtable base whose Client Delivery Feed produces the subscriber spreadsheet and summary email. A React dashboard fronts all of it: dashboard, cases, case detail, leads, review queue, and job runner with per-run counts and error tallies. The API is Express, the database is PostgreSQL with Drizzle, all TypeScript, hosted on Replit.
By the numbers
- probate cases in the database (as of 2026-07-22)
- 1,782, file dates 2026-05-12 to 2026-07-21
- qualification split
- 866 Qualified, 718 Unqualified, 198 Disqualified
- leads created
- 1,056 (869 new, 187 disqualified by an operator)
- new cases per filing day
- 24 to 59 (Airtable sample, 2026-06-11 to 2026-07-10)
- pipeline runs logged
- 487 between 2026-05-15 and 2026-07-22
- filings sent to the AI parser
- 3,582 across 60 runs, 133 failures (3.7%)
- AI parse run time
- 14 to 64 minutes for 39 to 150 filings (Airtable sample)
- county appraisal roll loaded into Postgres
- 7,023,520 records in 2 import runs
- cases run through property matching
- 1,386 across 50 runs, 0 errors
- parties extracted from scans
- 3,624 (Airtable sample)
- address candidates extracted
- 2,302 (Airtable sample)
- appraisal district property candidates scored
- 2,269 across 289 cases (Airtable sample)
- property match method
- 1,792 by owner name, 356 by spouse fallback, 121 by address from the PDF (Airtable sample)
- skip trace outcomes
- 296 complete, 33 partial, 97 no hit, 1 failed, 170 pending (Airtable sample)
- OpenAI cost, June 2026
- $8.58 for 1,784 requests and 13.77M tokens on gpt-4.1-mini
- leads in the 2026-07-16 delivery
- 10, 6 skip traced, 23 columns
- app surface
- 38 API endpoints, 7 dashboard pages, 10 Postgres tables, 9 job types
- in use since
- 2026-03 (earliest delivery email on record is 2026-03-28)
Key Decisions
A case with no residential property is unqualified even when commercial or vacant parcels match. Residential scores +40, commercial +10, vacant -10.
The wholesalers this was built for only ever wanted residential. Anything else was noise to them.
Property search falls back to the surviving spouse's name when the decedent's name finds nothing.
The county database lists owners in the order they appear on the deed. When the decedent was the second name, a search on their name alone missed the house. Searching both names gets the hit either way.
What broke & how it was fixed
Downloaded PDFs live in the server's temporary storage, and the app never deletes them. When the hosting environment cleared that storage, the parse stage hit filings whose PDF was gone. The fix was to detect a missing file during parsing, reset that filing's download fields in the database, and add a Retry Missing PDFs action to the intake step so the documents are fetched again on the next run. Parse runs on large batches still log a few failures each (133 of 3,582 filings), which is what the retry path absorbs.
Where else this applies
Any public record that arrives as a scanned PDF and only becomes valuable once it is joined to a second database fits this shape: read the scan with a model, extract the names and addresses, look them up in the authoritative record, score the match, and send only the uncertain ones to a human. Court filings, permits, liens, code enforcement, and business registrations all follow the same pattern.