Skip to main content

BatchData Property Search Request Body Reference

Authoritative quick reference for building POST /property/search request bodies — building filter field names, property type enumerations, quicklists, and time-window examples. Read this before generating a request body.

Written by Charles Parra

This is the authoritative quick reference for building a POST /property/search request body. Validate every field name and every enum value against the tables below before sending a request.


Building filters — exact field names

The searchCriteria.building object accepts these fields and only these fields. Use the names below verbatim.

Field

Type

Use for prompts mentioning...

bedroomCount

integer range

"bedrooms", "beds", "BR"

bathroomCount

integer range

"bathrooms", "baths", "BA"

calculatedBathroomCount

integer range

calculated bathroom count

livingAreaSquareFeet

integer range

"square feet", "sqft", "sf", "size", "living area"

totalBuildingAreaSquareFeet

integer range

"total area", "gross area" (only when explicitly asked)

yearBuilt

integer range

"year built", "built in", "built between"

storyCount

integer range

"stories", "floors"

roomCount

integer range

"rooms"

unitCount

integer range

"units"

residentialUnitCount

integer range

"residential units"

garageParkingSpaceCount

integer range

"garage spaces", "parking spaces"

For "square feet" / "sqft" / "sf" / "size" prompts, use livingAreaSquareFeet (heated/cooled space). Use totalBuildingAreaSquareFeet only if the prompt explicitly asks for total building area including non-living space (garage, porch, basement).

Range values use { "min": <number>, "max": <number> }; either bound may be omitted.

{
"building": {
"bedroomCount": { "min": 4 },
"livingAreaSquareFeet": { "min": 1800 },
"yearBuilt": { "min": 1950, "max": 1959 }
}
}


Property type filters — exact enum values

general.propertyTypeCategory and general.propertyTypeDetail are enumerated string filters with a closed value list. Use inList (multiple values) or equals (single value); the values below are the complete list, so partial matching is never needed.

propertyTypeCategory values

Residential, Commercial, Industrial, Agricultural.

Residential propertyTypeDetail values — copy these verbatim

Single Family
Single Family Residential (Assumed)
Multi-Family
Multi-Family Dwelling
Residential Income (Multi-Family)
Duplex
Triplex
Quadruplex
Apartments
Apartment House (5+ Units)
Apartment House (100+ Units)
Highrise Apartment
Garden Apartment, Court Apartment (5+ Units)
Cooperative Building
Cooperative Unit
Condominium Unit
Condominium Building
Residential Condominium Development
Townhouse
Mobile Home
Vacant Land

The value Garden Apartment, Court Apartment (5+ Units) is a single enum value that contains a comma — keep it as one string.

Concept → exact propertyTypeDetail.inList expansion

When a search describes a concept rather than a specific enum value, include the full inList of every value below. Always include every value in the expansion; never collapse to a single representative value.

"single family" / "SFR" / "single-family home" / "house" / "home" (when used as a property type):

"propertyTypeDetail": {
"inList": ["Single Family", "Single Family Residential (Assumed)"]
}

"multi-family" / "multifamily" / "multi family":

"propertyTypeDetail": {
"inList": [
"Multi-Family",
"Multi-Family Dwelling",
"Residential Income (Multi-Family)",
"Duplex",
"Triplex",
"Quadruplex",
"Apartments",
"Apartment House (5+ Units)",
"Apartment House (100+ Units)",
"Highrise Apartment",
"Garden Apartment, Court Apartment (5+ Units)",
"Cooperative Building",
"Cooperative Unit"
]
}

"condo" / "condominium" / "condos":

"propertyTypeDetail": {
"inList": [
"Condominium Unit",
"Condominium Building",
"Residential Condominium Development"
]
}

"townhouse" / "townhome":

"propertyTypeDetail": { "equals": "Townhouse" }

"mobile home" / "manufactured home":

"propertyTypeDetail": { "equals": "Mobile Home" }

"vacant land" / "land":

"propertyTypeDetail": { "equals": "Vacant Land" }

When the prompt does not name a property type, omit general.propertyTypeCategory and general.propertyTypeDetail entirely. Do not add filters the user did not request.

