Model MatchHelp

Recipes

Find properties likely to sell

Build a list of parcels in a market filtered by value, equity, and the sale-propensity score, ready to enrich with owner contact details.

Every parcel carries a sale propensity score from 0 to 100, the model’s read on how likely it is to sell soon. Combine it with value and equity filters to build a prospect list, then enrich the ids for owner contact details.

The request

curl -X POST https://api.modelmatch.com/v1/properties \
  -H "x-api-key: mm_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "flatFilters": {
      "city": "Austin",
      "state": "TX",
      "salePropensityCategory": "High",
      "avmValue": { "gte": 500000 },
      "ownerType": "individual"
    },
    "sort": [{ "field": "salePropensity", "order": "desc" }],
    "pagination": { "size": 25 }
  }'
import { createClient } from "@model-match/api";

const client = createClient({ apiKey: process.env.MODEL_MATCH_API_KEY });

const result = await client.properties.list({
  body: {
    flatFilters: {
      city: "Austin",
      state: "TX",
      salePropensityCategory: "High",
      avmValue: { gte: 500000 },
      ownerType: "individual",
    },
    sort: [{ field: "salePropensity", order: "desc" }],
    pagination: { size: 25 },
  },
});

const ids = result.data.data.map((p) => p.id); // feed these to enrichment

With the MCP server connected, ask:

Find homes in Austin, TX worth $500k or more that are highly likely to sell soon, owned by individuals. Show value, equity, and the current mortgage.

What comes back

{
  "data": [
    {
      "id": "mm_48453012345670000|48453-012345670000|",
      "mmPropertyId": "mm_48453012345670000",
      "address": "4312 ridgeline dr",
      "city": "austin",
      "state": "TX",
      "zip": "78731",
      "ownerName": "Rivera",
      "yearBuilt": 2018,
      "squareFeet": 3288,
      "avm": { "low": 734370, "mid": 807000, "high": 879630, "confidence": 91 },
      "equity": { "value": 458950, "pct": 0.569 },
      "salePropensity": { "score": 100, "category": "High" },
      "activeLoanCount": 1,
      "mortgageBalance": 348050,
      "loans": [
        {
          "amount": 354000,
          "loanType": "conventional",
          "transactionType": "refinance",
          "recordingDate": "2025-06-18T06:00:00.000Z",
          "lenderName": "crosscountry mortgage llc",
          "originatorNmls": "274124"
        }
      ],
      "sales": { "count": 2, "lastPrice": 799000, "lastDate": "2025-06-27T06:00:00.000Z" },
      "ownerOccupancy": "owner_occupied",
      "absenteeOwner": false
    }
  ],
  "total": 6850,
  "cursor": "WyJtbTp2MiIsMTAwLCJtbV80ODQ1MzAxMDgwMzA2MDMwMDAwIiwiMDEwODAzMDYwMzAwMDAiLG51bGxd"
}
  • avm.mid is the value estimate the avmValue filter matches. equity.pct is a fraction, so 0.569 is 57% equity.
  • loans holds the parcel’s most recent mortgages, including the loan officer and lender on each. That’s how you tie a property back to the people who financed it.
  • The id is what enrichment and bulk export take.

Make it yours

  • High equity, verified: "equityPct": { "gte": 0.5 }, "preSaleLoanCount": { "lte": 0 }. The second filter drops parcels whose zero-mortgage reading is just a not-yet-recorded sale.
  • Investor-owned: "ownerOccupancy": "not_flagged", "absenteeOwner": true, optionally "ownerType": "entity".
  • Financed by a specific loan officer: "loanOriginator": "274124" with "loanMatchMode": "most_recent".
  • Score threshold instead of category: "salePropensity": { "gte": 80 }. It’s a 0 to 100 score, so 0.8 would match almost everything.