---
updatedAt: 2026-07-03T13:44:02.000Z
agentTools:
  projectIndex: https://developer.realestateapi.com/llms.txt
---

# "ids_only": Enriching MLS Results with Public Record Data

<br />

## The problem this solves

MLS data (agent info, listing status, price history) and public record data (tax assessor info, ownership history, sale history) live in different systems. If you need both — say, an MLS search filtered by `beds`/`baths`/`status`, enriched with tax-assessor and ownership data — pulling the **full MLS record** for every result just to throw away most of the fields is wasteful. `ids_only` lets you run the MLS filter cheaply, get back just the REAPI property IDs (`assessorId`), and fetch full public-record detail only for the ids you actually want.

## Flow: MLS Search (`ids_only`) → PropertyDetail / PropertyDetailBulk

**Step 1 — filter in MLS Search, get IDs only:**

`POST /v3/MLSSearch`

```json
{
  "city": "Austin",
  "state": "TX",
  "active": true,
  "bedrooms_min": 3,
  "ids_only": true
}
```

Response:

```json
{
  "data": [203777375, 4753439, 41560455],
  "resultCount": 812,
  "recordCount": 50,
  "resultIndex": 0
}
```

`data` is an array of REAPI property IDs (`assessorId`) — the same ID space used across every RealEstateAPI public-record endpoint.

**Paging note:** results are capped at 50 ids per response, same as a full-record search. Page through with `resultIndex`:

```json
{
  "city": "Austin",
  "state": "TX",
  "active": true,
  "bedrooms_min": 3,
  "ids_only": true,
  "resultIndex": 50
}
```

Keep incrementing `resultIndex` by 50 until `resultIndex + recordCount >= resultCount`.

**Step 2 — enrich with public-record data, one of two ways:**

*Single record:*

`POST /v2/PropertyDetail`

```json
{ "id": 203777375 }
```

*Bulk (up to 1000 ids per call):*

`POST /v2/PropertyDetailBulk`

```json
{ "ids": [203777375, 4753439, 41560455] }
```

This gives you the full public-record shape — tax assessor data, ownership, mortgage/lien info, sale history — for exactly the properties your MLS filter matched.

## Alternative: `public: true` in the same MLS Search call

If you don't need the full standalone public-record shape and are fine with the **curated public-record subset** embedded inline, skip the second round-trip entirely:

`POST /v3/MLSSearch`

```json
{
  "city": "Austin",
  "state": "TX",
  "active": true,
  "bedrooms_min": 3,
  "public": true
}
```

Each returned MLS record now includes a `public` block alongside the MLS fields — one call, one response, no ID hand-off.

You can also request it via field selection instead of the boolean flag:

```json
{ "..." : "...", "fields": ["listingPrice", "public"] }
```

## Which approach to use

| Use `ids_only` + PropertyDetail/PropertyDetailBulk when...                                                                         | Use `public: true` when...                                             |
| ---------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| You want the **full** public-record shape (more fields than the curated MLS-embedded subset)                                       | The curated subset embedded in the MLS record is enough                |
| You're building a two-stage pipeline (store IDs now, enrich later/elsewhere)                                                       | You want everything in a single response                               |
| You need to batch enrichment independently of MLS paging (up to 1000 ids per `PropertyDetailBulk` call vs. 50 per MLS Search page) | You're fine being paged 50-at-a-time, matching your MLS Search cadence |
| You're deduping ids across multiple different MLS searches before enriching once                                                   | You're only running one MLS Search and want minimal round-trips        |

## Entitlements

Both paths are gated by the same public-record plan check. `public: true` (or a `public.*` `fields` selection) without an active public-record plan silently omits the block and returns a `warnings` entry explaining why — it does not error. `PropertyDetail`/`PropertyDetailBulk` calls without the right plan are gated at that endpoint directly. There's no entitlement difference between the two approaches — only an architecture/latency tradeoff.