REALTY-DATA.
Property APIGuides

Quickstart

Authenticate, discover the RESO service, query Property, and follow continuation pages

This quickstart uses the RESO Web API from discovery through synchronization. It covers the public contract that is ready for integration: the service document, $metadata, the Property collection, direct key retrieval, and opaque continuation paging.

Use placeholders in development

The hostname and API key below are examples. Every production request is scoped by the signed entitlement associated with the supplied key.

Configure authentication

export REALTY_API_KEY="<issued-api-key>"
export REALTY_API_BASE="https://api.example.invalid"
const baseUrl = "https://api.example.invalid";
const headers = { "x-api-key": process.env.REALTY_API_KEY! };
import os
import requests

base_url = "https://api.example.invalid"
headers = {"x-api-key": os.environ["REALTY_API_KEY"]}

Discover active resources

curl --request GET \
  --url "$REALTY_API_BASE/reso/odata" \
  --header "x-api-key: $REALTY_API_KEY" \
  --header "Accept: application/json"

The service document is the activation authority. Only request entity sets listed in its value array.

{
  "@odata.context": "https://api.example.invalid/reso/odata/$metadata",
  "value": [
    { "name": "Property", "kind": "EntitySet", "url": "Property" }
  ]
}

Inspect the schema

Fetch $metadata before generating queries or typed clients. It is the authoritative field, type, nullability, key, and entity-set contract.

curl --request GET \
  --url "$REALTY_API_BASE/reso/odata/\$metadata" \
  --header "x-api-key: $REALTY_API_KEY" \
  --header "Accept: application/xml"

The searchable Property field catalog provides the same implemented field inventory in a human-friendly form.

Query a compact Property page

Start with $select, a bounded $top, and a deterministic order. Use $filter for RESO field criteria.

curl --get \
  --url "$REALTY_API_BASE/reso/odata/Property" \
  --header "x-api-key: $REALTY_API_KEY" \
  --header "Accept: application/json" \
  --data-urlencode '$select=ListingKey,ListingId,OriginatingSystemName,StandardStatus,ListPrice,ModificationTimestamp' \
  --data-urlencode '$filter=StandardStatus eq '\''Active'\''' \
  --data-urlencode '$orderby=ModificationTimestamp asc,ListingKey asc' \
  --data-urlencode '$top=100' \
  --data-urlencode '$ignorenulls=true'
{
  "@odata.context": "https://api.example.invalid/reso/odata/$metadata#Property",
  "value": [
    {
      "ListingKey": "listing-key-01",
      "ListingId": "A1234567",
      "OriginatingSystemName": "ExampleMLS",
      "StandardStatus": "Active",
      "ListPrice": 725000,
      "ModificationTimestamp": "2026-07-22T14:30:00Z"
    }
  ],
  "@odata.nextLink": "https://api.example.invalid/reso/odata/Property?...&$skiptoken=OPAQUE"
}

Follow continuation pages

When @odata.nextLink is present, request that URL exactly as returned. Do not decode, edit, or combine its $skiptoken with $skip. The absence of @odata.nextLink means the result set is complete.

let next: string | undefined = `${baseUrl}/reso/odata/Property?$top=100`;

while (next) {
  const page = await fetch(next, { headers }).then((response) => response.json());
  await consume(page.value);
  next = page["@odata.nextLink"];
}

Choose the correct identity query

A Placekey identifies a physical property and may group many listing records. A ListingKey identifies one RESO Property record.

GET /reso/odata/Property?placekey=223-227@5vg-82n-pgk
GET /reso/odata/Property('listing-key-01')?$select=ListingKey,StandardStatus,ListPrice
GET /reso/odata/Property?$filter=OriginatingSystemName eq 'ExampleMLS' and ListingId eq 'A1234567'

On this page