Realestate.com.au API: Australian Listings as JSON
realestate.com.au has no self-serve API for reading its listings. To get them as JSON, call GET /v1/realestate-com-au/search with a location such as Sydney, NSW and a channel of buy, rent or sold. Each successful call costs 1 credit and returns a page of listings with address, price text, bedrooms, agency and a listing URL, which /v1/realestate-com-au/property takes to return the full listing.
Is there an official realestate.com.au API?
Not one we could find for reading listings: there is no public, self-serve API that returns realestate.com.au search results to any developer who signs up. REA Group, which runs the site, sells property data separately through PropTrack, its data and valuations business, which offers property data APIs including automated valuations (PropTrack, 2026).
If you need automated valuations or a licensed data product, talk to PropTrack. If you need what the listing pages show, as JSON, without a sales process, the realestate.com.au API returns it with the same key as every other API in the catalogue. Data is collected from publicly available sources and returned as found at the time of the call, and whether your use is allowed depends on the site's terms and Australian law.
Which endpoints does the realestate.com.au API have?
Nine GET endpoints, each 1 credit per successful call. Three carry the main flow (locations, search, property). Two give area context: suburb profiles and sales events by state. The other four cover agents and agencies. Most identify a page by its realestate.com.au url, so the URLs a search returns are the inputs to the next call.
| Endpoint | Returns | Required | Optional |
|---|---|---|---|
/v1/realestate-com-au/locations |
Location matches | query |
limit |
/v1/realestate-com-au/autocomplete |
Typeahead matches | query |
limit, types, source |
/v1/realestate-com-au/search |
A page of listings | location |
channel, page, sort, price, room and type filters |
/v1/realestate-com-au/property |
One listing | url |
none |
/v1/realestate-com-au/suburb-profile |
A suburb profile | url |
none |
/v1/realestate-com-au/sales-events |
Sales events | none | state, url |
/v1/realestate-com-au/agents |
Agents | none | url, location, page |
/v1/realestate-com-au/agent-profile |
One agent | url |
none |
/v1/realestate-com-au/agency-profile |
One agency | url |
none |
sales-events takes state as one of act, nsw, nt, qld, sa, tas, vic or wa.
How do you search realestate.com.au listings?
Call GET /v1/realestate-com-au/search with location and, usually, channel. location is free text up to 120 characters, written the way the site writes it, such as Sydney, NSW. If you're not sure how a place is spelled, call /v1/realestate-com-au/locations with query=Sydney first. channel is buy, rent or sold, and page steps through results. This is the request behind the recorded response below:
curl "https://api.perceptlayer.com/v1/realestate-com-au/search?location=Sydney%2C+NSW&channel=buy&page=1" \
-H "X-API-Key: $API_KEY"
Get a free API key if you don't have one; keys go in the X-API-Key header, as the authentication docs explain.
Which search parameters can you use?
Search takes one required parameter and eleven optional ones. The types and limits come from the endpoint definition, and nothing else about them is documented, so don't assume a default sort.
| Parameter | Type | Notes |
|---|---|---|
location |
string, required | Up to 120 characters, such as Sydney, NSW |
channel |
string | buy, rent or sold |
page |
integer | Results page |
sort |
string | Up to 40 characters |
min_price, max_price |
integer | Price bounds |
min_bedrooms, max_bedrooms |
integer | Bedroom bounds |
min_bathrooms |
integer | Minimum bathrooms |
min_carspaces |
integer | Minimum parking spaces |
property_types |
string | Up to 200 characters |
keywords |
string | Up to 200 characters |
For rentals in Parramatta with two or more bedrooms, that's location=Parramatta, NSW&channel=rent&min_bedrooms=2. Switch channel to sold for recent sales in the same area.
What does the recorded response contain?
The response has data.total_results, a pagination object and a listings array. This excerpt, trimmed with …, shows the paging fields and the second listing on the page:
{
"success": true,
"data": {
"channel": "buy",
"location": "Sydney, NSW",
"total_results": 596,
"pagination": {
"page": 1,
"pageSize": 25,
"localities": [{ "searchLocation": "Sydney CBD, NSW" }],
"filters": {
"surroundingSuburbs": true,
…
}
},
"listings": [
…,
{
"id": "151002436",
"url": "https://www.realestate.com.au/property-apartment-nsw-millers+point-151002436",
"property_type": "Apartment",
"address": {
"display": { "fullAddress": "28A High Street, Millers Point, NSW 2000", … },
"suburb": "Millers Point",
"state": "NSW",
"postcode": "2000"
},
"price": "Buyers Guide $2,200,000",
"features": {
"bedrooms": { "value": 3 },
"bathrooms": { "value": 2 },
"parkingSpaces": { "value": 0 },
…
},
"property_sizes": {
"land": { "displayValue": "103", … }
},
"listing_company": {
"name": "LJ Hooker - Blacktown",
"id": "EKORXD",
"ratingsReviews": { "avgRating": 5, "totalReviews": 202 },
…
},
…
}
],
…
}
}
Three details matter when you load this. Room counts sit one level down, under features.bedrooms.value. The listing's url is what the property endpoint takes. And the search resolved Sydney, NSW to the locality Sydney CBD, NSW with surroundingSuburbs: true, which is why a Millers Point listing appears. The first listing on the same page is in Sydney itself, with price set to Contact Agent.
How do you turn the price text into a number?
Keep the raw price string and add a parsed column next to it. On realestate.com.au the price is whatever the agent displays, so one page can mix a guide, a range and no figure at all. In the recorded page, one listing says Contact Agent and the other Buyers Guide $2,200,000. A parser that takes the first dollar figure and leaves the rest empty is honest about what the page gave you:
import os
import re
import requests
URL = "https://api.perceptlayer.com/v1/realestate-com-au/search"
HEADERS = {"X-API-Key": os.environ["API_KEY"]}
MONEY = re.compile(r"\$\s?([\d,]+)")
def parse_price(text):
m = MONEY.search(text or "")
return int(m.group(1).replace(",", "")) if m else None
r = requests.get(URL, params={"location": "Sydney, NSW", "channel": "buy", "page": 1},
headers=HEADERS, timeout=60)
r.raise_for_status()
for item in r.json()["data"]["listings"]:
print(item["id"], item["address"]["suburb"], item["features"]["bedrooms"]["value"],
item["price"], parse_price(item["price"]))
We checked parse_price against the recorded page but haven't run the request loop live for this article. For the two listings in the recorded page, parse_price returns None and 2200000. A range such as a lower and upper figure would return the lower one, so if your analysis needs ranges, capture both matches with MONEY.findall.
What does a suburb-level pull cost?
Each search page is one call and 1 credit, so a full pull costs the number of pages. With total_results 596 and pageSize 25, the recorded Sydney search needs 596 ÷ 25 = 23.84, rounded up to 24 pages: 24 credits. Opening every listing with property adds one call each, 596 credits, for 620 credits in total.
| Step | Calls | Credits |
|---|---|---|
search, 24 pages |
24 | 24 |
property for every listing |
596 | 596 |
| Full pull, buy channel | 620 | 620 |
Run the search pages weekly and skip property for listings you've already stored, and the recurring cost falls to 24 credits plus one call per new listing. That fits easily inside the 1,000 free credits a month. Read total_results from page one rather than hard-coding it, since it changes daily. Failed calls return X-Credits-Used: 0; the credits docs explain the balance, and pricing has what packs cost.
When should you call Domain.com.au as well?
Call both portals when you need coverage rather than one site's view, because a listing can appear on either and the two return different fields. Domain's API has auction results by city and suburb insights by bedrooms and property type; realestate.com.au has agency ratings, sales events by state and suburb profiles. The Domain.com.au guide compares the two response shapes field by field, so it isn't repeated here.
The listing IDs differ between portals, so you can't join on them. Normalise the address (unit, street number, street, suburb, postcode) and match on that; the article on deduplicating listings across sources has the method. To see the fields for your own area first, run a search in the playground on the realestate.com.au API page.
APIs in this post
Frequently asked questions
How much does the realestate.com.au API cost?
Every one of the 9 endpoints costs 1 credit per successful call, and failed calls cost nothing. The recorded Sydney search is 24 pages, so a full pass is 24 credits before opening any listings. Every verified account gets 1,000 free credits a month, and the pricing page has what credit packs cost.
Can I get sold prices from realestate.com.au?
Yes, through the same search endpoint with channel=sold and a location. Sold results come back as listings like the buy channel, with whatever price text the site shows for each sale. Where a sale shows no figure, the parser above returns None, so keep the raw price text next to any parsed number.
Why did my search return listings from other suburbs?
The recorded search shows surroundingSuburbs: true in its filters, and a search for Sydney, NSW returned a listing in Millers Point. If you need one suburb only, filter the listings on address.suburb and address.postcode after the call. Credits are per call, not per listing, so the filtering costs nothing extra.
Does the API return agents' personal details?
Listings include a listers array with the agents' names and job titles as shown on the page, and there are agent and agency profile endpoints. Australia's privacy regulator says personal information can include information about a person's work activities, and lists a name as an example (OAIC, 2026). Use agency-level fields for analysis and drop names you don't need.
What happens when a call fails?
You get an HTTP status and a JSON body with an error code, a message and a request_id, and X-Credits-Used is 0, so a failed property lookup for a withdrawn listing costs nothing. A location over 120 characters fails with invalid_parameters (422). The errors docs list every code and what to do about it.