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

# Filter Values

> Complete reference for filter operators and value shapes

Every filter in a search request is a JSON object with these fields:

```json theme={null}
{
  "filter_id": "estimated_value",
  "operator": "range",
  "value": { "min": 100000, "max": 500000 }
}
```

| Key         | Required | Description                                                                                                               |
| ----------- | -------- | ------------------------------------------------------------------------------------------------------------------------- |
| `filter_id` | Yes      | The filter slug from the [List Filters](/api-reference/filters/list-filters) endpoint                                     |
| `operator`  | Depends  | One of the `allowed_operators` for that filter. **Optional for BOOLEAN filters**; automatically defaults to `is_boolean`. |
| `value`     | Yes      | The filter value. Its shape depends on the operator (see below)                                                           |

The `value` shape is **operator-driven**. For simple operators it's a raw primitive (number, string, or boolean). For complex operators it's an object or array. This page documents every operator and its expected value.

<Tip>
  Use the [List Filters](/api-reference/filters/list-filters) endpoint to discover which operators
  each filter supports. The `allowed_operators` array tells you exactly what's available.
</Tip>

***

## NUMBER

Number filters work with numeric data points like estimated value, equity percentage, square footage, and bedroom count.

### `range`

Match values between a minimum and maximum (inclusive).

```json theme={null}
{
  "filter_id": "estimated_value",
  "operator": "range",
  "value": { "min": 100000, "max": 500000 }
}
```

| Key   | Type   | Required | Description               |
| ----- | ------ | -------- | ------------------------- |
| `min` | number | Yes      | Minimum value (inclusive) |
| `max` | number | Yes      | Maximum value (inclusive) |

### `greater_than`

Match values strictly greater than the given number.

```json theme={null}
{
  "filter_id": "equity_percent",
  "operator": "greater_than",
  "value": 50
}
```

`value` — number. Threshold (exclusive).

### `greater_than_or_equal`

Match values greater than or equal to the given number.

```json theme={null}
{
  "filter_id": "bedrooms",
  "operator": "greater_than_or_equal",
  "value": 3
}
```

`value` — number. Threshold (inclusive).

### `less_than`

Match values strictly less than the given number.

```json theme={null}
{
  "filter_id": "year_built",
  "operator": "less_than",
  "value": 1980
}
```

`value` — number. Threshold (exclusive).

### `less_than_or_equal`

Match values less than or equal to the given number.

```json theme={null}
{
  "filter_id": "bathrooms",
  "operator": "less_than_or_equal",
  "value": 2
}
```

`value` — number. Threshold (inclusive).

### `equals`

Match an exact numeric value.

```json theme={null}
{
  "filter_id": "bedrooms",
  "operator": "equals",
  "value": 4
}
```

`value` — number. Exact value to match.

### `not_equals`

Exclude an exact numeric value.

```json theme={null}
{
  "filter_id": "bedrooms",
  "operator": "not_equals",
  "value": 0
}
```

`value` — number. Value to exclude.

***

## STRING

String filters work with text data like owner name, city, address, and mailing address.

### `contains`

Match records where the field contains the given substring.

```json theme={null}
{
  "filter_id": "owner_name",
  "operator": "contains",
  "value": "Smith"
}
```

`value` — string. Substring to search for (case-insensitive).

### `not_contains`

Exclude records where the field contains the given substring.

```json theme={null}
{
  "filter_id": "owner_name",
  "operator": "not_contains",
  "value": "LLC"
}
```

`value` — string. Substring to exclude (case-insensitive).

### `starts_with`

Match records where the field starts with the given prefix.

```json theme={null}
{
  "filter_id": "city",
  "operator": "starts_with",
  "value": "San"
}
```

`value` — string. Prefix to match.

### `ends_with`

Match records where the field ends with the given suffix.

```json theme={null}
{
  "filter_id": "street_name",
  "operator": "ends_with",
  "value": "Ave"
}
```

`value` — string. Suffix to match.

### `equals`

Match an exact string value.

```json theme={null}
{
  "filter_id": "state",
  "operator": "equals",
  "value": "CA"
}
```

`value` — string. Exact string to match.

### `not_equals`

Exclude an exact string value.

```json theme={null}
{
  "filter_id": "state",
  "operator": "not_equals",
  "value": "TX"
}
```

`value` — string. Exact string to exclude.

### `any_of`

Match records where the field matches any of the provided values.

```json theme={null}
{
  "filter_id": "state",
  "operator": "any_of",
  "value": ["CA", "TX", "FL"]
}
```