Unit-count prompts use building.unitCount, not propertyTypeDetail

When the user specifies a number of units ("2+ unit residential", "3-unit", "4 or more units", "buildings with at least 5 units"), encode the count as a numeric range on building.unitCount (or building.residentialUnitCount if the prompt is residential-specific). propertyTypeDetail is an exact-match enum of named property types — it does not accept count-style values, and a unit-count expression belongs in the building filters, not the property-type filter.

{
"building": {
"unitCount": { "min": 2 }
}
}

If the user mentions both a unit count and a property-type concept ("2+ unit residential properties"), pair the building.unitCount filter with the multi-family propertyTypeDetail expansion above.


Quicklists — valid named filters

Use quickLists (AND semantics) or orQuickLists (OR semantics). Prefix with not- to negate (e.g. not-owner-occupied).

Quicklist

Meaning

owner-occupied

Owner resides at property

absentee-owner

Owner does not reside at property (umbrella — covers in-state and out-of-state)

in-state-absentee-owner

Absentee owner with mailing address in same state

out-of-state-absentee-owner

Absentee owner with mailing address in different state

out-of-state-owner

Owner resides out of state

same-property-and-mailing-address

Property and mailing address match

corporate-owned

Owned by corporate entity

trust-owned

Owned by a trust

inherited

Property was inherited

senior-owner

Owner is 65+ or has senior exemption

cash-buyer

Last purchase was all cash

fix-and-flip

Bought and sold within 12 months

tired-landlord

SFR owned 10+ years, built 30+ years ago

free-and-clear

No mortgage on property

high-equity

Owner has >20% equity

low-equity

Owner has <20% equity

unknown-equity

Equity cannot be determined

notice-of-default

Loan default notice filed

notice-of-sale

Foreclosure sale notice filed

notice-of-lis-pendens

Pending lawsuit on property

preforeclosure

Property in pre-foreclosure

tax-default

In tax default for 3+ years

active-auction

Property has upcoming auction date

involuntary-lien

Has involuntary lien

active-listing

Property has active listing

pending-listing

Property has pending listing

expired-listing

Property listing has expired

canceled-listing

Property listing was canceled

failed-listing

Listing was canceled or expired without sale

for-sale-by-owner

FSBO listing

listed-below-market-price

Listed below estimated market value

on-market

Property is available for sale

recently-sold

Sold within last 12 months

vacant

USPS flagged as vacant

vacant-lot

Likely a vacant lot

mailing-address-vacant

Owner's mailing address is vacant

has-hoa

Part of HOA

has-hoa-fees

Has HOA fees

Use the umbrella absentee-owner when the user says "absentee" without specifying in-state vs out-of-state. The in-state and out-of-state variants are subsets — picking only one of them silently drops the other half.

Required quicklists for canonical phrasings

When a search uses one of the phrasings below, always include the corresponding quicklist. These mappings are mandatory: omitting the quicklist drops the intent of the search.

User phrasing

Required quicklist

"owner-occupied" / "owner occupied" / "occupied by owner" / "owner-occupant" / "owner is the resident"

owner-occupied

"absentee" / "absentee owner" / "owner does not live there"

absentee-owner (umbrella)

"vacant" / "unoccupied property" / "USPS-vacant"

vacant

"high equity" / "lots of equity" / ">20% equity" / "equity-rich"

high-equity

"low equity" / "<20% equity" / "underwater" / "thin equity"

low-equity

"free and clear" / "no mortgage" / "paid off" / "mortgage-free"

free-and-clear

"cash buyer" / "purchased with cash"

cash-buyer

"corporate-owned" / "LLC-owned" / "owned by a company"

corporate-owned

"trust-owned" / "owned by a trust"

trust-owned

"inherited" / "passed down" / "estate property"

inherited

"preforeclosure" / "pre-foreclosure"

preforeclosure

"tax default" / "tax-delinquent for 3+ years"

tax-default

"fix and flip" / "flipped within 12 months"

fix-and-flip

"tired landlord"

tired-landlord

"FSBO" / "for sale by owner"

for-sale-by-owner

"listed below market" / "below market price"

