Scrappa's GET /api/property-com-au/search returns Property.com.au listings in Australia as structured JSON, for sale (channel=buy), for rent (channel=rent) and recently sold (channel=sold).
What you get
One request returns one page of up to 20 listings in data. Each listing has id, pid, path, url, address (full, suburb, state, postcode), status, price_text, price_numeric, price_numeric_max, price_period, sold_date, beds, baths, cars, land_size, latitude, longitude, images and realestate_com_au_url. price_text is the advertised text, such as Auction Guide $2m or Contact agent. price_numeric is the figure read from it, or null. Rent is per week (price_period is week). A search card has no property type or description: call the listing endpoint with path for those.
pagination has total and total_pages. map_pins has the coordinates and a short form of the matching listings on the whole search, not only this page. search_place names the place Property.com.au searched.
Location
location is the search_location of an autocomplete result, such as Bondi Beach, NSW 2026. Text Property.com.au does not know returns 422 (unknown_location) instead of a nationwide list.
Filters are honoured
Property.com.au applies the channel, sort, type, keyword and surrounding suburbs filters itself, and reports what it applied. If it ignored one, the request returns 422 (upstream_rejected). max_bedrooms has no upstream filter, so the API applies it to the page. Price, bedroom, bathroom and land size limits are checked on every listing too. A listing without the value a filter needs (for example Contact agent with a price filter) is removed. meta.filtered_out counts them, so a page can hold fewer than 20 listings. Unknown parameters and values are rejected with 422.
Property types
property_type accepts house, townhouse, villa, land, acreage and rural. Property.com.au has no working filter for apartments and units, retirement living or blocks of units, so those values are rejected instead of returning every type. A search card has no type, so use the listing endpoint for the property_type of a result.
Surrounding suburbs
Results cover only the place you asked for. Set include_surrounding=true to add nearby suburbs. They are marked is_surrounding_suburb.
Pagination
page is 1-based and the label always equals the page Property.com.au served. A page past the end returns an empty data with the real total. property_type takes one value per request.
Run this endpoint
Endpoint
Parameters
Start with the required fields, then add optional filters only when your use case needs them.
Runnable path
1 required parameter needed before sending a request.
12 optional filters available.
string
Required
The search_location of an autocomplete result, for example Bondi Beach, NSW 2026.
Bondi Beach, NSW 2026
string
Optional
buy (default), rent or sold.
sold
string
Optional
relevance (default), newest, oldest, price_asc, price_desc, next_auction (buy) or next_inspection (buy, rent).
price_desc
integer
Optional
Minimum price in AUD. Rent is per week.
10
integer
Optional
Maximum price in AUD. Rent is per week.
10
integer
Optional
Minimum bedrooms, 0 (studio) to 5.
2
integer
Optional
Maximum bedrooms, 0 to 10.
10
integer
Optional
Minimum bathrooms, 1 to 5.
10
string
Optional
house, townhouse, villa, land, acreage or rural. One type per request.
example
integer
Optional
Minimum land size in square metres.
10
string
Optional
Words the listing text must contain, for example pool.
running shoes
boolean
Optional
true to add listings from surrounding suburbs. Default false.
true
integer
Optional
Result page, 1-based. 20 listings per page.
1
Request Examples
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://scrappa.co/api/property-com-au/search?location=Bondi+Beach%2C+NSW+2026&channel=sold&sort=price_desc&min_bedrooms=2",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: YOUR_API_KEY_HERE"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
<?php
use Illuminate\Support\Facades\Http;
$response = Http::timeout(30)
->withHeaders(['x-api-key' => 'YOUR_API_KEY_HERE'])
->get('https://scrappa.co/api/property-com-au/search?location=Bondi+Beach%2C+NSW+2026&channel=sold&sort=price_desc&min_bedrooms=2');
if ($response->successful()) {
echo $response->body();
} else {
echo "Error: " . $response->status();
}
const options = {
method: 'GET',
headers: {
'x-api-key': 'YOUR_API_KEY_HERE'
}
};
fetch('https://scrappa.co/api/property-com-au/search?location=Bondi+Beach%2C+NSW+2026&channel=sold&sort=price_desc&min_bedrooms=2', options)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.text();
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
const axios = require('axios');
const options = {
method: 'GET',
url: 'https://scrappa.co/api/property-com-au/search?location=Bondi+Beach%2C+NSW+2026&channel=sold&sort=price_desc&min_bedrooms=2',
headers: {
x-api-key: 'YOUR_API_KEY_HERE',
}
};
try {
const response = await axios(options);
console.log(response.data);
} catch (error) {
console.error('Error:', error.message);
}
require 'net/http'
require 'uri'
uri = URI.parse("https://scrappa.co/api/property-com-au/search?location=Bondi+Beach%2C+NSW+2026&channel=sold&sort=price_desc&min_bedrooms=2")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == 'https'
request = Net::HTTP::Get.new(uri.request_uri)
request['x-api-key'] = 'YOUR_API_KEY_HERE'
begin
response = http.request(request)
puts response.body
rescue => e
puts "Error: #{e.message}"
end
import http.client
import json
conn = http.client.HTTPSConnection("scrappa.co")
headers = {
'x-api-key': 'YOUR_API_KEY_HERE',
}
try:
conn.request("GET", "/api/property-com-au/search?location=Bondi+Beach%2C+NSW+2026&channel=sold&sort=price_desc&min_bedrooms=2", headers=headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
except Exception as e:
print(f"Error: {e}")
finally:
conn.close()
import requests
headers = {
'x-api-key': 'YOUR_API_KEY_HERE',
}
try:
response = requests.get('https://scrappa.co/api/property-com-au/search?location=Bondi+Beach%2C+NSW+2026&channel=sold&sort=price_desc&min_bedrooms=2', headers=headers)
response.raise_for_status()
print(response.text)
except requests.exceptions.RequestException as e:
print(f"Error: {e}")
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
public class ApiExample {
public static void main(String[] args) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://scrappa.co/api/property-com-au/search?location=Bondi+Beach%2C+NSW+2026&channel=sold&sort=price_desc&min_bedrooms=2")
.addHeader("x-api-key", "YOUR_API_KEY_HERE")
.build();
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful()) {
System.out.println(response.body().string());
} else {
System.out.println("Error: " + response.code());
}
} catch (IOException e) {
System.out.println("Error: " + e.getMessage());
}
}
}
package main
import (
"fmt"
"net/http"
"io/ioutil"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://scrappa.co/api/property-com-au/search?location=Bondi+Beach%2C+NSW+2026&channel=sold&sort=price_desc&min_bedrooms=2", nil)
if err != nil {
fmt.Println("Error creating request:", err)
return
}
req.Header.Set("x-api-key", "YOUR_API_KEY_HERE")
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error making request:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error reading response:", err)
return
}
fmt.Println(string(body))
}
#!/bin/bash
curl -X GET \
-H "x-api-key: YOUR_API_KEY_HERE" \
"https://scrappa.co/api/property-com-au/search?location=Bondi+Beach%2C+NSW+2026&channel=sold&sort=price_desc&min_bedrooms=2"
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key", "YOUR_API_KEY_HERE");
try
{
var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, "https://scrappa.co/api/property-com-au/search?location=Bondi+Beach%2C+NSW+2026&channel=sold&sort=price_desc&min_bedrooms=2"));
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}
import axios from 'axios';
async function run(): Promise<void> {
try {
const response = await axios({
method: 'GET',
url: 'https://scrappa.co/api/property-com-au/search?location=Bondi+Beach%2C+NSW+2026&channel=sold&sort=price_desc&min_bedrooms=2',
headers: {
'x-api-key': 'YOUR_API_KEY_HERE',
},
});
console.log(response.data);
} catch (error) {
console.error('Error:', error);
}
}
void run();
use reqwest::Client;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new();
let response = client
.get("https://scrappa.co/api/property-com-au/search?location=Bondi+Beach%2C+NSW+2026&channel=sold&sort=price_desc&min_bedrooms=2")
.header("x-api-key", "YOUR_API_KEY_HERE")
.send()
.await?;
println!("{}", response.text().await?);
Ok(())
}
Response Schema
Example response fields are illustrative; inspect the JSON before integrating.
Example response fields
Scan these fields before integrating.
success
data
pagination
search_place
applied_filters
map_pins
meta
Common data fields
id
pid
path
url
{
"success": true,
"data": [
{
"id": "152423404",
"pid": 11646090,
"path": "/nsw/bondi-beach-2026/lamrock-ave/8-56-pid-11646090/",
"url": "https://www.property.com.au/nsw/bondi-beach-2026/lamrock-ave/8-56-pid-11646090/",
"realestate_com_au_url": "https://www.realestate.com.au/sold/property-apartment-nsw-bondi+beach-152423404",
"address": {
"full": "8/56 Lamrock Avenue, Bondi Beach, NSW 2026",
"suburb": "Bondi Beach",
"state": "NSW",
"postcode": "2026"
},
"status": "Recently sold",
"price_text": "$1,300,000",
"price_numeric": 1300000,
"price_numeric_max": 1300000,
"price_period": null,
"currency": "AUD",
"sold_date": "2026-10-24",
"beds": 2,
"baths": 1,
"cars": null,
"land_size": null,
"latitude": -33.89082563,
"longitude": 151.27014554,
"images": [
{
"alt": "Property at 8/56 Lamrock Avenue, Bondi Beach NSW 2026",
"jpg": "https://i2.au.reastatic.net/421x237-crop,progressive/653bfe33923b1fdb74d1e1c7f77daa1ff2c14c644a1206b0798d7110748ab1af/image.jpg",
"webp": "https://i2.au.reastatic.net/421x237-crop,format=webp,progressive/653bfe33923b1fdb74d1e1c7f77daa1ff2c14c644a1206b0798d7110748ab1af/image.jpg"
}
],
"is_surrounding_suburb": false
}
],
"pagination": {
"page": 1,
"page_size": 20,
"returned": 1,
"total": 75,
"total_pages": 4,
"has_more": true,
"next_page": 2
},
"search_place": {
"name": "Bondi Beach, NSW 2026",
"heading": "Properties sold in"
},
"applied_filters": {
"location": "Bondi Beach, NSW 2026",
"channel": "sold",
"sort": "price_desc",
"min_bedrooms": 2,
"include_surrounding": false
},
"map_pins": [
{
"latitude": -33.89082563,
"longitude": 151.27014554,
"label": "$1.3m",
"listings": [
{
"id": "152423404",
"pid": 11646090,
"path": "/nsw/bondi-beach-2026/lamrock-ave/8-56-pid-11646090/",
"address": {
"full": "8/56 Lamrock Avenue, Bondi Beach, NSW 2026",
"suburb": "Bondi Beach",
"state": "NSW",
"postcode": "2026"
},
"status": "Recently sold",
"price_text": "$1,300,000",
"price_numeric": 1300000,
"beds": 2,
"baths": 1
}
]
}
],
"meta": {
"endpoint_family": "search",
"billable": true,
"attempts": 1,
"filtered_out": 0
}
}
Errors
Handle these documented responses before retrying or showing customer-facing failures.
Location or Filter Rejected
Property.com.au does not know the `location` (`unknown_location`), or did not apply a requested filter (`upstream_rejected`). The request is rejected instead of returning a nationwide or unfiltered list. Use `search_location` from autocomplete. Non-billable.
{
"meta": {
"attempts": 1,
"billable": false,
"retryable": false,
"endpoint_family": "search"
},
"error": {
"code": "unknown_location",
"message": "Property.com.au does not know that location. Use search_location from autocomplete."
},
"success": false
}Validation Error
A query parameter is missing, unknown or unusable. Unknown parameters are rejected, never ignored. Non-billable.
{
"errors": {
"sort": [
"The selected sort is invalid."
]
},
"message": "The selected sort is invalid."
}Upstream Unavailable
Property.com.au could not be reached after retries or answered with something unusable (`upstream_unavailable`, `upstream_blocked`, `parser_drift`). Retryable and never billed. Clients are never rate limited.
{
"meta": {
"attempts": 3,
"billable": false,
"retryable": true,
"endpoint_family": "search"
},
"error": {
"code": "upstream_unavailable",
"message": "Property.com.au is temporarily unavailable. Please retry."
},
"success": false
}Generate Code with AI
Copy a ready-made prompt with all the endpoint details, parameters, and example responses. Paste it into ChatGPT, Claude, or any AI assistant to instantly generate working code.
Try It Live
Test this endpoint in our interactive playground with real data.