Geographic farming fails for a boring reason: the list is a chore. By the time an agent has pulled records, cleaned them, guessed at who has equity and found phone numbers, the month is gone. This specifies the version where drawing the shape is the whole job — and where the list arrives ranked, deduplicated and already scrubbed against the lists it is illegal to call.
The pipeline
Eight stages. One of them depends on a vendor decision.
Draw the farm
Freehand or vertex-by-vertex polygon on the map, or snap to a boundary already in the system — subdivision, block group, census tract, school attendance zone. Farms are named and saved, so the same territory can be re-run monthly and compared against last month rather than redrawn from memory.
Leaflet 1.9.4 already loaded; Map Polygon already a geography option — a draw plugin is the additionResolve the parcels inside it
Every parcel whose centroid falls in the polygon is pulled from the county appraisal district — WCAD and TCAD are already integrated as the authoritative source for Williamson and Travis, because MLS tax data lags a year. Owner name, situs address, mailing address, year built, stories, living area, assessed and market value, exemptions, and the ownership start date all come from that record.
cad_service.pyEnrich from what the platform already knows
Each parcel is joined to MLS history (last list date, last close, days on market, withdrawn or expired), to the block-group demographics, and to the current ALEX valuation — which is what turns an assessed value into an estimated equity position rather than a tax figure.
BigQuery listings 2016→present · demographics_data_service.py · ALEX 13.0Append contact data
Phone and email are not in this project today and are not derivable from county records — this step is a third-party skip-trace vendor and the one real dependency in the build. Coverage will be partial: every appended contact is stored with its source and a match confidence, and anything below threshold is surfaced as “mail only” rather than quietly guessed.
new — vendor selection is an open decisionScore and sort
The list arrives ranked, not alphabetical. Sort and filter on years owned, assessed value band, stories, living area, bed/bath, absentee owner (mailing address ≠ situs), homestead and over-65 exemptions, estimated equity, never listed, and previously expired or withdrawn — individually or stacked.
new — scoring runs server-side over the parcel tableSuppress before anything leaves
One global suppression pass runs on every export: federal and state Do Not Call, the brokerage’s own do-not-contact list, existing clients and current listings, and prior opt-outs. Suppression is global, not per-list — an owner who opted out in March cannot reappear because a new farm was drawn in June.
new — suppression table, shared with the CRMWork the list
Export to the Lofty CRM, to a mail-merge for postcards and letters, or into the existing drip machinery. Each parcel also gets a one-page owner brief — their property, their likely equity, and what has sold around them — which is the piece that makes the first call something other than a cold call.
lofty_crm_adapter.py · linkedin_drip_runner.py patternRe-run and diff
Next month the same farm is re-run and the answer is what changed: new owners, new listings, price changes, tenure crossing a threshold. That diff is the farming message; the list itself was never the point.
same pattern as the 90-Day Market Activity “changes since last night”What comes back per household
Everything above the line is already in the platform today.
| Field | Source | Status | Why it matters |
|---|---|---|---|
| Owner name | County appraisal district | have it | Public record |
| Situs and mailing address | County appraisal district | have it | Mismatch flags an absentee owner |
| Ownership start date → years owned | County appraisal district | have it | The single strongest listing predictor in the set |
| Stories, living area, year built, bed/bath | County appraisal district | have it | |
| Assessed and market value, exemptions | County appraisal district | have it | Homestead and over-65 are life-stage signals |
| MLS history — last list, last close, DOM, expired | BigQuery, 2016→present | have it | Never-listed and previously-expired are separate plays |
| Current ALEX valuation and estimated equity | ALEX 13.0 | have it | Value minus last sale and lien estimate |
| Block-group demographics | Census ACS | have it | Context, not targeting |
| Phone number | Skip-trace vendor | vendor | Partial coverage; DNC scrub mandatory |
| Email address | Skip-trace vendor | vendor | Partial coverage; CAN-SPAM opt-out required |
One list or three?
A design decision worth making once, on purpose.
Compliance
Conditions of shipping. None of these are settings.
- DNC scrub is a release condition, not a setting. No export path may produce a phone list that has not passed federal and state Do Not Call suppression, and the scrub date travels with the export.
- No autodialed calls or texts without consent. The tool produces a call list for a human to work; it does not dial, and it does not text.
- Every email carries a working opt-out, and an opt-out writes to the global suppression table immediately — not to one campaign.
- Contact data is never public. Owner PII is service-account read only, in a bucket with uniform access and no per-object public grants. This project has already had one world-readable bucket containing CRM PII; that must not repeat.
- County data is used within its terms. Appraisal district records are public for this purpose; bulk redistribution of them is a different thing and is out of scope.
- Retention has an end. A farm not worked in twelve months expires, and its appended contact data is deleted rather than kept indefinitely.
Phasing
Phase 1 is useful before any vendor is signed.
Phase 1 — the map and the parcels
Draw, save and name a farm; return every parcel inside it from the county record with the full county field set, sortable. No contact data, no vendor, no exports. Useful on its own — this is already a better farm list than most agents have.
Phase 2 — scoring and the owner brief
Equity estimate, tenure scoring, the stacked filters, and the one-page owner brief. Ends when the agent can hand-pick 40 doors out of 400 for a reason they can articulate.
Phase 3 — contact append and outbound
Vendor integration, suppression table, CRM push, mail merge, and the monthly diff. This phase does not ship until suppression does.