listed-below-market-price

"senior owner" / "owner is 65+"

senior-owner

"has HOA" / "HOA property"

has-hoa

"involuntary lien" / "has a lien"

involuntary-lien

"mailing address equals property address" / "mail goes to the property"

same-property-and-mailing-address

"mailing address is different from property" / "mail goes elsewhere" / "off-site mailing"

not-same-property-and-mailing-address

For "mailing address is different from the property", use the not- prefix on the existing quicklist (not-same-property-and-mailing-address). There is no different-property-and-mailing-address quicklist, and no mailingAddressHash workaround is needed.

These are independent of any other filters in the prompt. For example, "owner-occupied homes in Austin with high equity" requires both owner-occupied and high-equity in quickLists. Do not drop a required quicklist because another filter (property type, location, range filter) is also present.

Quicklists that should not be stacked

Quicklists combine with AND. Pick one quicklist per group below: a contradictory pair (such as owner-occupied with absentee-owner) matches zero records, and a subset pair (such as absentee-owner with out-of-state-absentee-owner) simply narrows to the subset, so name the single most specific list instead.

  • Owner occupancy: pick exactly one of owner-occupied / absentee-owner / in-state-absentee-owner / out-of-state-absentee-owner / out-of-state-owner.

  • Equity: pick exactly one of high-equity / low-equity / unknown-equity. free-and-clear (no mortgage) is compatible with high-equity and adding both just narrows to free-and-clear, so use free-and-clear alone when the customer means no mortgage.

  • Listing state: pick exactly one of active-listing / pending-listing / expired-listing / canceled-listing / failed-listing.

  • Market state: pick exactly one of on-market / recently-sold.

If the user's prompt itself contradicts (e.g. "owner-occupied absentee owner"), pick the more specific filter; do not emit both.


Owner tenure and equity — numeric range filters (not quicklists)

Some concepts have no quicklist and must be expressed as numeric range filters:

Prompt phrasing

Field

Filter

"owned for N+ years" / "lived there N+ years" / "long-term owner"

owner.lengthOfResidenceYears

{ "min": N }

"owned for less than N years" / "recent owner"

owner.lengthOfResidenceYears

{ "max": N }

tenure expressed in months ("owned 18+ months")

owner.lengthOfResidenceMonths

{ "min": N }

"negative equity" / "underwater" / "owes more than it's worth" / "upside-down mortgage"

valuation.equityPercent

{ "max": -1 } (range keys are min/max only; an unrecognized key like lt is silently ignored and returns the full unfiltered set)

There is no negative-equity quicklist; do not invent one. low-equity means under 20% equity, which is a different (and less extreme) concept than negative equity, so do not substitute it for "underwater". Use the valuation.equityPercent numeric filter.


Time-window prompts — pair the quicklist with a date range

When a prompt mentions a time window for a foreclosure, listing, or sale event ("notice of default in last 90 days", "auction in March", "sold this year", "listed Jan 1 to Jan 31"), the quicklist alone is not enough. You must:

  1. Resolve the window to absolute minDate / maxDate values from today's date in YYYY-MM-DD format.

  2. Include the corresponding quicklist.

  3. Include the matching DateRange filter on the correct field.

Phrasing

Quicklist

DateRange field

"notice of default" + window

notice-of-default

foreclosure.recordingDate

"notice of sale" + window

notice-of-sale

foreclosure.recordingDate

"lis pendens" + window

notice-of-lis-pendens

foreclosure.recordingDate

"auction" + window

active-auction

foreclosure.auctionDate

"sold" / "recently sold" + window

recently-sold

sale.lastSaleDate

"active listing" / "on market" + window

active-listing or on-market

listing.listingDate

"sold on MLS" / "MLS sold" + window

recently-sold

listing.soldDate

"failed listing" / "canceled listing" / "expired listing" + window

failed-listing (or the more specific canceled-listing / expired-listing)

listing.failedListingDate

"pending listing" + window

pending-listing

listing.listingDate

Example: notice of default in last 90 days (assuming today is 2026-04-22)

