Skip to content
Scrappa Get API key
Private Property API 1 credit/request

Private Property Search

GET https://scrappa.co/api/privateproperty/listings/search?type=residential&deal_type=sale&min_bedrooms=3

Search residential, commercial and farm listings across South Africa. Combine type with deal_type to pick a market. Listings keep their upstream fields, and description_truncated marks the one field that arrives shortened. A malformed location filter is silently ignored upstream rather than rejected, so compare the returned selected_shapes against the location_id you requested to confirm the area filter was applied.

Private Property Search 1 credit/request

Endpoint

Request preview
GET
https://scrappa.co/api/privateproperty/listings/search?type=residential&deal_type=sale&min_bedrooms=3
Auth header
x-api-key
Cost
1 credit/request
Response preview
200 OK
{
    "success": true,
    "page": 1,
    "total_filtered_results": 110757,
    "selected_shapes": [
        {
            "id": 10326,
            "name": "Waterfall Valley"
        }
    ],
    "results": [
        {
            "portalRef": "T5642440",
            "listingPrice": {
...

Parameters

Start with the required fields, then add optional filters only when your use case needs them.

Runnable path

This endpoint has no required query parameters.

23 optional filters available.

type string Optional

residential, commercial, or farm. Default residential.

Example value residential
deal_type string Optional

sale or rent. Default sale.

Example value sale
location_id integer Optional

Location id from locations/children or locations/autocomplete.

Example value 1234567890
location_name string Optional

Name of the chosen location, used for display.

Example value example
location_descriptor string Optional

Parent region of the chosen location, used for display.

Example value example
min_price integer Optional

Minimum price in rand.

Example value 10
max_price integer Optional

Maximum price in rand.

Example value 10
min_bedrooms integer Optional

Minimum bedrooms. Residential only.

Example value 3
min_baths integer Optional

Minimum bathrooms. Residential only.

Example value 10
sub_category[] string Optional

Sub category filter. Valid values depend on type and deal_type.

Example value example
rental_price_type string Optional

PerMonth, PerWeek, PerDay, or PerSquareMetre.

Example value example
location_shape_type integer Optional

Shape type of the chosen location, used for display.

Example value 10
has_pool boolean Optional

Restrict to listings with a pool. Residential only.

Example value true
has_staff_quarters boolean Optional

Restrict to listings with staff quarters. Residential only.

Example value true
has_flatlets boolean Optional

Restrict to listings with flatlets. Residential only.

Example value true
has_borehole boolean Optional

Restrict to listings with a borehole. Residential and farm only.

Example value true
has_scenic_view boolean Optional

Restrict to listings with a scenic view. Residential and farm only.

Example value true
has_alarm boolean Optional

Restrict to listings with an alarm. Residential only.

Example value true
has_electric_fencing boolean Optional

Restrict to listings with electric fencing. Residential only.

Example value true
has_security_post boolean Optional

Restrict to listings with a security post. Residential only.

Example value true
has_access_gate boolean Optional

Restrict to listings with an access gate. Residential only.

Example value true
has_intercom boolean Optional

Restrict to listings with an intercom. Residential only.

Example value true
page integer Optional

Page number, starting at 1.

Example value 1

Request Examples

PHP
<?php

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => "https://scrappa.co/api/privateproperty/listings/search?type=residential&deal_type=sale&min_bedrooms=3",
    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
<?php

use Illuminate\Support\Facades\Http;

$response = Http::timeout(30)
    ->withHeaders(['x-api-key' => 'YOUR_API_KEY_HERE'])
    ->get('https://scrappa.co/api/privateproperty/listings/search?type=residential&deal_type=sale&min_bedrooms=3');

if ($response->successful()) {
    echo $response->body();
} else {
    echo "Error: " . $response->status();
}
JavaScript
const options = {
    method: 'GET',
    headers: {
        'x-api-key': 'YOUR_API_KEY_HERE'
    }
};

fetch('https://scrappa.co/api/privateproperty/listings/search?type=residential&deal_type=sale&min_bedrooms=3', 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));
JavaScript
const axios = require('axios');

const options = {
    method: 'GET',
    url: 'https://scrappa.co/api/privateproperty/listings/search?type=residential&deal_type=sale&min_bedrooms=3',
    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);
}
Ruby
require 'net/http'
require 'uri'

uri = URI.parse("https://scrappa.co/api/privateproperty/listings/search?type=residential&deal_type=sale&min_bedrooms=3")
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
Python
import http.client
import json

conn = http.client.HTTPSConnection("scrappa.co")

headers = {
    'x-api-key': 'YOUR_API_KEY_HERE',
}

try:
    conn.request("GET", "/api/privateproperty/listings/search?type=residential&deal_type=sale&min_bedrooms=3", headers=headers)
    res = conn.getresponse()
    data = res.read()
    print(data.decode("utf-8"))
except Exception as e:
    print(f"Error: {e}")
finally:
    conn.close()
Python
import requests

headers = {
    'x-api-key': 'YOUR_API_KEY_HERE',
}

try:
    response = requests.get('https://scrappa.co/api/privateproperty/listings/search?type=residential&deal_type=sale&min_bedrooms=3', headers=headers)
    response.raise_for_status()
    print(response.text)
except requests.exceptions.RequestException as e:
    print(f"Error: {e}")
Java
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/privateproperty/listings/search?type=residential&deal_type=sale&min_bedrooms=3")
        .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());
        }
    }
}
Go
package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {
    client := &http.Client{}
    req, err := http.NewRequest("GET", "https://scrappa.co/api/privateproperty/listings/search?type=residential&deal_type=sale&min_bedrooms=3", 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))
}
Terminal
#!/bin/bash

curl -X GET \
    -H "x-api-key: YOUR_API_KEY_HERE" \
    "https://scrappa.co/api/privateproperty/listings/search?type=residential&deal_type=sale&min_bedrooms=3"
C#
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/privateproperty/listings/search?type=residential&deal_type=sale&min_bedrooms=3"));
            var content = await response.Content.ReadAsStringAsync();
            Console.WriteLine(content);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }
}
TypeScript
import axios from 'axios';

async function run(): Promise<void> {
    try {
        const response = await axios({
            method: 'GET',
            url: 'https://scrappa.co/api/privateproperty/listings/search?type=residential&deal_type=sale&min_bedrooms=3',
            headers: {
        'x-api-key': 'YOUR_API_KEY_HERE',
            },
        });

        console.log(response.data);
    } catch (error) {
        console.error('Error:', error);
    }
}

void run();
RUST
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/privateproperty/listings/search?type=residential&deal_type=sale&min_bedrooms=3")
        .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 page total_filtered_results selected_shapes results

Common selected_shapes fields

id name
JSON Response
200 OK
{
    "success": true,
    "page": 1,
    "total_filtered_results": 110757,
    "selected_shapes": [
        {
            "id": 10326,
            "name": "Waterfall Valley"
        }
    ],
    "results": [
        {
            "portalRef": "T5642440",
            "listingPrice": {
                "price": 1850000
            }
        }
    ]
}

Errors

Handle these documented responses before retrying or showing customer-facing failures.

503

Upstream Unavailable

Private Property returned an unsuccessful, empty or malformed answer.

{
    "error": {
        "code": "upstream_unavailable",
        "message": "The service is temporarily unavailable. Please retry shortly."
    },
    "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.