Skip to content

How to Build a Property Portal with BayutAPI: A Complete Guide

BayutAPI Team ·

Property portals are one of the most profitable categories of web applications in the UAE. Dubai alone sees billions of dollars in real estate transactions every month, and buyers, renters, and investors all start their search online. Building a property portal that aggregates real listings with accurate data is a genuinely viable business.

The hard part has always been the data. Scraping is fragile and legally risky. Building direct relationships with agents and agencies takes years. But with a structured API, you can go from zero to a working property portal in a weekend.

This guide walks through building a property portal from the ground up using BayutAPI. We will cover each layer of the application: location search, property listing pages, detail views, agent contact info, and pagination. Code examples are provided in both Python and JavaScript.

What You Need

Before writing any code, you need three things:

  1. A BayutAPI key — Sign up on RapidAPI and subscribe to a plan. The free tier gives you enough requests to build and test your portal.
  2. A frontend framework — Any framework works. React, Vue, Astro, Next.js, or even plain HTML and JavaScript. The API returns JSON, so your frontend just needs to render it.
  3. A basic backend or serverless function — You should not expose your API key in client-side code. Use a thin backend (Express, Flask, FastAPI) or serverless functions (Cloudflare Workers, Vercel Edge Functions) to proxy API requests.

The architecture is simple: your frontend sends requests to your backend, your backend adds the API key and forwards them to BayutAPI, and the response flows back to the user.

Step 1: Setting Up Location Search with Autocomplete

Every property portal starts with a search bar. Users type a location name and expect suggestions. BayutAPI’s autocomplete endpoint handles this perfectly.

Here is how to implement it in Python:

import requests

BASE_URL = "https://bayut14.p.rapidapi.com/v2"
HEADERS = {
    "x-rapidapi-host": "bayut14.p.rapidapi.com",
    "x-rapidapi-key": "YOUR_API_KEY"
}

def autocomplete(query: str, purpose: str = "for-sale") -> list[dict]:
    response = requests.get(
        f"{BASE_URL}/autocomplete",
        headers=HEADERS,
        params={"query": query, "purpose": purpose}
    )
    response.raise_for_status()
    data = response.json()
    return data["data"]["locations"]

And the equivalent in JavaScript using fetch:

const BASE_URL = "https://bayut14.p.rapidapi.com/v2";
const HEADERS = {
  "x-rapidapi-host": "bayut14.p.rapidapi.com",
  "x-rapidapi-key": "YOUR_API_KEY",
};

async function autocomplete(query, purpose = "for-sale") {
  const params = new URLSearchParams({ query, purpose });
  const response = await fetch(`${BASE_URL}/autocomplete?${params}`, {
    headers: HEADERS,
  });
  const json = await response.json();
  return json.data.locations;
}

Each location in the response includes a name, a hierarchy (e.g., UAE > Dubai > Dubai Marina), and an externalID that you will use in subsequent search queries. Render these as dropdown suggestions in your search bar. When the user selects a location, store its externalID for the next step.

A good UX pattern is to debounce the autocomplete input by 300ms so you don’t fire a request on every keystroke.

Step 2: Implementing Property Search with Filters

Once the user selects a location, you hit the search-property endpoint to fetch listings. This endpoint supports filters for purpose, property type, price range, bedrooms, furnishing status, and sort order.

def search_properties(
    location_id: str,
    purpose: str = "for-sale",
    property_type: str = None,
    price_min: int = None,
    price_max: int = None,
    rooms: str = None,
    sort: str = "popular",
    page: int = 1,
) -> dict:
    params = {
        "location_ids": location_id,
        "purpose": purpose,
        "sort": sort,
        "page": str(page),
    }
    if property_type:
        params["property_type"] = property_type
    if price_min is not None:
        params["price_min"] = str(price_min)
    if price_max is not None:
        params["price_max"] = str(price_max)
    if rooms:
        params["rooms"] = rooms

    response = requests.get(
        f"{BASE_URL}/properties",
        headers=HEADERS,
        params=params,
    )
    response.raise_for_status()
    return response.json()

The JavaScript equivalent:

async function searchProperties({
  locationId,
  purpose = "for-sale",
  propertyType,
  priceMin,
  priceMax,
  rooms,
  sort = "popular",
  page = 1,
}) {
  const params = new URLSearchParams({
    location_ids: locationId,
    purpose,
    sort,
    page: String(page),
  });
  if (propertyType) params.set("property_type", propertyType);
  if (priceMin) params.set("price_min", String(priceMin));
  if (priceMax) params.set("price_max", String(priceMax));
  if (rooms) params.set("rooms", rooms);

  const response = await fetch(`${BASE_URL}/properties?${params}`, {
    headers: HEADERS,
  });
  return response.json();
}

