Skip to content
Scrappa Get API key
Bproperty API 1 credit/request

Bproperty Property Search API Documentation

GET https://scrappa.co/api/bproperty/search?status=rent&min_price=20000&max_price=30000&bedrooms=3&per_page=20

Scrappa's GET /api/bproperty/search returns Bproperty listings in Bangladesh as structured JSON, for sale or for rent, with location, price, bedrooms, bathrooms, type and category filters, sort and paging.

Sale and rent

status is required: sale or rent. Prices are in BDT. A rent price is per month unless price_postfix says otherwise.

What you get

One request returns one page of listings, Bproperty's own match count in total, the real page, per_page and total_pages, and has_more. Each listing has id, slug, bn_id, url, title, description, status, type, price, price_postfix, negotiable, address, latitude, longitude, area, category, features, thumbnail, images, attributes (bedrooms, bathrooms, kitchens, size, floors, furnishing and more), featured, premium, verified, agent and dates. A field Bproperty does not state is left out. A hidden price is null with price_hidden true, never 0. Phone numbers in descriptions are masked. Call the listing endpoint for one full record.

Filters are honoured

Every filter is applied by Bproperty and checked again on each returned listing. A listing that breaks a requested filter is dropped and is never replaced from another page. meta.excluded_on_page counts the dropped ones. Bedrooms and bathrooms match the exact number. Unknown parameters and values return 422. applied_filters echoes what was sent.

Location

Take area from search_params of /api/bproperty/location-autocomplete. Take city from /api/bproperty/cities and category from /api/bproperty/categories. A map box needs all of min_lat, max_lat, min_lng and max_lng. Many listings state no coordinates and are not found by a map box.

Sorting and paging

sort is -orderingDate (default, newest first), -created, price or -price. page is 1-based and per_page is 1 to 50 (default 20). A page past the last one returns an empty list with the real total. It never returns another page's listings.

Agent listings

Set agent_id to list the homes of one agent. Take the id from agent.id of a listing.

Not included

There is no area size filter, because Bproperty offers none. The size of a listing is data only, in attributes.size.

Bproperty Property Search API Documentation 1 credit/request

Endpoint

Request preview
GET
https://scrappa.co/api/bproperty/search?status=rent&min_price=20000&max_price=30000&bedrooms=3&per_page=20
Auth header
x-api-key
Cost
1 credit/request
status = rent
Response preview
200 OK
{
    "success": true,
    "page": 1,
    "per_page": 20,
    "total": 768,
    "total_pages": 39,
    "has_more": true,
    "applied_filters": {
        "status": "rent",
        "min_price": 20000,
        "max_price": 30000,
        "bedrooms": 3,
        "sort": "-orderingDate"
    },
...

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.

19 optional filters available.

status string Required

sale or rent.

Example value rent
type string Optional

residential or commercial.

Example value example
category string Optional

Category id from the categories endpoint.

Example value example
area string Optional

Area id from location-autocomplete.

Example value example
city string Optional

City id from the cities endpoint.

Example value example
agent_id string Optional

Only listings of this agent (agent.id of a listing).

Example value 1234567890
q string Optional

Free text in title, address, description, area or city. A listing number such as BN-29192 also works.

Example value coffee shops
min_price number Optional

Minimum price in BDT.

Example value 20000
max_price number Optional

Maximum price in BDT.

Example value 30000
bedrooms integer Optional

Exact number of bedrooms, 1 to 50.

Example value 3
bathrooms integer Optional

Exact number of bathrooms, 1 to 50.

Example value 10
verified boolean Optional

true for verified listings only.

Example value true
min_lat number Optional

South edge of a map box. Needs max_lat, min_lng and max_lng.

Example value 10
max_lat number Optional

North edge of a map box.

Example value 10
min_lng number Optional

West edge of a map box.

Example value 10
max_lng number Optional

East edge of a map box.

Example value 10
sort string Optional

-orderingDate (default, newest first), -created, price (low to high) or -price (high to low).

Example value relevance
page integer Optional

Result page, 1-based.

Example value 1
per_page integer Optional

Listings per page, 1 to 50. Default 20.

Example value 20

Request Examples

PHP
<?php

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => "https://scrappa.co/api/bproperty/search?status=rent&min_price=20000&max_price=30000&bedrooms=3&per_page=20",
    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/bproperty/search?status=rent&min_price=20000&max_price=30000&bedrooms=3&per_page=20');

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/bproperty/search?status=rent&min_price=20000&max_price=30000&bedrooms=3&per_page=20', 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/bproperty/search?status=rent&min_price=20000&max_price=30000&bedrooms=3&per_page=20',
    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/bproperty/search?status=rent&min_price=20000&max_price=30000&bedrooms=3&per_page=20")
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/bproperty/search?status=rent&min_price=20000&max_price=30000&bedrooms=3&per_page=20", 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/bproperty/search?status=rent&min_price=20000&max_price=30000&bedrooms=3&per_page=20', 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/bproperty/search?status=rent&min_price=20000&max_price=30000&bedrooms=3&per_page=20")
        .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/bproperty/search?status=rent&min_price=20000&max_price=30000&bedrooms=3&per_page=20", 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/bproperty/search?status=rent&min_price=20000&max_price=30000&bedrooms=3&per_page=20"
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/bproperty/search?status=rent&min_price=20000&max_price=30000&bedrooms=3&per_page=20"));
            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/bproperty/search?status=rent&min_price=20000&max_price=30000&bedrooms=3&per_page=20',
            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/bproperty/search?status=rent&min_price=20000&max_price=30000&bedrooms=3&per_page=20")
        .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 per_page total total_pages has_more applied_filters listings +1 more

