# Real Estate Search

`POST /realestate_search`

- Live: `POST https://gdapi.globaldata.net.au/api/v2/realestate_search`
- Sandbox: `POST https://sandbox-gdapi.globaldata.net.au/api/v2/realestate_search`

The real estate search query returns **Australian real estate listing history** (sale, sold, and rental events) for
a given property address, sourced from the Global Data Australian property universe.

The query accepts an address in one of three formats:
- A **GNAF ID** (the unique GNAF address identifier)
- A **full address** as a single string
- A **structured address** with street_address, suburb, state, and postcode as separate fields

Results are returned in **reverse chronological order** (most recent first).

An optional `date_from` parameter can be provided to filter results to only include records on or after
the specified date.

## Address resolution

The `address` object in the response represents the resolved address that was used to search the
real estate universe:

- When a **GNAF ID** is provided, the returned address is the exact address referenced by that GNAF ID.
- When a **text-based address** is provided (full address or structured address), the system will resolve
  the input to the best matching address in the GNAF database. The returned address may include minor
  corrections or standardisations compared to the original input (e.g. corrected spelling, expanded
  abbreviations, standardised formatting) if these were needed to match a valid address.

## Response behaviour

The endpoint always returns HTTP 200. The `message` and `address` fields indicate the outcome:

| Scenario | `message` | `address` | `records` |
|:---------|:----------|:----------|:----------|
| Address found, records exist | `Ok` | Populated with the resolved address | Array of real estate records |
| Address found, no records | `Ok` | Populated with the resolved address | Empty array |
| Address not found | `Address not found` | Empty object | Empty array |

An address may not be found if the GNAF ID does not exist, or if the text-based address
could not be resolved to a valid address in the GNAF database.

## Address input modes

Only one address input mode can be used per request. The modes are mutually exclusive:

| Mode | Parameters | Description |
|:-----|:-----------|:------------|
| GNAF ID | `gnaf_id` | Direct lookup by GNAF address ID. This is the most efficient lookup. |
| Full address | `full_address` | A complete address as a single string (e.g. "20 Hardy St Lilydale VIC 3140"). The system will parse and resolve the address. |
| Structured address | `street_address`, `suburb`, `state`, `postcode` | Address components provided separately. At minimum, `street_address` is required. |

## Sandbox environment

When simulating queries in the sandbox environment the system will use a reduced sample dataset.
The following GNAF IDs will return real estate records:

| GNAF ID        | Address        | Suburb        | State | Postcode | Records |
|:---------------|:---------------|:--------------|:------|:---------|:--------|
| GAVIC421647320 | 20 HARDY ST    | LILYDALE      | VIC   | 3140     | 3       |
| GANSW716615055 | 35 YARALLA ST  | CONCORD WEST  | NSW   | 2138     | 2       |
| GANSW712900961 | 22 BRABYN ST   | WINDSOR       | NSW   | 2756     | 1       |

The following GNAF IDs exist in the sample dataset but have no real estate records:

| GNAF ID        | Address          | Suburb          | State | Postcode |
|:---------------|:-----------------|:----------------|:------|:---------|
| GAVIC419608268 | 8 WALTHAM ST     | RICHMOND        | VIC   | 3121     |
| GANSW705730292 | 6 WATERVIEW CL   | PORT MACQUARIE  | NSW   | 2444     |

## Request body

