# Look up any listing by MLS number or address

Source: https://help.ruuster.com/api/properties-lookup

```http
GET https://api.ruuster.com/v1/properties/lookup
```

Resolve one MLS number or street address to a listing in your MLSs, whether or not it's yours. A lookup call (20 per minute). Use it to turn an MLS number or address from a buyer's email, a showing request or a user's question into a propertyId.

- Authentication: `x-api-key` and `x-email` headers of an owner or admin
- Rate limit: *lookup* call, 20 per minute per key, within the 120 per minute

Finds a listing in any of your brokerage's MLSs by its MLS number, including listings other brokerages hold. It answers one number per call and is a *lookup* call, so it shares the lower limit of 20 per minute (see [Limits](https://help.ruuster.com/api/limits)). To search your own inventory only, use `?mlsRecordId=` on [List listings](https://help.ruuster.com/api/properties-list) instead.

The number is matched exactly as the MLS publishes it, or as the digits-only form where the MLS stores one (see [MLS numbers](https://help.ruuster.com/api/mls-numbers)). Older sales are found too, however long ago they closed, as far back as Ruuster's history for that MLS goes.

With `address`, send the street line plus a city or zip code (the state helps). The house number and the first word of the street name are matched, so "Trail" and "Trl" or a missing unit both find the home; a house number on more than one street of that name returns each, newest first, up to 10.

## Query parameters

| Name | Type | Default | Description |
|---|---|---|---|
| `mlsRecordId` | string | required unless `address` | The MLS number, with or without its leading letters |
| `address` | string | | Instead of `mlsRecordId`: a street address with a city or zip, for example `1013 Crossroads Trl, Milton, GA 30004` |
| `mlsId` | string | all your MLSs | Limit the search to one of your brokerage's MLSs (see `/me` › `mlsIds`) |
| `agent` | string | your default agent | Whose page the listing links (`url`) open under: an `agentId`, email or landing-page slug from [List agents](https://help.ruuster.com/api/agents-list). Whoever signs up from such a link becomes that agent's lead. Without it, links credit your brokerage's default agent (where unassigned leads go). `meta.agent` names the agent credited |

## Response

`data.properties` holds every match, each a property object as described on [List listings](https://help.ruuster.com/api/properties-list), plus `matchedOn` (`exact` or `digits` for an MLS number, `address` for an address). `ownedByYou` is `true` for a listing attributed to your brokerage and `false` otherwise. `data.ambiguous` is `true` when more than one listing matched; send the full number or add `mlsId` to pick one. No match returns an empty list with `200`.

From the result, [Get a listing](https://help.ruuster.com/api/properties-get) returns the full gallery, [List a listing's viewers](https://help.ruuster.com/api/properties-viewers) with `scope=any` names your leads who viewed it, and [Get listing engagement](https://help.ruuster.com/api/properties-engagement) with `scope=any` returns your leads' activity on it over time.

## Example request

cURL:

```bash
curl -s "https://api.ruuster.com/v1/properties/lookup?mlsRecordId=22431187" \
  -H "x-api-key: $RUUSTER_API_KEY" \
  -H "x-email: $RUUSTER_EMAIL"
```

Node.js:

```javascript
const res = await fetch("https://api.ruuster.com/v1/properties/lookup?mlsRecordId=22431187", {
  headers: {
    "x-api-key": process.env.RUUSTER_API_KEY,
    "x-email": process.env.RUUSTER_EMAIL,
  },
});
const body = await res.json();
if (!body.ok) throw new Error(`${body.error.code}: ${body.error.message} (${body.requestId})`);
console.log(body.data);
```

Python:

```python
import os
import requests

res = requests.get(
    "https://api.ruuster.com/v1/properties/lookup?mlsRecordId=22431187",
    headers={"x-api-key": os.environ["RUUSTER_API_KEY"], "x-email": os.environ["RUUSTER_EMAIL"]},
    timeout=30,
)
body = res.json()
if not body["ok"]:
    raise RuntimeError(f'{body["error"]["code"]}: {body["error"]["message"]} ({body.get("requestId")})')
print(body["data"])
```

## Example response

```json
{
  "ok": true,
  "data": {
    "ambiguous": false,
    "properties": [
      {
        "propertyId": "c81f0d2e-5a47-4b93-9e6c-1d8a3f7b2e50",
        "mlsId": "3f4a7b12-6c85-4d93-a1e0-8b2f5c9d7e31",
        "mlsName": "MLS of Southern Arizona",
        "mlsRecordId": "22431187",
        "mlsRecordIdCore": "22431187",
        "address": "7710 N Camino de Oeste",
        "city": "Tucson",
        "state": "AZ",
        "postalCode": "85742",
        "price": 535000,
        "status": "active",
        "mlsStatus": "Active",
        "onMarketDate": "2026-09-19",
        "closeDate": null,
        "listAgentMlsId": "40217",
        "listOfficeMlsId": "5190",
        "matchSource": null,
        "photoUrl": "https://cdn.example-mls.com/22431187/1.jpg",
        "mediaCount": 27,
        "url": "https://saguaro.ruuster.com/listings/c81f0d2e-5a47-4b93-9e6c-1d8a3f7b2e50",
        "previousPropertyIds": [],
        "firstSeenAt": null,
        "lastSeenAt": null,
        "mlsModifiedAt": "2026-10-01T02:14:08Z",
        "updatedAt": null,
        "ownedByYou": false,
        "matchedOn": "exact"
      }
    ]
  },
  "meta": {
    "brokerageId": "4f6c2a9e-8d31-4b57-9a0e-2c7d5e1b8f43",
    "coverage": { "ownershipAsOf": "2026-10-01T06:12:30Z" }
  }
}
```
