Skip to content
📊 beginner 15 minutes

Google Sheets Integration Guide

Pull UAE property data directly into Google Sheets using Apps Script. Build live dashboards and trackers without any external tools.

What you'll build: A Google Sheet that auto-populates with live UAE property data
Prerequisites: Google account · RapidAPI account (free)

Prerequisites

  • A Google account with access to Google Sheets
  • A RapidAPI account with a BayutAPI subscription (get your free API key)
  • Basic familiarity with Google Sheets (no coding experience required — just copy and paste the scripts below)

Overview

Google Sheets combined with Apps Script gives you a free, powerful way to pull BayutAPI data into a spreadsheet. You can build property trackers, price comparison tables, and market dashboards — all auto-updating on a schedule. No external tools, no paid integrations, no server required.

Setup: Open the Script Editor

  1. Open a new Google Sheet
  2. Click Extensions > Apps Script
  3. Delete any existing code in the editor
  4. Paste the scripts below and click Save

Authentication

Add your API key as a constant at the top of your script:

const API_KEY = "YOUR_API_KEY";
const API_HOST = "uae-real-estate3.p.rapidapi.com";
const BASE_URL = "https://uae-real-estate3.p.rapidapi.com";

Replace YOUR_API_KEY with the key from your RapidAPI dashboard.

Basic Example: Fetch Properties into a Sheet

This function searches for properties and writes the results to a sheet:

function fetchProperties() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Properties");
  if (!sheet) {
    SpreadsheetApp.getActiveSpreadsheet().insertSheet("Properties");
    return fetchProperties();
  }

  const url = BASE_URL + "/search-property?purpose=for-sale&location_ids=5002&page=1";

  const options = {
    method: "get",
    headers: {
      "x-rapidapi-key": API_KEY,
      "x-rapidapi-host": API_HOST,
    },
    muteHttpExceptions: true,
  };

  const response = UrlFetchApp.fetch(url, options);
  const data = JSON.parse(response.getContentText());

  // Clear existing data
  sheet.clear();

  // Write headers
  const headers = ["Title", "Price (AED)", "Bedrooms", "Bathrooms", "Area (sqft)", "Location", "Purpose"];
  sheet.getRange(1, 1, 1, headers.length).setValues([headers]);
  sheet.getRange(1, 1, 1, headers.length).setFontWeight("bold");

  // Write property data
  const rows = data.data.properties.map((property) => [
    (property.title && property.title.en) || "",
    property.price || 0,
    property.bedrooms || 0,
    property.bathrooms || 0,
    property.area || 0,
    property.location || "",
    property.purpose || "",
  ]);

  if (rows.length > 0) {
    sheet.getRange(2, 1, rows.length, headers.length).setValues(rows);
  }

  // Format price column as currency
  sheet.getRange(2, 2, rows.length, 1).setNumberFormat("#,##0");

  // Auto-resize columns
  for (let i = 1; i <= headers.length; i++) {
    sheet.autoResizeColumn(i);
  }

  SpreadsheetApp.getActiveSpreadsheet().toast(
    `Fetched ${rows.length} properties`,
    "BayutAPI",
    5
  );
}

Location Search Function

Add a custom function that lets you search locations directly from a cell:

function searchLocations(query) {
  if (!query) return "Enter a search query";

  const url = BASE_URL + "/autocomplete?query=" + encodeURIComponent(query) + "&langs=en";

  const options = {
    method: "get",
    headers: {
      "x-rapidapi-key": API_KEY,
      "x-rapidapi-host": API_HOST,
    },
    muteHttpExceptions: true,
  };

  const response = UrlFetchApp.fetch(url, options);
  const data = JSON.parse(response.getContentText());

  if (!data.data || !data.data.locations || data.data.locations.length === 0) {
    return "No locations found";
  }

  // Return array of [name, id, type]
  const results = data.data.locations.map((hit) => [
    hit.name || "",
    hit.externalID || "",
    hit.type || "",
  ]);

  return results;
}

