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

# Enrich by Geocode

Look up properties by geographic coordinates (reverse geocoding). Each item in the `data` array provides a `latitude` and `longitude` pair, and the API returns the property at that location.

<Note>
  Each request accepts up to **250 items** in the `data` array. The response returns every submitted
  item with a `matched` flag indicating whether a property was found.
</Note>

<Warning>
  The previous endpoint path `/v1/enrichment/latlng` still works as an alias but is deprecated.
  Please update your code to use `/v1/enrichment/reverse-geocode`.
</Warning>

## Body Parameters

<ParamField body="data" type="array" required>
  Array of coordinate objects to look up (max 250).

  <Expandable title="Coordinate object properties">
    <ParamField body="latitude" type="number" required>
      Property latitude (e.g., `30.2598`).
    </ParamField>

    <ParamField body="longitude" type="number" required>
      Property longitude (e.g., `-97.7544`).
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="fields" type="string[]">
  [Field IDs](/concepts/fields) to include in results. Can include both property and people fields.
  Omit or pass an empty array for the default set.
</ParamField>

<ParamField body="contact_audience" type="string">
  Which contacts to include on matched properties.

  Options: `owners`, `owners_and_family`, `renters`, `residents`, `none`

  Use `none` or omit this parameter to return property data without contacts or people data credit charges. Any other value includes a `contacts` array.
</ParamField>

***

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.v2.dealmachine.com/v1/enrichment/reverse-geocode" \
    -H "Authorization: Bearer dm_sk_live_xxx" \
    -H "Content-Type: application/json" \
    -d '{
      "data": [
        {
          "latitude": 30.2598,
          "longitude": -97.7544
        },
        {
          "latitude": 30.2271,
          "longitude": -97.7437
        }
      ],
      "fields": ["estimated_value", "equity_percent", "bedrooms", "full_name", "phones"],
      "contact_audience": "owners"
    }'
  ```

  ```typescript Node.js theme={null}
  const response = await fetch('https://api.v2.dealmachine.com/v1/enrichment/reverse-geocode', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${apiKey}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      data: [
        { latitude: 30.2598, longitude: -97.7544 },
        { latitude: 30.2271, longitude: -97.7437 },
      ],
      fields: ['estimated_value', 'equity_percent', 'bedrooms', 'full_name', 'phones'],
      contact_audience: 'owners',
    }),
  });

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

  console.log(`Matched ${totals.matched} of ${totals.submitted}`);
  for (const item of data) {
    if (item.matched) {
      console.log(`${item.full_address} — $${item.estimated_value.toLocaleString()}`);
    } else {
      console.log(`No match at (${item.input.latitude}, ${item.input.longitude})`);
    }
  }
  ```

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

  response = requests.post(
      "https://api.v2.dealmachine.com/v1/enrichment/reverse-geocode",
      headers={"Authorization": f"Bearer {api_key}"},
      json={
          "data": [
              {"latitude": 30.2598, "longitude": -97.7544},
              {"latitude": 30.2271, "longitude": -97.7437},
          ],
          "fields": [
              "estimated_value",
              "equity_percent",
              "bedrooms",
              "full_name",
              "phones",
          ],
          "contact_audience": "owners",
      },
  )

  body = response.json()
  for item in body["data"]:
      if item["matched"]:
          print(f"{item['full_address']} — ${item['estimated_value']:,}")
      else:
          print(f"No match at ({item['input']['latitude']}, {item['input']['longitude']})")
  ```