| Field | Type | Description |
|-------|------|-------------|
| `gnaf_id` | string [max 15 characters] | The GNAF address ID. Mutually exclusive with full_address and street_address/suburb/state/postcode. Example: `GAVIC421647320` |
| `full_address` | string [4..255 characters] | A complete Australian address as a single string. The system will parse and resolve this to a GNAF address. Mutually exclusive with gnaf_id and street_address/suburb/state/postcode. Example: `20 Hardy St Lilydale VIC 3140` |
| `street_address` | string [4..100 characters] | The street address component (e.g. "20 Hardy St"). Required when using structured address mode. Mutually exclusive with gnaf_id and full_address. Example: `20 Hardy St` |
| `suburb` | string [3..60 characters] | The suburb name. Used with street_address for structured address mode. Example: `Lilydale` |
| `state` | string | The Australian state or territory abbreviation. Used with street_address for structured address mode. Enum: `ACT`, `NSW`, `NT`, `QLD`, `SA`, `TAS`, `VIC`, `WA` Example: `VIC` |
| `postcode` | string [3..4 characters] | The 3 or 4 digit Australian postcode. Used with street_address for structured address mode. Pattern: `^\d{3,4}$` Example: `3140` |
| `date_from` | string (date) | Optional date filter in YYYY-MM-DD format. When provided, only real estate records with a date on or after this value will be returned. Example: `2015-01-01` |

**Sample request**

```json
{
    "gnaf_id": "GAVIC421647320",
    "full_address": "20 Hardy St Lilydale VIC 3140",
    "street_address": "20 Hardy St",
    "suburb": "Lilydale",
    "state": "VIC",
    "postcode": "3140",
    "date_from": "2015-01-01"
}
```

## Responses

### 200 Result of real estate search

Content type: `application/json`

| Field | Type | Description |
|-------|------|-------------|
| `message` | string | A message indicating the result of the request. This will be `Ok` if the request was successful. Example: `Ok` |
| `api_reference` | string (uuid) | A unique identifier for this request Example: `738d9a89-b6fe-4fc1-96be-1389b2a506a2` |
| `total_records` | integer | Number of real estate records in the result set Example: `3` |
| `address` | object | The resolved address details. Empty object if the address could not be found. |
| `address.address_id` | string | The GNAF address ID Example: `GAVIC421647320` |
| `address.address` | string | The combined street address Example: `20 HARDY ST` |
| `address.suburb` | string | The suburb Example: `LILYDALE` |
| `address.state` | string | The state Example: `VIC` |
| `address.postcode` | string | The postcode Example: `3140` |
| `records` | array of objects | Real estate listing records for this address, sorted by date descending (most recent first) |
| `records[].listing_type` | string | The type of real estate listing: * `sale` - Property listed for sale * `sold` - Property has been sold * `rent` - Property listed for rent Enum: `sale`, `sold`, `rent` Example: `sale` |
| `records[].property_type` | string | The type of property (e.g. house, townhouse, apartment, unit, flat, studio) Example: `townhouse` |
| `records[].num_bedrooms` | integer | Number of bedrooms Example: `3` |
| `records[].num_bathrooms` | integer | Number of bathrooms Example: `3` |
| `records[].num_car_spaces` | integer | Number of car spaces Example: `2` |
| `records[].date` | string (date) | The date of the listing or sale (YYYY-MM-DD) Example: `2018-03-01` |
| `records[].estate_agent` | string | The name of the estate agent Example: `ABC Property` |
| `records[].price` | string | The listed or sold price. For rentals this will include the rental period (e.g. "$550 per week"). Example: `$720,000` |

**Sample response**

```json
{
    "message": "Ok",
    "api_reference": "738d9a89-b6fe-4fc1-96be-1389b2a506a2",
    "total_records": 3,
    "address": {
        "address_id": "GAVIC421647320",
        "address": "20 HARDY ST",
        "suburb": "LILYDALE",
        "state": "VIC",
        "postcode": "3140"
    },
    "records": [
        {
            "listing_type": "sale",
            "property_type": "townhouse",
            "num_bedrooms": 3,
            "num_bathrooms": 3,
            "num_car_spaces": 2,
            "date": "2018-03-01",
            "estate_agent": "ABC Property",
            "price": "$720,000"
        }
    ]
}
```

Standard error responses: 400, 401, 402, 403, 429, 5XX (see [Common error responses](/docs/reference/general/common-error-responses.md))