{
"searchCriteria": {
"query": "Miami, FL",
"quickLists": ["owner-occupied", "notice-of-default"],
"building": {
"livingAreaSquareFeet": { "min": 1800 }
},
"foreclosure": {
"recordingDate": {
"minDate": "2026-01-22",
"maxDate": "2026-04-22"
}
}
}
}

Compute minDate / maxDate from the actual current date when generating a body — never use placeholder or training-cutoff dates.


Intel filters — BatchRank sale propensity (searchCriteria.intel)

BatchRank sale-propensity filtering lives in the searchCriteria.intel group. There is no flat, top-level propensity field and no min_sale_propensity / max_sale_propensity parameter — those names do not exist in the API.

Prompt phrasing

Field

Filter

"BatchRank score between X and Y" / "sale propensity X to Y"

intel.salePropensity

{ "min": X, "max": Y }

"high propensity to sell" / "most likely to sell" / "highest BatchRank"

intel.salePropensity

a high floor such as { "min": 80 } (illustrative, not a documented bucket boundary; see the sorting note below)

Key facts:

  • salePropensity is a 0 to 100 percentile rank, not a probability. A score of 82 ranks higher than 82% of all scored properties. Bounds are inclusive via min / max.

  • To get the score back in the response you must request the batchrank dataset under options.datasets. datasets belongs under options, never at the request root — a root-level datasets key is silently ignored.

  • Sorting by salePropensity is NOT supported. The sort field is a closed enum and does not include it, so "sort": { "field": "intel.salePropensity" } is invalid. Express "highest propensity" as a high min bound instead.

  • There is no high-sale-propensity quicklist. Do not invent one; use the numeric range.

  • intel.salePropensityCategory (High / Medium / Low) and intel.salePropensityStatus are response fields from the batchrank dataset, not search filters.

Example: Phoenix properties with a BatchRank score of 70-95

{
"searchCriteria": {
"query": "Phoenix, AZ",
"intel": {
"salePropensity": { "min": 70, "max": 95 }
}
},
"options": {
"skip": 0,
"take": 100,
"datasets": ["core", "batchrank"]
}
}


Worked examples

Multi-family in Boston, low equity, 4+ bedrooms, built in 1950s

{
"searchCriteria": {
"query": "Boston, MA",
"quickLists": ["low-equity"],
"general": {
"propertyTypeCategory": { "equals": "Residential" },
"propertyTypeDetail": {
"inList": [
"Multi-Family",
"Multi-Family Dwelling",
"Residential Income (Multi-Family)",
"Duplex",
"Triplex",
"Quadruplex",
"Apartments",
"Apartment House (5+ Units)",
"Apartment House (100+ Units)",
"Highrise Apartment",
"Garden Apartment, Court Apartment (5+ Units)",
"Cooperative Building",
"Cooperative Unit"
]
}
},
"building": {
"bedroomCount": { "min": 4 },
"yearBuilt": { "min": 1950, "max": 1959 }
},
"valuation": {
"estimatedValue": { "min": 50000, "max": 2000000 }
}
}
}

Condos in Nashville, free and clear, 3+ bedrooms, built 1980-2000

{
"searchCriteria": {
"query": "Nashville, TN",
"quickLists": ["free-and-clear"],
"general": {
"propertyTypeCategory": { "equals": "Residential" },
"propertyTypeDetail": {
"inList": [
"Condominium Unit",
"Condominium Building",
"Residential Condominium Development"
]
}
},
"building": {
"bedroomCount": { "min": 3 },
"yearBuilt": { "min": 1980, "max": 2000 }
},
"valuation": {
"estimatedValue": { "min": 50000, "max": 2000000 }
}
}
}

Notice of sale in Atlanta, valued $150K-$400K, 1500+ sqft

{
"searchCriteria": {
"query": "Atlanta, GA",
"quickLists": ["notice-of-sale"],
"valuation": {
"estimatedValue": { "min": 150000, "max": 400000 }
},
"building": {
"livingAreaSquareFeet": { "min": 1500 }
}
}
}

When the prompt does not name a property type, do not add general.propertyTypeCategory or general.propertyTypeDetail — leave them out, as in this example.


Request Options (pagination & sessions)

