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

# Search Activity

Query your past searches and enrichments. Filter by activity type, date range, or specific entity IDs — or use free-text search to find activities by filter names, location codes, enrichment inputs, and more. This endpoint does not consume credits.

## Body Parameters

<ParamField body="query" type="string">
  Free-text search across your activity history. Matches against filter IDs, filter values, location codes, enrichment inputs (email addresses, phone numbers, addresses), and requested field names.

  Examples: `"estimated_value"`, `"TX"`, `"john@example.com"`, `"48201"`, `"equity"`, `"555-123-4567"`, `"1200 Barton Springs"`

  The search is case-insensitive and matches partial strings — searching `"equity"` matches activities that used the `equity_percent` filter.
</ParamField>

<ParamField body="filters" type="object">
  Structured filters for activity history.

  <Expandable title="Filter properties">
    <ParamField body="type" type="string[]">
      Filter by activity type. Omit to include all types. See [Activity Types](/concepts/activity#activity-types) for the full list.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="types" type="string[]">
  Legacy top-level activity type filter. Prefer `filters.type` for new clients.
</ParamField>

<ParamField body="date_range" type="object">
  Filter to activities within a date range. Both fields are optional — omit `start` for "all time before end", omit `end` for "all time after start".

  <Expandable title="Date range properties">
    <ParamField body="start" type="string">
      ISO 8601 timestamp. Only include activities on or after this time.
    </ParamField>

    <ParamField body="end" type="string">
      ISO 8601 timestamp. Only include activities on or before this time.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="entity_ids" type="string[]">
  Find activities that returned specific entity IDs. Pass `dm_person_id` values (e.g., `"per_x1y2z3"`) or `dm_property_id` values (e.g., `"prop_a1b2c3"`). Activities matching **any** of the provided IDs are returned.

  This is useful for answering "have I already accessed this person/property?"
</ParamField>

<ParamField body="page" type="integer" default={1}>
  Page number (min: `1`).
</ParamField>

<ParamField body="per_page" type="integer" default={25}>
  Results per page (min: `1`, max: `100`).
</ParamField>

<ParamField body="sort" type="array">
  Array of sort objects. Defaults to `[{ "field": "created_at", "direction": "desc" }]` (most recent first).

  <Expandable title="Sort object properties">
    <ParamField body="field" type="string" required>
      Field to sort by. Options: `created_at`, `type`, `total_results`, `credits_used`, `relevance`. The `relevance` option is only available when `query` is provided and ranks results by match quality.
    </ParamField>

    <ParamField body="direction" type="string" required>
      `asc` (ascending) or `desc` (descending).
    </ParamField>
  </Expandable>
</ParamField>

***

<RequestExample>
  ```bash cURL — Text search theme={null}
  curl -X POST "https://api.v2.dealmachine.com/v1/activity/search" \
    -H "Authorization: Bearer dm_sk_live_xxx" \
    -H "Content-Type: application/json" \
    -d '{
      "query": "equity",
      "filters": {
        "type": ["search_people", "search_properties"]
      },
      "page": 1,
      "per_page": 25,
      "sort": [
        { "field": "relevance", "direction": "desc" }
      ]
    }'
  ```

  ```bash cURL — Date range theme={null}
  curl -X POST "https://api.v2.dealmachine.com/v1/activity/search" \
    -H "Authorization: Bearer dm_sk_live_xxx" \
    -H "Content-Type: application/json" \
    -d '{
      "filters": {
        "type": ["search_people", "search_properties"]
      },
      "date_range": {
        "start": "2025-06-01T00:00:00Z",
        "end": "2025-06-30T23:59:59Z"
      },
      "page": 1,
      "per_page": 25,
      "sort": [
        { "field": "created_at", "direction": "desc" }
      ]
    }'
  ```

  ```typescript Node.js theme={null}
  const response = await fetch(
    "https://api.v2.dealmachine.com/v1/activity/search",
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${apiKey}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        query: "equity",
        filters: {
          type: ["search_people", "search_properties"],
        },
        page: 1,
        per_page: 25,
        sort: [{ field: "relevance", direction: "desc" }],
      }),
    }
  );

  const { data, pagination } = await response.json();

  console.log(`Found ${pagination.total_results} activities`);
  for (const activity of data) {
    console.log(
      `${activity.created_at} — ${activity.type} — ${activity.result_summary.total_results} results`
    );
  }
  ```

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

  response = requests.post(
      "https://api.v2.dealmachine.com/v1/activity/search",
      headers={"Authorization": f"Bearer {api_key}"},
      json={
          "query": "equity",
          "filters": {
              "type": ["search_people", "search_properties"],
          },
          "page": 1,
          "per_page": 25,
          "sort": [{"field": "relevance", "direction": "desc"}],
      },
  )

  body = response.json()
  for activity in body["data"]:
      print(f"{activity['created_at']} — {activity['type']} — {activity['result_summary']['total_results']} results")
  ```
</RequestExample>

<ResponseExample>
  ```json 200 Success (with query: "equity") theme={null}
  {
    "data": [
      {
        "activity_id": "act_e5f6g7h8",
        "type": "search_properties",
        "created_at": "2025-06-20T11:45:00Z",
        "api_key_id": "key_abc123",
        "api_key_name": "Production integration",
        "matched_on": ["filters: equity_percent", "fields: equity_percent"],
        "request_summary": {
          "locations": [
            { "type": "county", "code": "48201" },
            { "type": "county", "code": "48113" }
          ],
          "filters": [
            { "filter_id": "property_type_id", "operator": "contains_any", "value": [1] },
            { "filter_id": "equity_percent", "operator": "greater_than_or_equal", "value": 40 }
          ],
          "fields": ["estimated_value", "equity_percent", "owner_name"]
        },
        "result_summary": {
          "total_results": 3412,
          "total_pages": 137,
          "pages_retrieved": 5,
          "credits_used": 125,
          "entity_count": {
            "people": 0,
            "properties": 125
          }
        }
      },
      {
        "activity_id": "act_r7s8t9u0",
        "type": "search_people",
        "created_at": "2025-06-28T14:22:00Z",
        "api_key_id": "key_def456",
        "api_key_name": "Data warehouse",
        "matched_on": ["fields: estimated_value"],
        "request_summary": {
          "locations": [
            { "type": "state", "code": "TX" }
          ],
          "filters": [
            { "filter_id": "estimated_value", "operator": "greater_than", "value": 500000 },
            { "filter_id": "has_phone", "value": true }
          ],
          "fields": ["full_name", "phones", "estimated_value"]
        },
        "result_summary": {
          "total_results": 1250,
          "total_pages": 50,
          "pages_retrieved": 3,
          "credits_used": 75,
          "entity_count": {
            "people": 75,
            "properties": 68
          }
        }
      }
    ],
    "pagination": {
      "page": 1,
      "per_page": 25,
      "total_results": 2,
      "total_pages": 1,
      "has_next_page": false,
      "has_previous_page": false
    }
  }
  ```

  ```json 400 Validation Error theme={null}
  {
    "error": {
      "code": "validation_error",
      "message": "Validation failed",
      "request_id": "req_abc123def456",
      "details": {
        "issues": [
          {
            "path": "filters.type[0]",
            "message": "Invalid activity type."
          }
        ]
      }
    }
  }
  ```

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

## Response Fields

### `data`

An array of activity records, each representing a past API request.

| Field             | Type           | Description                                                                                                                                                                          |
| ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `activity_id`     | string         | Unique activity identifier (e.g., `act_r7s8t9u0`). Use this with [Get Activity](/api-reference/activity/get-activity) for full details.                                              |
| `type`            | string         | Activity type. See [Activity Types](/concepts/activity#activity-types).                                                                                                              |
| `created_at`      | string         | ISO 8601 timestamp of when the request was made.                                                                                                                                     |
| `api_key_id`      | string         | Stable identifier for the API key or OAuth token that made the request.                                                                                                              |
| `api_key_name`    | string or null | Current name of the API key. `null` when the matching key record is no longer available.                                                                                             |
| `matched_on`      | string\[]      | Only present when `query` is provided. Shows which parts of the request matched the search term (e.g., `"filters: equity_percent"`, `"locations: TX"`, `"input: john@example.com"`). |
| `request_summary` | object         | Summary of the original request parameters (see below).                                                                                                                              |
| `result_summary`  | object         | Summary of what the request returned (see below).                                                                                                                                    |

### `request_summary`

A condensed view of what was sent in the original request. The shape varies by activity type.

**For search types** (`search_people`, `search_properties`, `count_people`, `count_properties`):

| Field       | Type      | Description                                                  |
| ----------- | --------- | ------------------------------------------------------------ |
| `locations` | array     | The location objects used in the search                      |
| `filters`   | array     | The filter objects with `filter_id`, `operator`, and `value` |
| `fields`    | string\[] | The field IDs requested (empty array if defaults were used)  |

**For enrichment types** (`enrich_email`, `enrich_phone`, `enrich_address`, `enrich_latlng`, `enrich_reverse_geocode`, `enrich_apn`, `enrich_name`):

| Field             | Type      | Description                                                                                     |
| ----------------- | --------- | ----------------------------------------------------------------------------------------------- |
| `enrichment_type` | string    | The enrichment method (`email`, `phone`, `address`, `latlng`, `reverse_geocode`, `apn`, `name`) |
| `items_submitted` | integer   | Number of items in the original request `data` array                                            |
| `fields`          | string\[] | The field IDs requested                                                                         |

### `result_summary`

A summary of the results and cost. The shape varies slightly by activity type.

**For search types:**

| Field                     | Type    | Description                                                                                 |
| ------------------------- | ------- | ------------------------------------------------------------------------------------------- |
| `total_results`           | integer | Total matching records across all pages                                                     |
| `total_pages`             | integer | Total pages available                                                                       |
| `pages_retrieved`         | integer | How many pages you actually fetched (across multiple requests with different `page` values) |
| `credits_used`            | integer | Total credits consumed across all pages retrieved                                           |
| `entity_count.people`     | integer | Unique people returned                                                                      |
| `entity_count.properties` | integer | Unique properties returned                                                                  |

**For enrichment types:**

| Field                     | Type    | Description                |
| ------------------------- | ------- | -------------------------- |
| `total_results`           | integer | Total matched entities     |
| `items_matched`           | integer | Items that found a match   |
| `items_unmatched`         | integer | Items that did not match   |
| `credits_used`            | integer | Credits consumed           |
| `entity_count.people`     | integer | Unique people returned     |
| `entity_count.properties` | integer | Unique properties returned |

**For count types:**

| Field           | Type    | Description                  |
| --------------- | ------- | ---------------------------- |
| `total_results` | integer | The count returned           |
| `credits_used`  | integer | Always `0` (counts are free) |

### `pagination`

| Field               | Type    | Description                                |
| ------------------- | ------- | ------------------------------------------ |
| `page`              | integer | Current page number                        |
| `per_page`          | integer | Results per page                           |
| `total_results`     | integer | Total activity records matching your query |
| `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        |

***

## Text Search

The `query` parameter searches across the full request parameters of every activity. This is the fastest way to find a past search when you remember what filters or inputs you used, but not the exact date or activity ID.

### What Gets Searched

| Activity Type   | Searchable Fields                                                                                                                                         |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Searches**    | Filter IDs (`estimated_value`, `equity_percent`, `has_phone`...), filter values, location types and codes (`TX`, `48201`, `90210`), requested field names |
| **Enrichments** | Enrichment inputs (email addresses, phone numbers, street addresses, APNs, coordinates), requested field names                                            |
| **All types**   | Activity type name                                                                                                                                        |

### Search Behavior

* **Case-insensitive** — `"equity"` matches `equity_percent`
* **Partial matching** — `"barton"` matches `"1200 Barton Springs Rd"`
* **Multi-term** — `"TX equity"` matches activities that contain both `TX` and `equity` anywhere in the request
* **Combinable:** use `query` together with `filters.type`, `date_range`, and `entity_ids` to narrow results further

### Examples

Find all searches that used an equity filter:

```json theme={null}
{ "query": "equity" }
```

Find enrichments where you looked up a specific email:

```json theme={null}
{ "query": "john.smith@example.com", "filters": { "type": ["enrich_email"] } }
```

Find searches in Texas from last month:

```json theme={null}
{
  "query": "TX",
  "filters": {
    "type": ["search_people", "search_properties"]
  },
  "date_range": {
    "start": "2025-06-01T00:00:00Z",
    "end": "2025-06-30T23:59:59Z"
  }
}
```

Find any activity involving a specific address:

```json theme={null}
{ "query": "1200 Barton Springs" }
```

<Tip>
  When using `query`, sort by `relevance` to get the best matches first. Without `query`, `relevance` sort is not available and the default sort is `created_at` descending.
</Tip>

***

## Searching by Entity ID

The `entity_ids` parameter lets you find all past activity that involved a specific person or property. This is especially useful for:

* **Deduplication** — check if you've already accessed an entity before running a new search
* **Audit trail** — see every request that touched a specific entity
* **Cost optimization** — entities accessed within the same billing period are free on repeat

```bash theme={null}
curl -X POST "https://api.v2.dealmachine.com/v1/activity/search" \
  -H "Authorization: Bearer dm_sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "entity_ids": ["per_x1y2z3", "prop_a1b2c3"]
  }'
```

This returns all activities where either `per_x1y2z3` or `prop_a1b2c3` appeared in the results. The match is OR logic — activities matching **any** of the provided IDs are included.

***

## Notes

* This endpoint does **not** consume credits.
* All parameters are optional. An empty request body `{}` returns your most recent activity, sorted newest first.
* Activity is scoped to your organization. All API keys under the same account see the same history.
* The `request_summary` is a condensed view. Use [Get Activity](/api-reference/activity/get-activity) for the full, unmodified request parameters.
* Results are capped at 12 months of history.
