> ## Documentation Index
> Fetch the complete documentation index at: https://api.docs.dealmachine.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Response Format

> Understanding the search response envelope and always-included fields

All search endpoints return results in a consistent envelope with three top-level keys: `data`, `totals`, and `pagination`.

## Response Envelope

```json theme={null}
{
  "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](/api-reference/properties/count-properties) and [Count People](/api-reference/people/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](#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](#phones) below)                             |
| `emails`       | array          | Email addresses (see [Emails](#emails) below)                           |
| `residence`    | object         | Where the person lives (see [Residence](#residence) below)              |
| `property`     | object         | The associated property (see [Nested Property](#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.

```json theme={null}
{
  "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           |

<Note>
  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.
</Note>

***

## Phones

The `phones` array on each person contains all available phone numbers:

```json theme={null}
{
  "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:

```json theme={null}
{
  "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.

```json theme={null}
{
  "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](/concepts/credits) for full details on how credits work.

***

## The `pagination` Object

Every response includes pagination metadata. See [Pagination & Sorting](/concepts/pagination) 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:

```json theme={null}
{
  "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](/errors) for the full error format and codes.

```json theme={null}
{
  "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               |