These optional fields live under options on a Property Search request.

Default paging (small result sets):

  • skip (integer, default 0) — number of records to skip.

  • take (integer, default 25, sync max 100 / async max 1000) — number of records to return on this page. Passing take: 0 returns aggregate data only (counts, summaries) and is billed for one property record at the request's resolved dataset rate (the basic property dataset rate if no dataset resolves). take values greater than 0 are billed only for the records actually returned, with no minimum charge; a request that returns no matching properties is not charged.

Exceeding the cap returns a 400 whose message states the limit explicitly, e.g. "The options.take must not be greater than 100." on sync /property/search and "The options.take must not be greater than 1000." on /property/search/async. If a caller reports a different limit than the one above, follow the number in the API's own error message rather than restating a fixed value.

Retrieving large volumes (tens of thousands of records). Do not deep-page with bare skip/take — skip-based deep paging is unstable as the index shifts underneath you, so rows can be duplicated or missed between pages as results move across page boundaries. In descending order of preference:

  1. Cursor pagination — options.useCursorPagination: true, then round-trip nextPageCursor as options.pageCursor. Stable across data changes; see below.

  2. A search session — for incremental delivery across days or weeks without paying for the same property twice; see below.

  3. The async endpoint — POST /property/search/async accepts take up to 1000 and delivers to options.webhookUrl; combine it with useCursorPagination for stable pages. These options are not mutually exclusive.

Arithmetic for 50,000 records: ~500 requests against sync at take: 100 (cursor pagination makes the same number of requests, but pages stably), or ~50 against async at take: 1000. Request count is rarely the binding constraint — billing is per record returned, not per request, and the rate limit is 3,000 requests per minute per account — so prefer cursor pagination for stability rather than to save requests. The MCP tools' 10-results-per-page behaviour is a tool-layer limit and must never be quoted as an API limit or used to compute request counts for someone building their own integration.

Cursor pagination (stable paging through large result sets; supported on both sync /property/search and async /property/search/async — on async, the webhook payload carries results.nextPageCursor in the same shape):

  • useCursorPagination (boolean, default false) — when true, the response includes nextPageCursor (and previousPageCursor on subsequent pages). Cannot be combined with sort.sortOrder: "random". Required when searchSession is set.

  • pageCursor (string, opaque, optional) — pass the value of nextPageCursor (or previousPageCursor) from the previous response verbatim to retrieve the next (or previous) page. Treat as a black box: do not parse, modify, or generate. Cursors are bound to the original searchCriteria; reusing one against different criteria returns 400. Mutually exclusive with searchSession (the session owns the cursor).

Search session (named, persistent delivery context across requests, sync /property/search only):

  • searchSession.id (required string, regex ^[a-zA-Z0-9_-]{1,128}$, max length 128) — customer-chosen session id, scoped to your account. Two accounts may use the same id without interference.

  • searchSession.idempotencyKey (optional string, same regex) — when supplied, an identical retry carrying the same key against a session that has already advanced returns 409 without re-advancing the session. Use for queue workers, webhook retries, CI jobs.

Constraints (verbatim 400 error strings):

  • "Invalid request. searchSession requires useCursorPagination to be true."

  • "Invalid request. searchSession cannot be combined with pageCursor."

  • "Invalid request. skip and cursor cannot be used together."

  • "Invalid request. searchSession is not supported on async endpoints."

Token ability required for sessions: property-search-sessions (also gates GET /api/v2/property/search-sessions and DELETE /api/v2/property/search-sessions/{id}). 100 sessions max per account.

Response fields added on Property Search:

  • nextPageCursor / previousPageCursor — present when useCursorPagination: true and no session is set.

  • searchSessionMeta — present when options.searchSession was set. Contains isNewSession (boolean) and totalDelivered (integer). When this object is present, nextPageCursor/previousPageCursor are deliberately suppressed.

Example — session-backed paging:

{
"searchCriteria": { "query": "Phoenix, AZ" },
"options": {
"take": 100,
"useCursorPagination": true,
"searchSession": {
"id": "monthly-leads-az-85020"
}
}
}

