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 = "bayut14.p.rapidapi.com";
const BASE_URL = "https://bayut14.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