Use it in a cell: =searchLocations("dubai marina")

Advanced Example: Multi-Area Price Comparison

Build a comparison dashboard that shows average prices across multiple areas:

function buildPriceComparison() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Price Comparison");
  if (!sheet) {
    SpreadsheetApp.getActiveSpreadsheet().insertSheet("Price Comparison");
    return buildPriceComparison();
  }

  const areas = [
    { name: "Dubai Marina", id: "5002" },
    { name: "Downtown Dubai", id: "5001" },
    { name: "JVC", id: "5548" },
    { name: "Business Bay", id: "5003" },
    { name: "Palm Jumeirah", id: "5004" },
  ];

  sheet.clear();

  // Headers
  const headers = ["Area", "Avg Price (AED)", "Min Price", "Max Price", "Total Listings", "Avg Price/sqft"];
  sheet.getRange(1, 1, 1, headers.length).setValues([headers]);
  sheet.getRange(1, 1, 1, headers.length).setFontWeight("bold");

  const rows = [];

  areas.forEach((area) => {
    const url = BASE_URL + "/search-property?purpose=for-sale&location_ids=" + area.id + "&page=1";

    const options = {
      method: "get",
      headers: {
        "x-rapidapi-key": API_KEY,
        "x-rapidapi-host": API_HOST,
      },
      muteHttpExceptions: true,
    };

    try {
      const response = UrlFetchApp.fetch(url, options);
      const data = JSON.parse(response.getContentText());
      const hits = data.data.properties;

      if (hits.length > 0) {
        const prices = hits.map((h) => h.price).filter((p) => p > 0);
        const avgPrice = prices.reduce((a, b) => a + b, 0) / prices.length;
        const minPrice = Math.min(...prices);
        const maxPrice = Math.max(...prices);

        const pricesPerSqft = hits
          .filter((h) => h.area > 0 && h.price > 0)
          .map((h) => h.price / h.area);
        const avgPsf = pricesPerSqft.length > 0
          ? pricesPerSqft.reduce((a, b) => a + b, 0) / pricesPerSqft.length
          : 0;

        rows.push([
          area.name,
          Math.round(avgPrice),
          minPrice,
          maxPrice,
          data.data.total,
          Math.round(avgPsf),
        ]);
      }
    } catch (e) {
      rows.push([area.name, "Error", "", "", "", ""]);
    }

    // Pause between requests to respect rate limits
    Utilities.sleep(1000);
  });

  if (rows.length > 0) {
    sheet.getRange(2, 1, rows.length, headers.length).setValues(rows);
    sheet.getRange(2, 2, rows.length, 4).setNumberFormat("#,##0");
  }

  for (let i = 1; i <= headers.length; i++) {
    sheet.autoResizeColumn(i);
  }

  SpreadsheetApp.getActiveSpreadsheet().toast(
    `Compared ${rows.length} areas`,
    "BayutAPI",
    5
  );
}

Automate with Triggers

Set up automatic data refreshes so your sheet stays current:

  1. In the Apps Script editor, click the clock icon (Triggers) in the left sidebar
  2. Click Add Trigger
  3. Configure:
    • Function: fetchProperties (or buildPriceComparison)
    • Event source: Time-driven
    • Type: Day timer (or Hour timer for more frequent updates)
    • Time: Choose your preferred time
  4. Click Save

Your spreadsheet will now auto-update on the schedule you set.

Adding a Custom Menu

Make it easy to run your functions from the Sheets toolbar:

function onOpen() {
  const ui = SpreadsheetApp.getUi();
  ui.createMenu("BayutAPI")
    .addItem("Fetch Properties", "fetchProperties")
    .addItem("Price Comparison", "buildPriceComparison")
    .addToUi();
}

After adding this function, reload the spreadsheet. A “BayutAPI” menu will appear in the toolbar.

Next Steps

Start Building with BayutAPI

Get your free API key and make your first request in under 5 minutes.

900 free requests/month — no credit card required