Wildcard-restricted fields — contains/startsWith/endsWith return HTTP 400

contains, startsWith, and endsWith return an HTTP 400 error naming the field and operator on the high and medium cardinality text fields listed below. On these fields use equals, inList, notInList, or matches instead.

  • owner: firstName, lastName, middleName, fullName, mailingStreet, mailingCity, mailingAddressHash

  • previousOwner: fullName

  • address: street, streetNoUnit, formattedStreet, city, locality, county, cbsaTitle, csaTitle

  • ids: apn, taxId, addressHash, mailingAddressHash, propertyId

  • lot: zoningCode

  • demographics: demographics

  • permit: allTags

  • legal: subdivisionName

  • sale: lastSaleTransactionTypeCode, priorSaleTransactionTypeCode (low-cardinality code fields that are restricted as well)

owner.firstName and owner.lastName additionally accept containsWords (see Owner-name search below). The wildcard operators remain available on the low-cardinality enumerated fields, for example address.state, address.zip, property type, and most other status and type enums. Note the restriction applies to the text title fields (address.cbsaTitle, address.csaTitle), not to their numeric code counterparts.

matches is a complete-value operator like equals, not a partial-match substitute. matches appears in the replacement list above because it is still accepted on every field in it. It will not match a fragment of a stored value, and matches with more than one value behaves differently from field to field and returns zero on several of them, so use inList to match any of several values.

Never offer matches as a partial-name or keyword workaround, on any string field. It requires the complete stored value, so a fragment returns zero results with an HTTP 200, and nothing in the response signals the query was wrong. When only part of a value is known, route to equals or inList with complete values, or to containsWords on owner.firstName and owner.lastName, which is the one tokenized owner-name operator.

Supply exactly one operator per field. If a field carries more than one operator, the API applies one and silently discards the rest, with HTTP 200 and no error or warning in the response. Of the eight text operators matches ranks last, so on a field that accepts matches, a matches clause paired with any other operator is the one that gets dropped. The loan-type fields do not accept matches at all, so supplying it there makes the request fail instead; these are the openLien loan-type fields (allLoanTypes, juniorLoanTypes, and firstLoanType through fourthLoanType). The silent discard applies when the field accepts every supplied operator: if any supplied operator is not accepted on the field, the request fails instead, so a wildcard paired with equals on a restricted field still returns its HTTP 400. Two different operators on the same field cannot be combined in one request. To match any of several values, use inList.

Using legal.subdivisionName in practice

Filter Property Search to a known subdivision:

{
"searchCriteria": {
"legal": { "subdivisionName": { "equals": "Briarwood Estates" } }
}
}

Use inList to span a set of subdivisions, or notInList to exclude them.

Comparables in the subject's subdivision — use options.useSubdivision: true:

{
"searchCriteria": {
"compAddress": { "street": "...", "city": "...", "state": "...", "zip": "..." }
},
"options": {
"useDistance": true,
"distanceMiles": 1,
"useSubdivision": true
}
}

useSubdivision: true derives the subject's subdivision from compAddress automatically — equivalent to passing the subject's legal.subdivisionName in an equals filter, but simpler. Set the explicit legal.subdivisionName clause only when comparables in a different subdivision are needed, or inList across multiple.

If the customer only has a fragment of the subdivision name, look up any property known to be in the subdivision via Property Lookup and copy the response's legal.subdivisionName verbatim into the equals or inList clause. Do not paraphrase, lowercase, or trim it.

Owner-name search: containsWords on owner.firstName / owner.lastName

To find a property by its owner's name, use containsWords on owner.firstName and/or owner.lastName. It is a tokenized, order-insensitive, case-insensitive word match and is the supported replacement for wildcard matching on owner-name fields. When you supply both owner.firstName and owner.lastName, a property matches only if both names appear on the same owner record. When both names use containsWords, satisfying one name through one owner and the other through a second owner is not a match. Supplying a single name part matches it against either owner. The same-owner rule applies when both names use containsWords or both names use equals or inList. If you use containsWords for one name and equals or inList for the other, the API checks each name separately. The two names can then match two different owners on the same property. A search that uses containsWords on either name requires a location, such as a city and state, a ZIP code, or a full address. Without a location, the request returns HTTP 400. An owner-name search that uses only equals or inList does not require a location.

