# Aqar.fm Monitor — Saudi New Listings & Price Drops (EN/AR) (`s3nafps/aqar-monitor`) Actor

Get alerts for new Aqar.fm listings and price drops in Saudi Arabia. Schedule it daily; English + Arabic fields, price per m², district comparison.

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

## Pricing

from $5.00 / 1,000 change reporteds

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 Monitor — Saudi New Listings & Price Drops (EN/AR)

Get alerts when Aqar.fm lists a new property, or changes a price, on any search in Saudi Arabia. Schedule it daily and each run reports only what changed since the last one. Every row comes with English and Arabic fields, the price per m², and a comparison with other listings in the same district.

### How it works

- **The first run builds a baseline.** It scans your search, saves what it sees, and returns nothing. The log says how many listings it is now tracking.
- **Every later run returns only changes:** new listings, price drops, and price increases.
- **The monitor's memory is kept on your Apify account**, in a key-value store named `aqar-monitor-state`.
- **Each search has its own memory.** Changing the filters or the start URLs starts a separate monitor. If you set a **Monitor name**, that monitor keeps its memory even when you change the filters.

### Set it up in 2 minutes

1. Choose a search: pick a **City** and **Category**, add any filters, or paste Aqar.fm search URLs into **Start URLs**.
2. Click **Save as task**.
3. Set the task to run **daily** with a schedule.
4. Open **Integrations** and connect email, Slack, Google Sheets or a webhook to receive the new rows.

**Use one saved task per search.** Two tasks with exactly the same search share the same memory.

### What each alert contains

- **`changeType`**: `new`, `price_drop` or `price_increase`.
- **`previousPriceSar`** and **`priceChangePct`**: the price the monitor last saw and the percent change. A negative percent means the price fell. Both are empty for new listings.
- **`districtMedianPricePerSqm`** and **`priceVsDistrictMedianPct`**: how the price per m² compares with similar listings in the same district, from the listings scanned in this run (at least 5 are needed).
- **`firstSeenAt`**, **`detectedAt`** and **`monitorName`**: when the monitor first saw the listing, when the change was detected, and which monitor reported it.
- The search-page fields from [Aqar.fm Scraper](https://apify.com/s3nafps/aqar-scraper): titles and descriptions in English and Arabic, price, area, bedrooms, district, photos, advertiser and links. Detail-only fields such as licences and dates are not included.

**Listings to track** sets how many listings of the search are scanned and watched each run. The default is 500 and the maximum is 5,000. Changing this number does not reset the monitor.

### Pricing

You pay only for what the monitor checks and reports.

| Event | Price |
|---|---|
| Listing checked | $0.30 per 1,000 |
| Change reported | $5 per 1,000 |

Example: a daily run that checks 500 listings and reports about 20 changes costs about $0.25 a day ($0.15 for the checks and $0.10 for the changes). The first run only charges for listings checked, because it reports no changes.

If you set a spending limit, the Actor tracks no more listings than the limit can pay for. Changes it cannot pay to deliver are held back and reported on the next run.

### Privacy

The monitor does not open listing detail pages, so the `advertiserPhone` field is always empty. Phone numbers that advertisers type into titles or descriptions are replaced with `[phone removed]`. No login-protected data is collected.

### FAQ

**Why does the first run return nothing?**
The first run only saves a baseline of the listings it sees, so there is nothing to compare against yet. From the second run on, you get the changes.

**How do I start a monitor over?**
Change the **Monitor name**. A new name starts a fresh monitor with no memory, so its first run is a baseline run again. The old memory stays in the `aqar-monitor-state` store.

**Why did an older ad not show up as new?**
Only ads posted after your monitor's last check are reported as new. Older ads that move into your search's range are added to the monitor's memory silently.

**Can a new ad be missed?**
If more new ads are posted between two runs than your "Listings to track" setting, the extra ones can be missed. For busy searches, raise the limit or run the monitor more often. The run log shows how many older listings entered your search without an alert.

**Are listings outside my filters tracked?**
Listings just outside your filters that the monitor has already seen are remembered, so you get a price-drop alert when one falls into your price range.

**What if a run can't read the monitor's memory?**
The run stops without scanning, charging or changing anything, and the next run catches up.

### 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، ويمكنك تغيير "اسم المراقبة" لبدء مراقبة جديدة.
التسعير: 0.30 دولار لكل 1,000 إعلان مفحوص، و5 دولارات لكل 1,000 تغيير مُبلَّغ عنه.

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

***

More from this developer: [Aqar.fm Scraper](https://apify.com/s3nafps/aqar-scraper), for one-off exports of Aqar.fm listings with English and Arabic fields.

# 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 watch instead of using City and Category. Results come back in the URL's language only (Arabic or English).

## `maxListingsToTrack` (type: `integer`):

How many listings of this search to scan and watch each run.

## `monitorName` (type: `string`):

Optional. Name this monitor to keep several searches apart, or change it to start fresh. Leave empty to use the search itself.

## `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",
  "maxListingsToTrack": 500,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "SA"
  }
}
```

# Actor output Schema

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

Dataset containing the new listings and price changes found in each run

# 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",
    "maxListingsToTrack": 500,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "SA"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("s3nafps/aqar-monitor").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",
    "maxListingsToTrack": 500,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "SA",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("s3nafps/aqar-monitor").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",
  "maxListingsToTrack": 500,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "SA"
  }
}' |
apify call s3nafps/aqar-monitor --silent --output-dataset

```

## MCP server setup

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

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/5qq0x1sBW1dCwGsaj/builds/FQIE8PO6NPHw4J5wa/openapi.json
