Files
homeproz/wp-content/plugins/mls-by-hansonxyz/docs/API.md
T
Hanson.xyz Dev acc8ac87a0 wip
2026-01-04 17:50:08 -06:00

7.2 KiB
Executable File

MLS Grid API Reference

Documentation for the MLS Grid API v2 used by this plugin.

Base URL

https://api.mlsgrid.com/v2

Authentication

Bearer token authentication via HTTP header:

Authorization: Bearer {access_token}

Required Header:

Accept-Encoding: gzip

The API requires gzip compression and will return error 400 without it.

Rate Limits

Limit Value
Per Second 2 requests
Per Hour 7,200 requests
Per Day 40,000 requests
Data Per Hour 4GB

Exceeding limits returns HTTP 429 and temporarily suspends access.

Endpoints

Property

GET /Property

Main endpoint for listing data.

Query Parameters:

  • $filter - OData filter expression (required)
  • $expand - Include related resources: Media, Rooms, UnitTypes
  • $top - Records per page (max 5000, max 1000 with $expand)
  • $select - Specific fields to return
  • $orderby - Sort order

Example:

/Property?$filter=OriginatingSystemName eq 'northstar' and MlgCanView eq true&$expand=Media&$top=1000

Member

GET /Member

Agent/member records.

Office

GET /Office

Brokerage office records.

OpenHouse

GET /OpenHouse

Open house event records.

Lookup

GET /Lookup

Field value definitions. Query no more than once per day.

OData Filter Syntax

Operators

Operator Description Example
eq Equals City eq 'Austin'
ne Not equals Status ne 'Sold'
gt Greater than ListPrice gt 200000
ge Greater or equal BedroomsTotal ge 3
lt Less than ListPrice lt 500000
le Less or equal YearBuilt le 2020
and Logical AND City eq 'Austin' and BedroomsTotal ge 3
or Logical OR Limited to 5 per query
in In list City in ('Austin', 'Dallas')

Required Filters

Every Property request MUST include:

OriginatingSystemName eq 'northstar'

For initial import, add:

MlgCanView eq true

Timestamp Filters

For incremental sync:

ModificationTimestamp gt 2024-01-15T00:00:00.000Z

Pagination

Responses include @odata.nextLink field containing URL for next page.

{
    "@odata.context": "...",
    "value": [...],
    "@odata.nextLink": "https://api.mlsgrid.com/v2/Property?$filter=...&$skip=1000"
}

Continue fetching until @odata.nextLink is absent.

Property Fields

Core Fields

Field Type Description
ListingKey string Unique identifier
ListingId string MLS listing number
StandardStatus string Active, Pending, Closed, etc.
ListPrice decimal Listing price
ClosePrice decimal Sold price

Address Fields

Field Type Description
StreetNumber string Street number
StreetName string Street name
StreetSuffix string St, Ave, Blvd, etc.
UnitNumber string Unit/apt number
City string City name
StateOrProvince string State abbreviation
PostalCode string ZIP code
CountyOrParish string County name
Latitude decimal GPS latitude
Longitude decimal GPS longitude

Property Details

Field Type Description
PropertyType string Residential, Land, Commercial, etc.
PropertySubType string Single Family, Condo, etc.
BedroomsTotal integer Total bedrooms
BathroomsTotalInteger integer Total bathrooms
BathroomsFull integer Full bathrooms
BathroomsHalf integer Half bathrooms
LivingArea integer Square feet
LotSizeArea decimal Lot size
LotSizeUnits string Acres, SqFt
YearBuilt integer Year built
GarageSpaces integer Garage spaces

Description Fields

Field Type Description
PublicRemarks string Property description
Directions string Driving directions

Agent/Office Fields

Field Type Description
ListAgentKey string Listing agent ID
ListAgentMlsId string Agent MLS ID
ListOfficeKey string Listing office ID
ListOfficeName string Office name
ListOfficeMlsId string Office MLS ID

Timestamps

Field Type Description
ModificationTimestamp datetime Last modified (use for sync)
PhotosChangeTimestamp datetime Media last changed
ListingContractDate date Listed date
CloseDate date Sold date
DaysOnMarket integer DOM count

MLS Grid Fields

Field Type Description
MlgCanView boolean OK to display (false = delete)
MlgCanUse array Permitted use cases (IDX, VOW, etc.)
OriginatingSystemName string Source MLS identifier

Media (via $expand)

When using $expand=Media, each property includes Media array:

{
    "Media": [
        {
            "MediaKey": "abc123",
            "MediaURL": "https://media.mlsgrid.com/...",
            "Order": 1,
            "ImageWidth": 1200,
            "ImageHeight": 800,
            "MediaModificationTimestamp": "2024-01-15T10:30:00Z"
        }
    ]
}

Important: MediaURL is for downloading only. Store images locally.

Sync Strategy

Initial Import

  1. Query with MlgCanView eq true to get viewable records
  2. Follow @odata.nextLink for pagination
  3. Store ModificationTimestamp from last record

Incremental Sync

  1. Query with ModificationTimestamp gt {last_timestamp}
  2. Do NOT filter by MlgCanView (need to see deletions)
  3. If MlgCanView = false, delete local record

Media Sync

  1. Check PhotosChangeTimestamp on each property
  2. If changed, replace all media for that listing
  3. Match by MediaKey, download via MediaURL
  4. Delete media where MediaKey no longer exists

Error Recovery

Store @odata.nextLink after each page. On failure, resume from that URL.

Best Practices

  1. Sequential requests only - Do not parallelize API calls
  2. Respect rate limits - 2 req/sec max, pause if approaching limits
  3. Use $expand wisely - Reduces per-page limit from 5000 to 1000
  4. Store raw JSON - Keep original response for debugging
  5. Query Lookup sparingly - Once per day maximum
  6. Don't hotlink media - Download and serve from local storage

Error Responses

{
    "error": {
        "code": 400,
        "message": "Error description",
        "target": "misc",
        "details": []
    }
}
Code Meaning
400 Bad request (check filters, missing gzip)
401 Unauthorized (invalid token)
429 Rate limited (wait and retry)
500+ Server error (retry with backoff)

Resources