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.
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.
19 optional filters available.
string
Required
sale or rent.
rent
string
Optional
residential or commercial.
example
string
Optional
Category id from the categories endpoint.
example
string
Optional
Area id from location-autocomplete.
example
string
Optional
City id from the cities endpoint.
example
string
Optional
Only listings of this agent (agent.id of a listing).
1234567890
string
Optional
Free text in title, address, description, area or city. A listing number such as BN-29192 also works.
coffee shops
number
Optional
Minimum price in BDT.
20000
number
Optional
Maximum price in BDT.
30000
integer
Optional
Exact number of bedrooms, 1 to 50.
3
integer
Optional
Exact number of bathrooms, 1 to 50.
10
boolean
Optional
true for verified listings only.
true
boolean
Optional
true for featured listings only.
true
number
Optional
South edge of a map box. Needs max_lat, min_lng and max_lng.
10
number
Optional
North edge of a map box.
10
number
Optional
West edge of a map box.
10
number
Optional
East edge of a map box.
10
string
Optional
-orderingDate (default, newest first), -created, price (low to high) or -price (high to low).
relevance
integer
Optional
Result page, 1-based.
1
integer
Optional
Listings per page, 1 to 50. Default 20.
20
Request Examples
<?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
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();
}
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));
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);
}
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
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()
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}")
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());
}
}
}
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))
}
#!/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"
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}");
}
}
}
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();
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
{
"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.
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
}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."
}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.