Constructing Property Queries
The Datafiniti API lets you build out a wide variety of search queries so you can get the exact data you want.
Querying a single field
The simplest query you can do is querying a single field. Here's an example:
{
"query": "city:Austin"
}
This tells the API to search the property database for any business that has the value Austin in its city field.
You can do similar queries on any of the fields in the property schema. Here's an example that queries the country field:
{
"query": "country:US"
}
You are search for a single address
Querying multiple fields
You can run more complicated queries by combining fields with various boolean operators (e.g., AND OR). For example:
{
"query": "city:Austin AND numBathroom:2"
}
This returns any properties in Austin that have 2 bathrooms.
You can use the OR operator to run broader queries. For example:
{
"query": "city:Austin OR city:Houston"
}
That's not all though. We can group fields and operators with parentheses to do some really fancy stuff:
{
"query": "(categories:Austin OR city:Houston) AND numBathroom:2"
}
Querying multiple values
If you want to query multiple values within the same field, there is a simple way to do this. For example:
{
"query": "city:(Austin OR Houston OR Dallas)"
}
This returns any properties in any of the above cities. This is much simpler than:
{
"query": "city:Austin OR city:Houston OR city:Dallas"
}
Exact matches
You can use " quotes to match the exact string you are searching for
{
"query":"dateUpdated:[2022-01-01 TO *] AND mostRecentStatus:(Rental OR "For Sale")"
}
You can use an exact search to search for specific addresses
{
"query":"address:"3900 Eventide Ave" AND city:("Sacramento") AND postalCode:95835 AND province:("CA") AND country:"US"" }
Address normalization — Datafiniti normalizes street designations to standardized abbreviations, such as converting street to st and drive to dr. Use normalized forms when you need an exact match against Datafiniti property data. Learn more in Normalized Property Addresses.
Fuzzy Matching
The fuzzy_match parameter controls how the address field in your query is matched against property records. By default, Datafiniti applies its own normalization standard to the address field so that minor variations in spelling, formatting, or abbreviation still return the records you expect.
The three accepted values for fuzzy_match behave as follows:
on— Datafiniti matches theaddressfield using its own normalization standard, autocorrecting the supplied value to a matching record. This is the default behavior.off— Theaddressfield value is matched exactly as supplied, with no normalization. Only records that exactly match will be returned.retry— Datafiniti first matches as ifoff. If no record is found, it then attempts to fuzzy match as ifon. This gives you the precision of an exact match while falling back to a broader search only when needed.
For the full feature guide, see Fuzzy Match.
Fuzzy match on
With the default (on) behavior, minor variations in the address string are still matched. For an address like 1100 Congress Ave., Austin, TX 78701, the following queries would all return results:
- 1100 Congress Ave
- 1100 Congress Avenue
- 1100 Congress Ave, Austin
- 1100 Congress Ave, Austin, TX 78701
{
"query": "address:"100 Congress Ave, Austin, Texas 78701"",
"fuzzy_match": "on",
"num_records": 5,
"download": false,
"format": "json"
}
Exact matching
Set fuzzy_match to off when you need precise results and want to avoid close-but-not-exact matches. This is useful when you already know the exact stored value and want to guarantee that only matching records are returned.
{
"query": "address:"123 Main Street" AND city:Austin AND province:TX",
"fuzzy_match": "off",
"num_records": 5,
"download": false,
"format": "json"
}
Exact string matching
When using fuzzy_match: off, remember to wrap multi-word values in escaped quotes (field:\"value\") so the API treats them as a single exact string rather than separate terms.
Retry matching
Set fuzzy_match to retry when you want the best of both approaches. The API attempts an exact match first, and only falls back to fuzzy matching if the exact search returns zero records.
{
"query": "address:"123 Main Street" AND city:Austin AND province:TX",
"fuzzy_match": "retry",
"num_records": 5,
"download": false,
"format": "json"
}
retry is a good default for address lookups where you want exact results when they exist, but would rather receive close matches than an empty response when they don't.
Address parsing details
When fuzzy matching is active, Datafiniti parses the address field into its component parts (street, city, state, postal code) to normalize and match against stored records. The following details describe how this parsing works.
Address prerequisites
addressfield must start with a digit (no P.O. Box, rural route, etc.)- US-only — state must match a recognized US state abbreviation or name
Supported address formats
| Format | Example |
|---|---|
| Comma after street, city+state+zip space-delimited | 1706 Sierra RD, Austin TX 78759 |
| All fields comma-delimited | 1706 Sierra Road, Austin, TX, 78759 |
| No commas at all (token-walks for street suffix) | 1706 Sierra Road Austin TX 78759 |
| No zip | 1706 Sierra Rd, Austin, TX |
| Full state name, single-word | 1706 Sierra Rd, Austin, Texas |
| Full state name, multi-word | 350 Fifth Ave, New York, New York |
| ZIP+4 | 1706 Sierra Rd, Austin, TX 78759-1234 |
Ambiguous state/suffix 2-letter codes
Some codes are valid both as street suffixes and state abbreviations (e.g., CT = Court or Connecticut, LA = Lane or Louisiana). The splitter requires at least one disambiguator to treat them as a state:
- A zip code is present, OR
- A comma appears before the state token
Without a disambiguator, the code is left as a street suffix. UNAMBIGUOUS_STATES (AL, OR, PA, WY, WA) bypass this check but are still protected by a secondary guard: if splitting would leave the street portion as just a house number (< 2 tokens), the split is rejected.
Other parsing behavior
- Pre-existing
city,province,postalCodefields are never overwritten — the split only populates missing fields. - The no-comma path uses street suffix abbreviation tables to find the boundary between street and city; if no suffix is found, it falls back to treating the last word as the city.
- A bare house number without a street name (< 2 tokens remaining after extracting city/state) is treated as a failed parse, and the original string is returned unchanged.
Wildcards
You can use * to query a field for any value, like this:
{
"query": "prices:*"
}
This will return any properties that have price information. This is helpful if we want to make sure any properties we get back are guaranteed to have certain fields filed out.
Wildcards can do more though. You can also append * to the value we're searching on to broaden its potential matches. For example:
{
"query": "buildingName:Tower*"
}
This will return properties with any of the following in their buildingName field: Tower, Towers, and so on.
Querying sub-fields
Several fields in our schema have sub-fields. For example, reviews has sub-fields like date, rating, and others. Everything you can do to query fields, you can also do to query sub-fields. For example:
{
"query": "reviews.rating:3"
}
will return all properties that have a review with a 3-star rating.
It's important to note here that querying on sub-fields will not only return sub-objects that match your query. The entire field will be returned.
For instance, if a property look likes this:
{
"address": "123 Anywhere Ln",
"reviews:": [
{
"rating": 3
},
{
"rating": 4
}
]
}
then you'll see both rating values in your data, even if you do "query": "reviews.rating:3".
Compound Queries on sub-fields
Along with querying individual sub-fields, you can also query for sub-objects that have multiple fields that meet specific requirements. For example, you can find all properties that have a broker with a listed email and phone number.
{
"query":"{ brokers.emails:* AND brokers.phones:* }",
"num_records":10
}
The key thing to note for these queries is that any sub-field requirements that you want to match within a single sub-object must be contained within curly brackets "****"
Range queries
Any fields that are dates, integers, or doubles will let you search them based on a range.
{
"query": "dateAdded:[2017-01-01 TO 2017-02-01]"
}
will return all properties that have been added to the database between Jan 1, 2017 and Feb 2, 2017.
You can do unbounded range queries as well, like:
{
"query": "dateAdded:[2017-01-01 TO *]"
}
This will return all properties have been added since Jan 1, 2017 until the current date.
You can also use comparison operators like >, >=, <=, and <. These are helpful when you want to search for products that are cheaper or more expensive than certain limits. E.g.:
{
"query": "reviews.rating:>3"
}
returns all properties that have reviews greater than 3.
Excluding values
For some searches, you'll want to exclude certain values from returning. For example, let's say you wanted to find all listings, except for those in the US. You would use the - operator to negate US values:
{
"query": "-country:US"
}
Searching by Address
You can use the API to search via the address field. For example, if you would like to find 2815 Manor Rd you could use the following query.
{
"query":"address:"2815 Manor Rd" AND postalCode:78722"
}
However there are many different ways to approach searching via an address. You can learn more here about Search address in property or business data.
Geo Queries
You can also use the API to do queries based around latitude and longitude values. For example, if you would like to find all properties within 10 miles of a specific point in Austin, Texas you could use the following query.
{
"query":"geoLocation:[-97.7430600,30.2671500,10,mi]"
}
The format for the parameter values is: [ Longitude, Latitude, Distance, Distance Unit ]
You can also use the following units for measuring distance:
m - meters
mi - miles
ft - feet
in - yards
mm - millimeters
km - kilometers
NM - nautical miles
cm - centimeters
Count Feature
As an alternative or used for testing purposes you can set your num_records to 0 in your property search query. This is will only return the num_found of the query and will cost 0 credits to search.
Try it in the API Playground
Test your property search queries directly in the API reference.
{
"query": "country:US",
"num_records":0
}
Count Feature
Please note that this is feature is only for paid accounts. So please check your account plan or contact <support@datafinti.co.>
Paging Over Results
As an alternative to running a download, you can also use the API to page through the data. This approach allows you to consume one chunk at a time.
POST https://api.datafiniti.co/v4/properties/paginate?page=1&limit=500
{
"query": "keys:*"
}
The pagination endpoint uses the following parameters:
- page - You specify which chunk of data you would like to access. You can iterate the page to work your way through all of the results. You cannot paginate further than the 10,000th record.
- limit - This specifies the number of results you want returned within the page. The maximum number of results that can be returned per page is 500.
Regex Queries
You can filter any field with a regular expression by wrapping the pattern in forward slashes (/.../). This lets you match values by shape rather than by exact string. For example, to match any postal code beginning with 787 followed by two more digits:
{
"query": "postalCode:/787[0-9]{2}/"
}
Character classes — [0-9]
A character class matches any single character from a set. Use [0-9] for a digit, and {n} to repeat it. For example, all five-digit postal codes:
{
"query": "postalCode:/[0-9]{5}/"
}
Wildcards — .*
. matches any single character and * repeats the preceding token zero or more times, so .* matches any run of characters. For example, any city name that contains ville:
{
"query": "city:/.*ville.*/"
}
Alternation — |
The pipe (|) matches any one of several alternatives. For example, either of two provinces:
{
"query": "province:/TX|CA/"
}
Combining with other operators
Regex patterns work alongside boolean operators and other fields just like any other query:
{
"query": "city:"Dallas"|"Austin" AND postalCode:/787[0-9]{2}/ AND numBedroom:3"
}
Regex reference
- Wrap the pattern in forward slashes:
field:/pattern/. [0-9]matches a digit;{n}and{n,m}set repetition counts..matches any character,*repeats zero or more, and.*matches any run of characters.- The pipe
|is alternation (OR) between patterns.