> ## 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.

# Count Properties

Returns the total number of properties and people matching a set of filters. Use the same `filters`, `anchor`, and `contact_audience` parameters as [Search Properties](/api-reference/properties/search-properties).

## Body Parameters

<ParamField body="locations" type="array">
  Array of [location objects](/concepts/locations) defining where to search. Required unless filters or protocol filters are provided (max 15). Locations use **OR** logic.

  <Expandable title="Location object properties">
    <ParamField body="type" type="string" required>
      Location type: `state`, `county`, `city`, `zip_code`, `radius`, or `polygon`.
    </ParamField>

    <ParamField body="code" type="string">
      Location identifier. Required for `state` (2-letter abbreviation), `county` (5-digit FIPS code), `city` (place ID), and `zip_code` (5-digit ZIP).
    </ParamField>

    <ParamField body="latitude" type="number">
      Center point latitude. Required for `radius`.
    </ParamField>

    <ParamField body="longitude" type="number">
      Center point longitude. Required for `radius`.
    </ParamField>

    <ParamField body="radius_miles" type="number">
      Search radius in miles. Required for `radius`.
    </ParamField>

    <ParamField body="coordinates" type="array">
      Array of `[longitude, latitude]` pairs defining the boundary. Required for `polygon` (minimum 3 points).
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="filters" type="array">
  Array of [filter objects](/concepts/filter-values). Required unless locations or protocol filters are provided. You can mix property filters (`source_type=properties`) and people filters (`source_type=people`).

  <Expandable title="Filter object properties">
    <ParamField body="filter_id" type="string" required>
      The filter slug from the [List Filters](/api-reference/filters/list-filters) endpoint (e.g., `estimated_value`, `property_type_id`).
    </ParamField>

    <ParamField body="operator" type="string">
      One of the filter's `allowed_operators`. See [Filter Values](/concepts/filter-values) for all operators by type. **Optional for BOOLEAN filters** — automatically defaults to `is_boolean`.
    </ParamField>

    <ParamField body="value" type="any" required>
      The filter value. Shape depends on the operator — can be a number, string, boolean, array, or object. See [Filter Values](/concepts/filter-values).
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="include_lists" type="object">
  Restrict counts to property list IDs, for example `{ "property_list_ids": [123] }`.
</ParamField>

<ParamField body="exclude_lists" type="object">
  Exclude property list IDs, for example `{ "property_list_ids": [456] }`.
</ParamField>

<ParamField body="exclude_previously_exported" type="boolean | object">
  Exclude records already exported by your organization.
</ParamField>

<ParamField body="anchor" type="string" default="properties">
  Controls which entity is counted as `total_results`.

  Use `properties` to count matching properties. Use `people` to count matching people; this requires `contact_audience`.
</ParamField>

<ParamField body="contact_audience" type="string">
  Which contacts to count. **Required** when `anchor` is `people`, optional when `properties`.

  Options: `owners`, `owners_and_family`, `renters`, `residents`
</ParamField>

***

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.v2.dealmachine.com/v1/properties/search/count" \
    -H "Authorization: Bearer dm_sk_live_xxx" \
    -H "Content-Type: application/json" \
    -d '{
      "locations": [
        { "type": "state", "code": "TX" }
      ],
      "anchor": "properties",
      "contact_audience": "owners",
      "filters": [
        {
          "filter_id": "estimated_value",
          "operator": "range",
          "value": { "min": 200000, "max": 600000 }
        },
        {
          "filter_id": "has_absentee_owners",
          "value": true
        }
      ]
    }'
  ```

  ```typescript Node.js theme={null}
  const response = await fetch('https://api.v2.dealmachine.com/v1/properties/search/count', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${apiKey}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      locations: [{ type: 'state', code: 'TX' }],
      anchor: 'properties',
      contact_audience: 'owners',
      filters: [
        {
          filter_id: 'estimated_value',
          operator: 'range',
          value: { min: 200000, max: 600000 },
        },
        {
          filter_id: 'has_absentee_owners',
          value: true,
        },
      ],
    }),
  });

  const counts = await response.json();

  console.log(`Properties: ${counts.total_properties.toLocaleString()}`);
  console.log(`People: ${counts.total_people.toLocaleString()}`);
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.v2.dealmachine.com/v1/properties/search/count",
      headers={"Authorization": f"Bearer {api_key}"},
      json={
          "locations": [{"type": "state", "code": "TX"}],
          "anchor": "properties",
          "contact_audience": "owners",
          "filters": [
              {
                  "filter_id": "estimated_value",
                  "operator": "range",
                  "value": {"min": 200000, "max": 600000},
              },
              {
                  "filter_id": "has_absentee_owners",
                  "value": True,
              },
          ],
      },
  )

  counts = response.json()
  print(f"Properties: {counts['total_properties']:,}")
  print(f"People: {counts['total_people']:,}")
  ```
</RequestExample>

<ResponseExample>
  ```json 200 Anchor: properties theme={null}
  {
    "total_properties": 1847,
    "total_people": 2134,
    "total_results": 1847
  }
  ```

  ```json 200 Anchor: people theme={null}
  {
    "total_properties": 1847,
    "total_people": 3412,
    "total_results": 3412
  }
  ```

  ```json 400 Validation Error theme={null}
  {
    "error": {
      "code": "validation_error",
      "message": "Validation failed",
      "request_id": "req_abc123def456",
      "details": {
        "issues": [
          {
            "path": "contact_audience",
            "message": "contact_audience is required when anchor is 'people'"
          }
        ]
      }
    }
  }
  ```

  ```json 401 Unauthorized theme={null}
  {
    "error": {
      "code": "invalid_api_key",
      "message": "The provided API key is invalid",
      "request_id": "req_def456ghi789"
    }
  }
  ```

  ```json 429 Rate Limited theme={null}
  {
    "error": {
      "code": "rate_limit_exceeded",
      "message": "Too many requests. Please retry after the specified time.",
      "request_id": "req_ghi789jkl012"
    }
  }
  ```
</ResponseExample>

## Response Fields

| Field              | Type    | Description                                                                                          |
| ------------------ | ------- | ---------------------------------------------------------------------------------------------------- |
| `total_properties` | integer | Number of properties matching the filters                                                            |
| `total_people`     | integer | Number of people matching the filters and `contact_audience`                                         |
| `total_results`    | integer | Equals `total_properties` when `anchor` is `properties`, or `total_people` when `anchor` is `people` |

## Notes

* The same filter validation rules apply as [Search Properties](/api-reference/properties/search-properties).
* `contact_audience` is **required** when `anchor` is `"people"` and **optional** when `anchor` is `"properties"`.