</RequestExample>

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "data": [
      {
        "input": {
          "latitude": 30.2598,
          "longitude": -97.7544
        },
        "matched": true,
        "dm_property_id": "prop_a1b2c3",
        "full_address": "1200 Barton Springs Rd, Austin, TX 78704",
        "address": "1200 Barton Springs Rd",
        "city": "Austin",
        "state": "TX",
        "zip": "78704",
        "latitude": 30.2598,
        "longitude": -97.7544,
        "estimated_value": 575000,
        "contacts": [
          {
            "dm_person_id": "per_x1y2z3",
            "full_name": "John Smith",
            "phones": [{ "number": "5125551234", "type": "wireless", "do_not_call": false }]
          }
        ]
      },
      {
        "input": {
          "latitude": 30.2271,
          "longitude": -97.7437
        },
        "matched": false,
        "match_failure": {
          "code": "not_found",
          "reason": "No property found at the provided coordinates"
        }
      }
    ],
    "totals": {
      "submitted": 2,
      "matched": 1,
      "unmatched": 1
    },
    "credits": {
      "used": 1,
      "properties": 1,
      "people": 0,
      "deduplicated": 0
    }
  }
  ```

  ```json 400 Validation Error theme={null}
  {
    "error": {
      "code": "validation_error",
      "message": "Validation failed",
      "request_id": "req_abc123def456",
      "details": {
        "issues": [
          {
            "path": "data[0].latitude",
            "message": "latitude is required"
          }
        ]
      }
    }
  }
  ```

  ```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

The response contains a `data` array and a `totals` object. There is no pagination — all submitted items are returned in a single response.

### Matched Result

When `matched` is `true`, the result contains all [always-included property fields](/concepts/response-format#properties) plus any requested fields.

| Field                             | Type    | Description                                                                           |
| --------------------------------- | ------- | ------------------------------------------------------------------------------------- |
| `input`                           | object  | Echo of the original input object                                                     |
| `matched`                         | boolean | `true`                                                                                |
| `dm_property_id`                  | string  | DealMachine internal property ID                                                      |
| `full_address`                    | string  | Complete formatted address                                                            |
| `address`, `city`, `state`, `zip` | string  | Parsed address components                                                             |
| `latitude`, `longitude`           | number  | Property coordinates                                                                  |
| `contacts`                        | array   | Contacts matching `contact_audience`. Omitted when the audience is `none` or not set. |
| *requested fields*                | varies  | Any fields specified in `fields`                                                      |

### Unmatched Result

| Field                  | Type    | Description                                                                           |
| ---------------------- | ------- | ------------------------------------------------------------------------------------- |
| `input`                | object  | Echo of the original input object                                                     |
| `matched`              | boolean | `false`                                                                               |
| `match_failure`        | object  | Structured failure with `code` and `reason`                                           |
| `match_failure.code`   | string  | Machine-readable failure code (see [Match Failure Codes](#match-failure-codes) below) |
| `match_failure.reason` | string  | Human-readable explanation of why no match was found                                  |

### Match Failure Codes

These codes are shared across all enrichment endpoints.

| Code            | Description                                                                                                                           |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `not_found`     | No matching record exists for the provided input                                                                                      |
| `invalid_input` | The input could not be processed (e.g., invalid address, invalid email, invalid phone number). The `reason` field provides specifics. |

### Totals

| Field       | Type    | Description                                 |
| ----------- | ------- | ------------------------------------------- |
| `submitted` | integer | Number of items in the request `data` array |
| `matched`   | integer | Number of items that matched a property     |
| `unmatched` | integer | Number of items that did not match          |

## Credits

This endpoint consumes 1 [property data credit](/concepts/credits) per matched property. A non-`none` `contact_audience` adds people data credits for included contacts. Use `none` for zero people data credits. Only matched results consume credits. Credits are deduplicated within your billing period, so accessing the same entity again is free.

Every response includes a `credits` object with a full breakdown of what was charged. See [Credits](/concepts/credits) for details.

## Notes

* Both `latitude` and `longitude` are required for each item.
* The API matches the nearest property parcel to the provided coordinates. For best results, use coordinates that fall within the property boundary.
* Items are matched independently — one failed match does not affect others.
* The `input` object is always echoed back so you can correlate results with your input data.
* When `contact_audience` is set to an audience other than `none`, each matched result includes a `contacts` array with the same structure and match behavior as [Search Properties](/api-reference/properties/search-properties#contact-match-status).
* The old `/v1/enrichment/latlng` path is still supported as a deprecated alias.
