All search endpoints return results in a consistent envelope with three top-level keys: data, totals, and pagination.
Response Envelope
{
"totals": {
"properties": 1847,
"people": 2134
},
"data": [
{
"dm_property_id": "prop_a1b2c3",
"full_address": "1200 Barton Springs Rd, Austin, TX 78704",
"address": "1200 Barton Springs Rd",
"unit": null,
"city": "Austin",
"state": "TX",
"zip": "78704",
"latitude": 30.2598,
"longitude": -97.7544,
"images": {
"street_view": "https://img.dealmachine.com/sv/30.2598,-97.7544.jpg",
"satellite": "https://img.dealmachine.com/sat/30.2598,-97.7544.jpg",
"roadmap": "https://img.dealmachine.com/map/30.2598,-97.7544.jpg"
},
"estimated_value": 575000,
"equity_percent": 72
}
],
"pagination": {
"page": 1,
"per_page": 25,
"total_results": 1847,
"total_pages": 74,
"has_next_page": true,
"has_previous_page": false
}
}
The data Array
The data array contains the matching records. Each record is a JSON object with always-included fields plus any fields you requested.
- Always-included fields are present on every record regardless of your
fields selection (see below).
- Requested fields appear when you include their
field_id in the fields array.
- Default fields are returned if you omit the
fields parameter or pass an empty array.
- Values match the field type: numbers are JSON numbers, dates are
YYYY-MM-DD strings, booleans are true/false, and multi-select values are arrays of option IDs.
- Null values: Fields with no data return
null.
The totals Object
Every search response includes a totals object with the full count of matching entities across the entire result set, regardless of pagination or anchor.
| Field | Type | Description |
|---|
properties | integer | Total number of matching properties |
people | integer | Total number of matching people/contacts |
These are the same values returned by the Count Properties and Count People endpoints — embedded directly in every search response so you don’t need a separate call.
Always-Included Fields
These fields are present on every record in every response — you never need to request them.
Properties
| Field | Type | Description |
|---|
dm_property_id | string | DealMachine internal property ID |
full_address | string | Complete formatted address (street, city, state, ZIP) |
address | string | Street address line |
unit | string | null | Unit/apt number (e.g., ”# 1”, “Apt 203”) |
city | string | City |
state | string | Two-letter state abbreviation |
zip | string | 5-digit ZIP code |
latitude | number | Property latitude |
longitude | number | Property longitude |
images | object | Image URLs (see Images below) |
People
When anchor is "people", each record in data represents a person. Person records always include:
| Field | Type | Description |
|---|
dm_person_id | string | DealMachine internal person ID |
full_name | string | Full display name |
first_name | string | null | First/given name |
last_name | string | null | Last/family name |
phones | array | Phone numbers (see Phones below) |
emails | array | Email addresses (see Emails below) |
residence | object | Where the person lives (see Residence below) |
property | object | The associated property (see Nested Property below) |
Residence
The residence object is the person’s place of residence — where they currently live. This is not necessarily a property they own; it is simply their home address.
| Field | Type | Description |
|---|
address | string | null | Street address |
unit | string | null | Unit/apt (e.g., “APT 304”, “UNIT 206”) |
city | string | null | City |
state | string | null | Two-letter state abbreviation |
zip | string | null | 5-digit ZIP code |
full_address | string | null | Complete formatted address |
Nested Property
The property object contains the property associated with this person through the search — for example, a property they own, rent, or are otherwise connected to based on the contact_audience parameter. It uses the same structure as a property-anchored result, including images and any requested property fields like estimated_value.
| Field | Type | Description |
|---|
dm_property_id | string | null | DealMachine property ID |
full_address | string | null | Complete formatted property address |
address | string | null | Property street address |
unit | string | null | Unit/apt number |
city | string | null | City |
state | string | null | State abbreviation |
zip | string | null | ZIP code |
latitude | number | null | Property latitude |
longitude | number | null | Property longitude |
images | object | null | Property image URLs |
Images
Every property includes an images object with three views served via img.dealmachine.com. Image URLs are edge-cached and do not consume additional credits.
{
"images": {
"street_view": "https://img.dealmachine.com/sv/30.2598,-97.7544.jpg",
"satellite": "https://img.dealmachine.com/sat/30.2598,-97.7544.jpg",
"roadmap": "https://img.dealmachine.com/map/30.2598,-97.7544.jpg"
}
}
| Key | Description |
|---|
street_view | Street-level photograph of the property |
satellite | Aerial/bird’s-eye satellite view |
roadmap | Map view with streets and labels |
Image URLs follow the pattern https://img.dealmachine.com/{type}/{lat},{lng}.jpg and support optional query parameters:
| Parameter | Applies to | Default | Description |
|---|
size | all | 500x500 (sv), 600x600 (sat/map) | Image dimensions (WxH) |
zoom | sat, map | 19 (sat), 16 (map) | Google Maps zoom level |
heading | sv | — | Camera heading in degrees (0–360) |
fov | sv | 90 | Field of view in degrees |
pitch | sv | 0 | Camera pitch in degrees |
Image URLs are edge-cached and do not consume additional credits. If a street view is not
available for a location, Google returns a grey placeholder tile — the CDN still caches and serves
it.
Phones
The phones array on each person contains all available phone numbers:
{
"phones": [
{
"number": "5125551234",
"type": "wireless",
"do_not_call": false
},
{
"number": "5125559876",
"type": "landline",
"do_not_call": true
}
]
}
| Field | Type | Description |
|---|
number | string | 10-digit phone number |
type | string | wireless, landline, or voip |
do_not_call | boolean | Whether the number is on the national Do Not Call registry |
Emails
The emails array on each person contains all available email addresses:
{
"emails": [
{
"address": "john.smith@example.com"
}
]
}
| Field | Type | Description |
|---|
address | string | Email address |
The credits Object
Every endpoint that consumes credits includes a credits object in the response. This tells you exactly what was charged for the request.
{
"credits": {
"used": 7,
"properties": 5,
"people": 2,
"deduplicated": 3
}
}
| Field | Type | Description |
|---|
used | integer | New credits charged after deduplication |
properties | integer | Property lead records evaluated in this response |
people | integer | People lead records evaluated in this response |
deduplicated | integer | Entities already accessed this billing period (free) |
The credits object is not included on non-billable endpoints (account info, filter metadata, field discovery) or when estimate_cost: true is used on search endpoints.
See Credits for full details on how credits work.
Every response includes pagination metadata. See Pagination & Sorting for full details.
| Field | Type | Description |
|---|
page | integer | Current page number |
per_page | integer | Results per page |
total_results | integer | Total matching records |
total_pages | integer | Total pages available |
has_next_page | boolean | Whether more pages exist after this one |
has_previous_page | boolean | Whether pages exist before this one |
Empty Results
When no records match your filters, the response still uses the same envelope:
{
"totals": {
"properties": 0,
"people": 0
},
"data": [],
"pagination": {
"page": 1,
"per_page": 25,
"total_results": 0,
"total_pages": 0,
"has_next_page": false,
"has_previous_page": false
}
}
Error Responses
When a request fails, the API returns an error object instead of the data envelope. See Errors for the full error format and codes.
{
"error": {
"code": "validation_error",
"message": "Validation failed",
"request_id": "req_abc123def456",
"details": {
"issues": [
{
"path": "filters[0].operator",
"message": "Operator 'contains' is not allowed for NUMBER filter 'estimated_value'"
}
]
}
}
}
Common search-related errors:
| Status | Code | Cause |
|---|
| 400 | validation_error | Invalid filter, operator, value shape, or sort field |
| 401 | invalid_api_key | Missing or invalid API key |
| 429 | rate_limit_exceeded | Too many requests — back off and retry |