Common listings fields

id slug bn_id url
JSON Response
200 OK
{
    "success": true,
    "page": 1,
    "per_page": 20,
    "total": 768,
    "total_pages": 39,
    "has_more": true,
    "applied_filters": {
        "status": "rent",
        "min_price": 20000,
        "max_price": 30000,
        "bedrooms": 3,
        "sort": "-orderingDate"
    },
    "listings": [
        {
            "id": "b2yt0jncuz0teyg",
            "slug": "premium-3-bedroom-residence-in-baridhara-diplomatic-zone-29172",
            "bn_id": 29172,
            "url": "https://www.bproperty.com/property/premium-3-bedroom-residence-in-baridhara-diplomatic-zone-29172",
            "title": "Premium 3-Bedroom Residence in Baridhara Diplomatic Zone",
            "description": "Strategic 3,000 sqft semi-furnished apartment for rent in Baridhara.",
            "status": "Rent",
            "type": "Residential",
            "price": 120000,
            "price_postfix": "Per Month",
            "negotiable": true,
            "address": "Dhaka",
            "area": {
                "id": "ia0k6ykx1x0j9gn",
                "name": "Baridhara Diplomatic Zone",
                "city_id": "eyz5vhrduc9tsk0",
                "city": "Dhaka"
            },
            "category": {
                "id": "1fn9ieyhdl7vgya",
                "name": "Apartment",
                "slug": "apartment",
                "property_type": "Residential"
            },
            "features": [
                {
                    "id": "7ni7mtte612sj9i",
                    "name": "Garage"
                },
                {
                    "id": "fcxyt7qo4bs9u9e",
                    "name": "Parking"
                }
            ],
            "thumbnail": "https://api.bproperty.com/api/files/a4alnectuppemjo/b2yt0jncuz0teyg/img_20261006_115448_028_bunbkzami2.webp?thumb=310x0",
            "images": [
                "https://api.bproperty.com/api/files/a4alnectuppemjo/b2yt0jncuz0teyg/img_20261006_115554_859_iip7nlkegs.webp"
            ],
            "image_count": 12,
            "attributes": {
                "bedrooms": 3,
                "bathrooms": 3,
                "size_raw": "3000",
                "size": 3000,
                "size_unit": "sqft",
                "furnishing": "Semi Furnished"
            },
            "featured": true,
            "premium": true,
            "verified": true,
            "is_project": false,
            "agent": {
                "id": "9tbx5mt7au0r2qp",
                "name": "BestBari",
                "role": "buyer",
                "verified": true
            },
            "created_at": "2026-10-17 18:59:05.922Z",
            "expires_at": "2027-04-17 18:59:47.381Z"
        }
    ],
    "meta": {
        "endpoint_family": "search",
        "billable": true,
        "attempts": 1,
        "excluded_on_page": 0
    }
}

Errors

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

422

Filters Rejected

Bproperty refused the filter combination (`upstream_rejected`). Non-billable.

{
    "meta": {
        "attempts": 1,
        "billable": false,
        "retryable": false,
        "endpoint_family": "search"
    },
    "error": {
        "code": "upstream_rejected",
        "message": "Bproperty could not accept the requested filters."
    },
    "success": false
}
422

Validation Error

A query parameter is missing, unknown or unusable. Unknown parameters and unknown values are rejected, never ignored. Non-billable.

{
    "errors": {
        "status": [
            "The selected status is invalid."
        ]
    },
    "message": "The selected status is invalid."
}
503

Upstream Unavailable

Bproperty could not be reached after one retry, answered with an error or changed its format (`upstream_unavailable`, `upstream_blocked`, `parser_drift`). Retryable and never billed. Clients are never rate limited.

{
    "meta": {
        "attempts": 2,
        "billable": false,
        "retryable": true,
        "endpoint_family": "search"
    },
    "error": {
        "code": "upstream_unavailable",
        "message": "Bproperty 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.