The response includes a data object with a properties array and pagination fields (total, totalPages, page). Each property in the array has a title, price, location, area, room count, photos, and an externalID that links to its detail page.

Build your listing page by rendering each property as a card with the key details and a link to its full page.

Step 3: Building Property Detail Pages

When a user clicks on a listing, you fetch its full details using the property-details endpoint. This returns everything about the property: full description, all photos, amenities, floor plans, agent info, and geographic coordinates.

def get_property(external_id: str) -> dict:
    response = requests.get(
        f"{BASE_URL}/property-detail",
        headers=HEADERS,
        params={"external_id": external_id},
    )
    response.raise_for_status()
    return response.json()
async function getProperty(externalId) {
  const params = new URLSearchParams({ external_id: externalId });
  const response = await fetch(`${BASE_URL}/property-detail?${params}`, {
    headers: HEADERS,
  });
  return response.json();
}

The detail page is where you can differentiate your portal. Show a photo gallery, render the description with proper formatting, display a map using the coordinates, and list amenities. The title field is a localized object — use title.en for the English name.

Key fields to display

  • Priceprice (integer, in AED)
  • Titletitle.en
  • Photosphotos array, each with a url field
  • Locationlocation array with hierarchy levels
  • Detailsrooms, baths, area (in square feet)
  • Descriptiondescription (HTML string in some cases, plain text in others)
  • Amenitiesamenities array with group names and amenity text
  • AgentcontactName and agency object

Step 4: Adding Agent Contact Information

A property portal is only useful if the user can contact someone about the listing. The property detail response includes basic agent info, but you can get the full agent profile using the agent-details endpoint.

def get_agent(agent_id: str) -> dict:
    response = requests.get(
        f"{BASE_URL}/agent-detail",
        headers=HEADERS,
        params={"agent_id": agent_id},
    )
    response.raise_for_status()
    return response.json()

Display the agent’s name, photo, phone number, and the agency they belong to. You can also link to a page showing all their listings using the agent-properties endpoint with their ownerID.

This gives your portal a professional feel — users see who they are contacting and can browse an agent’s other listings before reaching out.

Step 5: Pagination and Performance Tips

BayutAPI returns paginated results. The search response includes total, totalPages, hitsPerPage, and page (1-based). Use these to build pagination controls on your listing pages.

Here are performance tips for a production portal:

Cache aggressively

Location autocomplete results rarely change. Cache them in memory or in a key-value store like Redis for at least 24 hours. Property search results can be cached for shorter periods — 15 to 60 minutes depending on your freshness requirements.

Pre-fetch the next page

When the user is viewing page 1 of results, pre-fetch page 2 in the background. This makes pagination feel instant.

Use CDN for images

Property photos are hosted on external URLs. If you are proxying them, put a CDN in front. If you are linking directly, the photos are already served from a CDN.

Limit initial data

On listing cards, you only need the title, price, rooms, area, one photo, and location. Don’t fetch full property details until the user clicks through. This keeps your search responses fast and your rendering efficient.

Handle errors gracefully

API requests can fail due to network issues, rate limits, or invalid parameters. Always wrap your API calls in try/catch blocks and show meaningful error messages to users.

Putting It All Together

The complete flow for your property portal looks like this:

  1. User types a location in the search bar
  2. Your backend calls /autocomplete and returns suggestions
  3. User selects a location and applies filters
  4. Your backend calls /properties with the location ID and filters
  5. Frontend renders listing cards with pagination
  6. User clicks a listing
  7. Your backend calls /property-detail with the external ID
  8. Frontend renders the full property page with photos, details, and agent info

This architecture works whether you are building a traditional server-rendered app, a single-page application, or a mobile app with an API backend.

Next Steps

If you are using Python, our Python integration guide walks through setting up a complete client library. For JavaScript developers, the JavaScript guide covers the same ground with Node.js and browser examples.

For inspiration on what to build, check out our property listing websites use case, which covers the business side of running a property portal.

Ready to start building? Get your API key and have your first property search running in under five minutes. The free tier includes enough requests to build, test, and launch a basic portal. When you are ready to scale, upgrade your plan on RapidAPI and keep building.

B

BayutAPI Team

Building tools for UAE real estate developers

Ready to Build with UAE Real Estate Data?

Get your API key and start making requests in minutes. Free tier available with 900 requests per month.