`value` — string\[]. Array of strings to match against.

***

## DATE

Date filters work with date fields like last sale date, list date, and year built. All date values use `YYYY-MM-DD` format.

### `date_range`

Match dates between a start and end date (inclusive).

```json theme={null}
{
  "filter_id": "last_sale_date",
  "operator": "date_range",
  "value": { "start": "2020-01-01", "end": "2024-12-31" }
}
```

| Key     | Type   | Required | Description                                   |
| ------- | ------ | -------- | --------------------------------------------- |
| `start` | string | Yes      | Start date in `YYYY-MM-DD` format (inclusive) |
| `end`   | string | Yes      | End date in `YYYY-MM-DD` format (inclusive)   |

### `is_after`

Match dates after a given date.

```json theme={null}
{
  "filter_id": "last_sale_date",
  "operator": "is_after",
  "value": "2023-01-01"
}
```

`value` — string. Date in `YYYY-MM-DD` format.

### `is_before`

Match dates before a given date.

```json theme={null}
{
  "filter_id": "last_sale_date",
  "operator": "is_before",
  "value": "2015-06-01"
}
```

`value` — string. Date in `YYYY-MM-DD` format.

### `equals`

Match an exact date.

```json theme={null}
{
  "filter_id": "last_sale_date",
  "operator": "equals",
  "value": "2024-03-15"
}
```

`value` — string. Date in `YYYY-MM-DD` format.

### `relative_time`

Match dates relative to the current date. This is useful for queries like "sold within the last 6 months" or "listed more than 30 days ago."

```json theme={null}
{
  "filter_id": "last_sale_date",
  "operator": "relative_time",
  "value": {
    "value": 6,
    "unit": "months",
    "direction": "ago",
    "comparison": "less_than"
  }
}
```

| Key          | Type   | Required | Description                                                                |
| ------------ | ------ | -------- | -------------------------------------------------------------------------- |
| `value`      | number | Yes      | Positive integer number of time units.                                     |
| `unit`       | string | Yes      | `"days"`, `"weeks"`, `"months"`, or `"years"`                              |
| `direction`  | string | Yes      | `"ago"` (before now) or `"from_now"` (after now)                           |
| `comparison` | string | Yes      | `"less_than"` (within the period) or `"greater_than"` (outside the period) |

**How it works:** The API calculates a reference date from `value` + `unit` + `direction`, then compares the field value against that date using `comparison`.

<AccordionGroup>
  <Accordion title="Example: Sold within the last 6 months">
    `direction: "ago"` sets the reference date to 6 months before today.
    `comparison: "less_than"` means the sale date is *more recent* than that reference, so it falls within the last 6 months.

    ```json theme={null}
    {
      "filter_id": "last_sale_date",
      "operator": "relative_time",
      "value": {
        "value": 6,
        "unit": "months",
        "direction": "ago",
        "comparison": "less_than"
      }
    }
    ```
  </Accordion>

  <Accordion title="Example: Owned for more than 10 years">
    `direction: "ago"` sets the reference date to 10 years before today.
    `comparison: "greater_than"` means the purchase date is *older* than that reference, so it falls more than 10 years ago.

    ```json theme={null}
    {
      "filter_id": "last_sale_date",
      "operator": "relative_time",
      "value": {
        "value": 10,
        "unit": "years",
        "direction": "ago",
        "comparison": "greater_than"
      }
    }
    ```
  </Accordion>

  <Accordion title="Example: Listed in the last 7 days">
    ```json theme={null}
    {
      "filter_id": "list_date",
      "operator": "relative_time",
      "value": {
        "value": 7,
        "unit": "days",
        "direction": "ago",
        "comparison": "less_than"
      }
    }
    ```
  </Accordion>
</AccordionGroup>

### Export Activity

The `last_exported` filter uses export events recorded for the authenticated organization. It supports every standard DATE operator listed above. It also supports `is_known` to include records that have any export activity or records that have none.

```json theme={null}
{
  "filter_id": "last_exported",
  "operator": "is_after",
  "value": "2026-07-01"
}
```

To find records with no export activity, use a JSON boolean:

```json theme={null}
{
  "filter_id": "last_exported",
  "operator": "is_known",
  "value": false
}
```

`true` matches records with at least one export event. `false` matches records with no export events. Export Activity is available for both property and people searches.

***

## MULTI\_SELECT

Multi-select filters work with fields that have a predefined set of options, like property type, zoning, or MLS status. Option values are numeric IDs — use the [List Filters](/api-reference/filters/list-filters) endpoint to discover the available options and their IDs.

