About
Programmatic access to the property database: search by address, parcel, or MLS id, fetch property details and attributes, run your saved property filters, count signal events, organize properties with tags and lists, and skip-trace owners. Shared filter-authoring operations also support CONTACT and DEAL filters. All operations go through the developer API gateway — one endpoint, called byoperationId. If you haven’t set up a key yet, start with the
Developer API Overview.
Property idsThe search operations (
findProperties, findPropertiesByParcel,
findPropertiesByMlsId) return the property id to use everywhere else —
pass it as-is to getProperty, getRelatedProperties, tag/list operations,
and skip tracing.Operations
Lookup and search (READ scope)
Address/parcel/MLS searches are paginated
findProperties, findPropertiesByParcel, and findPropertiesByMlsId return up
to 50 matches per call (a larger limit is clamped) but take an offset,
and return totalCount + hasMore — so you can page through the full result set:
send offset: 0, then offset: 50, and so on until hasMore is false. See
Result limits & truncation.Signal event counts (READ scope)
An event is a property’s signal of one type on one publication day; one
property can contribute several events. Standing conditions such as absentee
ownership are not events. This differs from
filterProperties.total, which
counts distinct matching properties. Express the area in the PROPERTY filter
DSL: use a county’s fips from searchCounties or a city’s id from
searchCities. includeIncompleteRecords widens the same completeness gate
as on filterProperties.
Saved filters (READ + WRITE scopes)
filterProperties checks the resolved criteria against your organization’s
plan, for both saved filterId and inline filterTree requests. A field the
plan excludes causes an operation error with code PLAN_ENTITLEMENT_REQUIRED;
it does not return an empty match set. Saving a filter does not preserve
access to a feature your plan no longer includes.
File a filter with
saveFilter.folderId or updateFilter.folderId; explicit
null on update removes it from its folder. Reuse a folder only when its name,
parent, and privacy match. Deal filters run over one separately supplied
pipeline; see the Deals API.
filterProperties.sort.direction is ASC or DESC. Supported fields are
spicy_lead_score, estimated_value_dollars, estimatedRent, last_property_signal_date
(or lastPropertySignalDate), closed_date (or closedDate), unit_count
(or unitCount), latestListingStatusDate (or z_latest_listing_status_date),
fsboListedDate, frboListedDate, fsboListingRemovedDate,
frboListingRemovedDate, listingRemovedDate, listingRemovedRentDate,
listingRemovedSaleDate, and auction_date (earliest upcoming auction,
properties with none last). Unknown fields are silently ignored, leaving the
default order.
includeIncompleteRecords: true includes properties normally hidden because
they lack both parcel identity and a signal. It widens results and cannot
turn off the same option already enabled in a saved filter’s queryOptions.
Use the same option when previewing and submitting a filter-based list action.
Saved-filter groups can carry negated: true to invert the whole group,
including its nested groups and conditions. It is a group-level option;
omitting it leaves the group uninverted.
Hidden and retired fields
hidden describes visibility in the app’s filter builder; it does not mean
a field is unusable. retired marks fields withdrawn from new authoring
while existing saved conditions keep working. Prefer their replacements.
listFilterFieldNames leaves retired fields out; explicitly requesting their
ids with listFilterFields still returns details for interpreting saved trees.
For contact filters, dealFilters combines stage, assignee, and close-date
criteria on the same deal. The retired dealPipelineAndStages,
dealUserIds, and dealCloseDateRange conditions can each match a different
deal when combined.Relay filter warningsA successful save or update can return
warnings. These are not errors: the
filter was persisted, but its criteria may deserve attention — for example,
selecting same-named counties from different states. Show every warning to
the user and correct the tree if it reveals an unintended selection.Cities and counties are identified by id, not by nameA
cityFilters condition takes the id from searchCities as its value
(with label set to "Name, ST", e.g. "Memphis, TN"), and a
countyFilters condition takes the 5-digit fips from searchCounties.
saveFilter and updateFilter reject a bare city or county name: 11,347
US city names occur in more than one state, and a county name compiles to a
county_fips term that would match nothing. Resolve the name to an id first.Tags and lists (READ + WRITE scopes)
Selecting properties for a list action
Both list actions requiretotalCount and accept one selection form:
- Explicit ids: send
propertyIdsand their count astotalCount. Omit filter and selection-window fields. To exclude a property, leave its id out. - Filter: send either
filterIdorfilterTree, plus eitherselectAll: trueorselectCount: N. A filter without either window, or with both, is rejected. OptionalexcludeIdsapplies only to this form. A saved filter must be visible to the key owner; an inline tree is strictly validated, so unknown field ids reject the call.
filterProperties first and pass its unsubtracted
total as totalCount. This is an execution cap: understating it stops the
job early. Exclusions are handled by the worker; do not subtract them. For
explicit ids or selectCount, the server derives the cap from the id count
or N, but totalCount remains a required, non-negative input.
selectCount takes the first N in the worker’s default traversal order; it
does not use a preview’s sort. For a sorted top-N, pass the sorted page’s
explicit ids. Keep includeIncompleteRecords consistent with the preview,
and review the match count before submitting a filter selection that could
affect thousands of properties.
Skip tracing (ADMIN scope)
Properties are global, not org-ownedUnlike deals or contacts, a property isn’t owned by any one organization — it’s
shared reference data. So property operations are not org-guarded on the
property id: any valid property id (esId) is readable, and referencing one never
returns
403 forbidden. Your scope (READ / WRITE / ADMIN) still gates
what you can do. The tags and lists you organize properties with are yours,
though — a tag or list id from another org returns 403 forbidden. Saved filters
you create are tied to your organization by the key. See
Authorization for the model.