For a containsWords search, set options.ownerNameAddressMatchMode to control address handling:

  • standard (default): closest matching properties at the location with owner-name matching applied. Accepts a full address or a location query (city, county, or ZIP).

  • exact: resolves the supplied structured address to the single parcel there (no widening). Requires a structured address plus an owner-name containsWords criterion, and returns meta.results.ownerNameMatch carrying matchedParcelCount (the total, and the value to use for the zero / one / more-than-one decision), ownerNameMatchCount and trustMatchCount (attributions explaining how those parcels were reached, which overlap rather than dividing the total between them), and matchSource. standard omits ownerNameMatch.

Mapping common phrasings:

Search intent

Use

"find properties owned by John Smith in Phoenix"

owner.firstName.containsWords + owner.lastName.containsWords, standard mode, with a location; both names must appear on the same owner record

"is John Smith the owner at 123 Main St?"

owner.*.containsWords + structured address, options.ownerNameAddressMatchMode: exact

"probate / estate: confirm the owner at this address"

exact mode; read meta.results.ownerNameMatch.matchedParcelCount for the zero / one / more-than-one decision

Confirm an owner at a specific address (exact mode):

{
"searchCriteria": {
"owner": {
"firstName": { "containsWords": "John" },
"lastName": { "containsWords": "Smith" }
},
"address": {
"street": { "equals": "123 Main St" },
"city": { "equals": "Phoenix" },
"state": { "equals": "AZ" },
"zip": { "equals": "85020" }
}
},
"options": { "ownerNameAddressMatchMode": "exact", "take": 1 }
}

Previous-owner search: previousOwner.fullName

searchCriteria.previousOwner.fullName matches a party against the seller of record on the property's past sales. Use it to find properties a party sold, as opposed to owner.*, which finds properties a party currently owns. The common case is a fix-and-flip investor or a company whose past sales the customer wants to study.

Operators. Supported: equals, inList, notInList, matches. Matching is case-insensitive. All four operators compare against the complete stored name, never against a fragment of it: matches is not a partial, prefix, or keyword search. Supplied with a single name it is identical to equals, and more than one value returns no results on this field, so use inList to match any of several names. containsWords is not supported on this field, so do not carry the owner-name recipe over to it. contains, startsWith, and endsWith return HTTP 400 like the other restricted string fields.

Limitation. State this in every answer that uses this filter. Matching applies to the seller of record on the two most recent sales only. It does not search a property's full ownership or transaction history, so a sale further back than that will not match. When a customer asks for everything a party has ever transacted, point them at Investor Profile rather than this filter.

Mapping common phrasings:

Search intent

Use

"what properties did ACME Home Buyers sell in Phoenix"

previousOwner.fullName.equals plus a location query

"find homes this flipper flipped"

previousOwner.fullName.equals, and state the two-most-recent-sales limitation

"properties previously sold by any of these companies"

previousOwner.fullName.inList with one entry per company

"everything this investor has ever bought and sold"

do NOT use this filter; route to Investor Profile

"properties whose past seller name starts with ACME"

not supported; startsWith returns HTTP 400. Offer equals with the complete stored name, or inList with several complete variants. Do NOT offer matches as a partial-name workaround: it also requires the complete stored name

Properties a named party sold at a location:

{
"searchCriteria": {
"query": "Phoenix, AZ",
"previousOwner": {
"fullName": { "equals": "ACME HOME BUYERS LLC" }
}
},
"options": { "take": 25 }
}

Several parties at once (inList):

{
"searchCriteria": {
"query": "Maricopa County, AZ",
"previousOwner": {
"fullName": {
"inList": ["ACME HOME BUYERS LLC", "BLUE DOOR PROPERTIES LLC"]
}
}
},
"options": { "take": 50 }
}

Related Resources

  • Text Search Grammar Best Practices: guidance on choosing the right text-search operator for each Property Search field, including the field-specific restrictions on legal.subdivisionName and previousOwner.fullName.

Did this answer your question?