# Aqar.fm Scraper — Saudi Property Listings & Agents (EN/AR) (`s3nafps/aqar-scraper`) Actor

From $1.50/1K. Scrape Aqar.fm (sa.aqar.fm) Saudi property listings in English + Arabic: price, price per m², below-market flags vs district median, beds, area, GPS, photos, agents, REGA & FAL licences. Riyadh, Jeddah, Dammam, Mecca, Medina and more. No login.

- **URL**: https://apify.com/s3nafps/aqar-scraper.md
- **Developed by:** [mohamed senator](https://apify.com/s3nafps) (community)
- **Categories:** Real estate, Lead generation
- **Stats:** 2 total users, 1 monthly users, 66.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 listing scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Aqar.fm Scraper — Saudi Property Listings & Agents (EN/AR)

Scrape property listings from **Aqar.fm (sa.aqar.fm)**, Saudi Arabia's largest real estate portal, into clean rows with **English and Arabic** fields side by side. Every listing comes with **price per m²** and a **below-market flag** that compares it with similar listings in the same district. Turn on full details to also get **REGA advertising licences, FAL brokerage licences, publish dates**, and more.

Built for investors hunting underpriced deals, agents tracking their market, and proptech teams that need a reliable Saudi property feed.

### What data you get

| Field | Example | Notes |
|---|---|---|
| `id`, `url`, `urlEn` | `6915374`, Aqar links | Arabic and English listing pages |
| `titleEn`, `titleAr` | `Apartment for Rent in Riyadh Al Malqa` | |
| `descriptionEn`, `descriptionAr` | full ad text | English is Aqar's own translation, when Aqar provides one |
| `city`, `cityAr`, `district`, `districtAr` | `Riyadh`, `الرياض`, `Al Malqa`, `حي الملقا` | |
| `category`, `categoryAr`, `propertyType`, `listingPurpose` | `apartments-for-rent`, `rent` | |
| `priceSar`, `rentPeriod` | `75000`, `yearly` | |
| `areaSqm`, `pricePerSqm` | `203`, `369.46` | |
| `districtMedianPricePerSqm`, `priceVsDistrictMedianPct` | `542.27`, `-31.9` | Negative = cheaper than similar listings in the district |
| `bedrooms`, `bathrooms`, `livingRooms`, `streetWidthM` | `3`, `4`, `1` | |
| `latitude`, `longitude` | `24.8048`, `46.6152` | |
| `imageUrls` | photo links | First photo; all photos with full details |
| `advertiserName`, `advertiserType` | `company` | `owner`, `broker` or `company` (precise with full details) |

#### Extra fields with "Include full details"

`publishedAt`, `updatedAt`, `regaAdLicense` (REGA advertising licence), `falLicense` (FAL brokerage licence), `facade` / `facadeAr`, `propertyAgeYears`, `furnished`, all photos, and `advertiserPhone` for **licensed brokers only**.

### How to use

**Simple search:** pick a **City** and **Category**, optionally add price, area, bedroom or district filters, set **Max results**, and run.

```json
{
  "city": "riyadh",
  "category": "apartments-for-rent",
  "district": "Al Malqa",
  "minBedrooms": 3,
  "maxResults": 200
}
```

**Any Aqar search:** paste one or more Aqar.fm search URLs into **Start URLs**. Results come back in the language of the URL (Arabic or English); use City and Category if you need both languages.

```json
{
  "startUrls": [{ "url": "https://sa.aqar.fm/en/villa-for-sale/jeddah" }],
  "maxResults": 100,
  "includeDetails": true
}
```

Cities: Riyadh, Jeddah, Dammam, Al Khobar, Mecca, Medina, Taif, Abha, Tabuk, Buraydah. Categories: apartments, villas, land, buildings and floors (rent or sale), shops and offices (rent). Use Start URLs for anything else on Aqar.

### Pricing

You pay only for listings delivered.

| Event | Price |
|---|---|
| Listing scraped | $1.50 per 1,000 |
| Full details (optional) | +$1.50 per 1,000 |

1,000 listings cost **$1.50**, or **$3.00** with full details. If you set a spending limit on your run, the Actor stops at that limit.

### Get alerts instead of full exports

Want only **new listings and price drops** for a search, every day? Use [Aqar.fm Monitor](https://apify.com/s3nafps/aqar-monitor): it remembers what it has already seen and returns only the changes, so you can schedule it and send the results to email, Slack or Google Sheets.

### Privacy

This Actor never outputs phone numbers of private owners. The `advertiserPhone` field is filled only for listings advertised by a **FAL-licensed broker**, taken from the government REGA advertisement record that is published with the listing. Phone numbers that advertisers type into titles or descriptions are replaced with `[phone removed]`. No login-protected data is collected.

### FAQ

**Why is the district median empty for some listings?**
The median is calculated from comparable listings in the same run: same city, district, category and rent period. If fewer than 5 such listings were collected, the field stays empty instead of showing a misleading number. Scrape more listings to fill more medians.

**Why are the English fields empty?**
When you use Start URLs, only that URL's language is fetched. Some ads also have no English translation on Aqar, so `descriptionEn` can be empty.

**My district filter returns nothing with a Start URL.**
With Start URLs, district names are matched in that URL's language only. Type the district as it appears on that page (for example `الملقا` for an Arabic URL), or use the City and Category dropdowns, which match both languages.

**The run failed with "Aqar.fm changed its data format".**
Aqar updated its website and the Actor needs an update. You are not charged for listings that could not be read. The Actor is checked daily, so fixes usually follow quickly.

### Feedback

Found a listing or page that doesn't come out right, or need a feature? Open an issue in the **Issues** tab and I'll take a look. If the Actor saves you time, a short review on its Store page helps other people find it.

### بالعربية

أداة لاستخراج إعلانات العقارات من موقع عقار (sa.aqar.fm) في جميع مدن المملكة العربية السعودية.
تحصل على السعر، والمساحة، وسعر المتر، وعدد الغرف، والموقع، والصور، وبيانات المعلن باللغتين العربية والإنجليزية.
تُظهر الأداة مقارنة سعر المتر بمتوسط الحي لاكتشاف العروض الأقل من سعر السوق.
مع خيار "التفاصيل الكاملة": رقم ترخيص الإعلان من الهيئة العامة للعقار، ورقم رخصة فال، وتاريخ النشر، وعمر العقار.
لا تعرض الأداة أرقام هواتف الملاك الأفراد.

إذا وفّرت عليك الأداة الوقت، فإن تقييماً قصيراً في صفحتها على متجر Apify يساعد الآخرين في العثور عليها.

***

Coming soon: **Dubai Property Fair-Price Checker**, comparing any Dubai listing's price with official Dubai Land Department sale prices.

# Actor input Schema

## `city` (type: `string`):

Saudi city to search. Ignored when you provide Start URLs.

## `category` (type: `string`):

Property type and purpose. Ignored when you provide Start URLs.

## `district` (type: `string`):

Optional. Keep only listings whose district contains this text, in English or Arabic (e.g. "Al Malqa" or "الملقا"). With Start URLs, use the language of the URL.

## `minPrice` (type: `integer`):

Optional. For rentals this is the price per rent period shown on Aqar (usually yearly).

## `maxPrice` (type: `integer`):

Optional.

## `minArea` (type: `integer`):

Optional.

## `maxArea` (type: `integer`):

Optional.

## `minBedrooms` (type: `integer`):

Optional.

## `startUrls` (type: `array`):

Optional. Paste Aqar.fm search URLs to scrape instead of using City and Category. Results come back in the URL's language only (Arabic or English).

## `maxResults` (type: `integer`):

Maximum number of listings to return. Start small to check the data.

## `includeDetails` (type: `boolean`):

Also open each listing to get publish/update dates, REGA and FAL licence numbers, facade, property age, furnished status, all photos, and licensed brokers' phone numbers. Charged as an extra event per listing.

## `proxyConfiguration` (type: `object`):

Proxy servers used to reach Aqar.fm. Saudi residential proxies are the default because Aqar.fm blocks datacenter IPs after a few pages.

## Actor input object example

```json
{
  "city": "riyadh",
  "category": "apartments-for-rent",
  "maxResults": 50,
  "includeDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "SA"
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing all scraped listings

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "city": "riyadh",
    "category": "apartments-for-rent",
    "maxResults": 50,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "SA"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("s3nafps/aqar-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "city": "riyadh",
    "category": "apartments-for-rent",
    "maxResults": 50,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "SA",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("s3nafps/aqar-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "city": "riyadh",
  "category": "apartments-for-rent",
  "maxResults": 50,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "SA"
  }
}' |
apify call s3nafps/aqar-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,s3nafps/aqar-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/vN4hFkfymy1bnljd9/builds/6AHJdw39BT3dDOCiL/openapi.json