### `contains_any`

Match records that have **any** of the selected options (OR logic).

```json theme={null}
{
  "filter_id": "property_type_id",
  "operator": "contains_any",
  "value": [1, 2, 5]
}
```

`value` — number\[]. Array of option IDs — match if the record has any of these.

### `contains_none`

Match records that have **none** of the selected options.

```json theme={null}
{
  "filter_id": "property_type_id",
  "operator": "contains_none",
  "value": [3, 4]
}
```

`value` — number\[]. Array of option IDs — match if the record has none of these.

### `contains_all`

Match records that have **all** of the selected options (AND logic).

```json theme={null}
{
  "filter_id": "tags",
  "operator": "contains_all",
  "value": [10, 20]
}
```

`value` — number\[]. Array of option IDs — match if the record has all of these.

***

## BOOLEAN

Boolean filters work with true/false fields like absentee owner, vacant, and has pool.

For BOOLEAN filters, you only need to pass `filter_id` and `value` — the operator is automatically inferred.

```json theme={null}
{
  "filter_id": "is_absentee_owner",
  "value": true
}
```

`value` — boolean. `true` or `false`.

<Warning>
  Use native JSON booleans (`true` / `false`), not strings (`"true"` / `"false"`) or numbers (`1` /
  `0`). String or numeric values will be rejected with a validation error.
</Warning>

***

## Quick Reference

| Type                        | Operator                                                                                           | Value                                                                            |
| --------------------------- | -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| NUMBER                      | `range`                                                                                            | `{ "min": number, "max": number }`                                               |
| NUMBER                      | `greater_than`, `greater_than_or_equal`, `less_than`, `less_than_or_equal`, `equals`, `not_equals` | `number`                                                                         |
| STRING                      | `contains`, `starts_with`, `ends_with`, `equals`, `not_equals`, `not_contains`                     | `"string"`                                                                       |
| STRING                      | `any_of`                                                                                           | `["a", "b"]`                                                                     |
| DATE                        | `date_range`                                                                                       | `{ "start": "YYYY-MM-DD", "end": "YYYY-MM-DD" }`                                 |
| DATE                        | `is_after`, `is_before`, `equals`                                                                  | `"YYYY-MM-DD"`                                                                   |
| DATE                        | `relative_time`                                                                                    | `{ "value": number, "unit": string, "direction": string, "comparison": string }` |
| DATE (`last_exported` only) | `is_known`                                                                                         | `true` or `false`                                                                |
| MULTI\_SELECT               | `contains_any`, `contains_none`, `contains_all`                                                    | `[1, 2, 3]`                                                                      |
| BOOLEAN                     | *(automatic)*                                                                                      | `true` or `false`                                                                |

***

## Common Mistakes

<AccordionGroup>
  <Accordion title="Using a string for boolean values">
    **Wrong:**

    ```json theme={null}
    { "filter_id": "is_vacant", "value": "true" }
    ```

    **Right:**

    ```json theme={null}
    { "filter_id": "is_vacant", "value": true }
    ```
  </Accordion>

  <Accordion title="Using an operator not allowed for the filter type">
    A NUMBER filter does not support `contains`. Check the `allowed_operators` array from the [List
    Filters](/api-reference/filters/list-filters) response.
  </Accordion>

  <Accordion title="Wrapping simple values in an object">
    Single-value operators take a raw primitive, not a nested object:

    **Wrong:**

    ```json theme={null}
    { "operator": "greater_than", "value": { "value": 50 } }
    ```

    **Right:**

    ```json theme={null}
    { "operator": "greater_than", "value": 50 }
    ```
  </Accordion>

  <Accordion title="Using option labels instead of IDs for MULTI_SELECT">
    Multi-select filters use numeric option IDs, not human-readable labels:

    **Wrong:**

    ```json theme={null}
    { "operator": "contains_any", "value": ["Single Family", "Multi Family"] }
    ```

    **Right:**

    ```json theme={null}
    { "operator": "contains_any", "value": [1, 2] }
    ```

    Use [List Filters](/api-reference/filters/list-filters) to look up the correct option IDs.
  </Accordion>

  <Accordion title="Wrong date format">
    Dates must be `YYYY-MM-DD`:

    **Wrong:**

    ```json theme={null}
    { "operator": "is_after", "value": "01/15/2024" }
    ```

    **Right:**

    ```json theme={null}
    { "operator": "is_after", "value": "2024-01-15" }
    ```
  </Accordion>
</AccordionGroup>
