Model MatchHelp

Recipes

Enrich properties with owner contacts

Turn a list of property ids into owner names, phone numbers, and emails. You pay only for matches.

Enrichment skip-traces a parcel and returns the people tied to it. Send up to 50 ids in one synchronous call, or queue a bulk job for up to 50,000. A match costs 10 credits. Cache hits and no-matches are free.

The request

curl -X POST https://api.modelmatch.com/v1/properties/enrich \
  -H "x-api-key: mm_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "propertyIds": [
      "mm_48453012345670000|48453-012345670000|",
      "mm_48453098765430000|48453-098765430000|"
    ]
  }'
import { createClient } from "@model-match/api";

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

const result = await client.properties.enrichPropertiesBatch({
  body: {
    propertyIds: [
      "mm_48453012345670000|48453-012345670000|",
      "mm_48453098765430000|48453-098765430000|",
    ],
  },
});

for (const item of result.data.results) {
  if (item.status === "ok") console.log(item.data.persons);
}

With the MCP server connected, ask:

Enrich the top 10 properties from that list with owner contact details.

The assistant calls enrichProperties with the ids it already has. It will tell you the credit cost before running it.

The ids come straight from a property search. Pass "refresh": true only when you want a fresh skip-trace on a parcel you’ve already enriched; it re-charges on a match.

What comes back

{
  "results": [
    {
      "propertyId": "mm_48453012345670000|48453-012345670000|",
      "status": "ok",
      "charged": true,
      "reason": "fresh_skip_trace",
      "data": {
        "persons": [
          {
            "name": { "first": "Elena", "last": "Rivera", "full": "Elena Rivera" },
            "phoneNumbers": [
              { "number": "+15125550142", "type": "mobile", "reachable": true, "dnc": false, "score": 92 }
            ],
            "emails": [{ "email": "elena.rivera@example.com" }],
            "mailingAddress": { "street": "4312 Ridgeline Dr", "city": "Austin", "state": "TX", "zip": "78731" }
          }
        ]
      }
    },
    {
      "propertyId": "mm_48453098765430000|48453-098765430000|",
      "status": "ok",
      "charged": false,
      "reason": "member_cache_hit",
      "data": { "persons": [] }
    }
  ],
  "summary": { "requested": 2, "succeeded": 2, "failed": 0, "charged": 1 }
}
  • charged is true only when reason is fresh_skip_trace. Everything else was free.
  • dnc flags numbers on the Do Not Call registry. score is the provider’s confidence in the number.
  • A bad id never fails the batch. It comes back as status: "error" with a code.

Enrich a whole search instead

For more than 50 parcels, queue a bulk job with the same filters as your property search. It enriches every match up to limit and you poll for the file.

curl -X POST https://api.modelmatch.com/v1/properties/enrich-bulk \
  -H "x-api-key: mm_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "flatFilters": { "city": "Austin", "state": "TX", "salePropensityCategory": "High" },
    "limit": 500
  }'

The full guide covers polling, cancelling, and listing past enrichments: Property Enrichment.