# Saudi Real Estate — Bayut, Wasalt, Aqar.fm, PropertyFinder (`constructive_calm/saudi-real-estate-scraper`) Actor

Saudi-only real estate intelligence across 4 verified platforms: Bayut.sa (72K listings), Wasalt.sa PIF-owned (24K), Aqar.fm, PropertyFinder.sa. REGA license cross-reference, installment plans, Vision 2030 zone tagging, Arabic district normalization. $4/1K listings.

- **URL**: https://apify.com/constructive\_calm/saudi-real-estate-scraper.md
- **Developed by:** [Omar Eldeeb](https://apify.com/constructive_calm) (community)
- **Categories:** Real estate, Lead generation, E-commerce
- **Stats:** 4 total users, 2 monthly users, 100.0% runs succeeded, 2 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

Pay per event

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Saudi Real Estate Scraper

**Saudi-only real estate intelligence across 4 verified platforms.** No UAE-only wrappers pretending to cover KSA. No remote-dev guesses about Arabic district variants. No silent gaps on REGA license cross-reference.

Pulls listings from **Bayut.sa** (72K+ listings), **Wasalt.sa** (24K+, PIF-owned), **Aqar.fm** (1.5M total, #1 in KSA), and **PropertyFinder.sa** — normalizes everything into a single schema, surfaces the **REGA license number as a cross-platform join key**, and auto-tags Vision 2030 mega-project zones (NEOM, Red Sea, Diriyah, ROSHN, Qiddiya).

---

### Why use this actor

- ✅ **REGA license cross-reference.** Saudi Real Estate General Authority license number is the canonical join key across Bayut.sa, Wasalt.sa, and PropertyFinder.sa — surfaced under a single `rega_license_number` field. Aqar.fm doesn't expose it; that's an honest null, not silent data loss.
- ✅ **Installment plan extraction** (Aqar.fm-unique). Most Saudi listings expose 2/4/12-month installment splits. No other actor surfaces these as structured fields.
- ✅ **Vision 2030 zone auto-tagging.** Listings inside NEOM, Red Sea Project, Diriyah Gate, ROSHN developments, Qiddiya, and King Salman Park are auto-tagged via description regex + coordinate bounds.
- ✅ **Arabic district normalization.** Variant spellings of top-50 KSA districts (`النرجس` / `Narjis` / `Narjes` / `Al Narjis`) collapse to canonical English + Arabic forms.
- ✅ **Per-platform field union, not lowest-common-denominator.** PIF/Wasalt's `darReference` Saudi MoJ ID, Bayut's `permitUrl` link to rega.gov.sa, Aqar's REGA-declared reference price — all preserved alongside the unified schema.
- ✅ **No proxy needed for Aqar / Bayut / Wasalt.** PropertyFinder rate-limits pages 2+ from non-US IPs — actor auto-falls-back to Apify US residential proxy on 403.

---

### How to use

1. Pick one or more platforms in the input form
2. (Optional) filter by city, category, price range, REGA-verified-only, or Vision 2030 zone
3. Run. First 10 chargeable events per run are free — try it before committing.

---

### Input examples

#### Example 1 — Riyadh apartments on Bayut.sa
```json
{
  "platforms": ["bayut_sa"],
  "cities": ["Riyadh"],
  "categories": ["apartment"],
  "listingType": "sale",
  "maxListingsPerPlatform": 50
}
````

#### Example 2 — All 4 platforms, broad sweep

```json
{
  "platforms": ["bayut_sa", "wasalt", "aqar", "pf_sa"],
  "listingType": "sale",
  "maxListingsPerPlatform": 100
}
```

#### Example 3 — REGA-verified only (excludes Aqar.fm since Aqar doesn't expose license)

```json
{
  "platforms": ["bayut_sa", "wasalt", "pf_sa"],
  "cities": ["Riyadh", "Jeddah"],
  "listingType": "sale",
  "regaVerifiedOnly": true,
  "maxListingsPerPlatform": 200,
  "fetchBayutRegaDetails": true
}
```

#### Example 4 — Vision 2030 mega-project zones only

```json
{
  "platforms": ["bayut_sa", "wasalt", "aqar"],
  "listingType": "sale",
  "vision2030ZonesOnly": true,
  "priceMinSar": 2000000,
  "maxListingsPerPlatform": 100
}
```

#### Example 5 — Aqar.fm with installment plans (3-bed villas in Jeddah)

```json
{
  "platforms": ["aqar"],
  "cities": ["Jeddah"],
  "categories": ["villa"],
  "listingType": "sale",
  "bedroomsMin": 3,
  "priceMinSar": 500000,
  "maxListingsPerPlatform": 200
}
```

#### Example 6 — PropertyFinder.sa with US proxy enabled (deeper pagination)

```json
{
  "platforms": ["pf_sa"],
  "cities": ["Riyadh"],
  "categories": ["apartment", "villa"],
  "listingType": "sale",
  "maxListingsPerPlatform": 500,
  "useProxy": true
}
```

***

### Output sample (Bayut.sa, REGA-verified)

```json
{
  "listing_id": "bayut_sa:87862279",
  "platform": "bayut_sa",
  "platform_listing_id": "87862279",
  "source_url": "https://www.bayut.sa/en/property/details-87862279/",
  "fetched_at": "2026-05-24T11:47:33Z",

  "rega_license_number": "7200764863",
  "rega_license_url": "https://eservicesredp.rega.gov.sa/public/OfficesBroker/ElanDetails/08de260f-cc78-49d0-86fa-5dbb34b9fd5c",
  "rega_license_expires_at": "2026-12-29T00:00:00Z",
  "is_rega_verified": true,

  "price_sar": 720000,
  "rega_declared_price_sar": null,
  "installment_plans": null,
  "is_auction": false,

  "listing_type": "sale",
  "rent_period": null,
  "property_type": "apartment",
  "property_type_raw": "Apartments",
  "completion_status": "completed",

  "area_sqm": 135,
  "plot_area_sqm": null,
  "bedrooms": 3,
  "bathrooms": 4,
  "living_rooms": null,
  "furnished": false,
  "amenities": ["Air Conditioning", "Built-in Cabinets", "Parking"],
  "age_of_listing_days": 12,

  "country": "SA",
  "city_en": "Jeddah",
  "city_ar": "جدة",
  "district_en": "Al Nuzhah",
  "district_ar": "النزهة",
  "region_en": "Makkah Region",
  "region_ar": "منطقة مكة المكرمة",
  "location_path": ["KSA", "Jeddah", "Al Nuzhah"],
  "coordinates": { "lat": 21.623646, "lng": 39.159675 },
  "street_name": "فؤاد شاكر",
  "street_direction": null,
  "street_width_m": null,
  "zip_code": null,

  "vision_2030_zone": null,

  "agent_name_en": "Adel Ayed",
  "agent_name_ar": null,
  "agent_phone": "+966115009156",
  "agent_email": null,
  "agent_whatsapp": "966114049994",
  "brokerage_name": "Adel Ayed Real Estate",
  "brokerage_logo_url": null,
  "agent_capacity": "company_broker",

  "cover_photo_url": "https://images.bayut.sa/.../cover.jpg",
  "photo_urls": ["https://images.bayut.sa/.../cover.jpg"],
  "photo_count": 26,
  "video_count": 0,
  "panorama_count": 0,

  "title_en": "Spacious housing annex for sale in Al-Nazha district",
  "title_ar": "ملحق سكني واسع للبيع في حي النزهة",
  "description_en": null,
  "description_ar": null,

  "posted_at": "2026-05-12T08:14:11Z",
  "updated_at": "2026-05-12T08:14:11Z",
  "refreshed_at": "2026-01-05T16:47:34Z",

  "is_verified": true,
  "is_premium": true,
  "is_featured": false,
  "platform_score": 375,

  "scraping_strategy": "window_state_algolia"
}
```

### Output sample (Aqar.fm, with installment plans + Saudi-unique fields)

```json
{
  "listing_id": "aqar:6628451",
  "platform": "aqar",
  "platform_listing_id": "6628451",
  "source_url": "https://sa.aqar.fm/villa-for-sale/jeddah/north-of-jeddah/al-murjan/villa-for-sale-6632320",
  "fetched_at": "2026-05-24T11:47:33Z",

  "rega_license_number": null,
  "rega_license_url": null,
  "rega_license_expires_at": null,
  "is_rega_verified": null,

  "price_sar": 2450000,
  "rega_declared_price_sar": 3000000,
  "installment_plans": {
    "months_2": 1250000,
    "months_4": 612500,
    "months_12": 204167,
    "monthly_rnpl": 12500
  },
  "is_auction": false,

  "listing_type": "sale",
  "property_type": "villa",
  "area_sqm": 297,
  "bedrooms": null,
  "living_rooms": null,
  "street_direction": "E",
  "street_width_m": 12,

  "city_en": "Jeddah",
  "district_en": "Al Murjan",
  "coordinates": { "lat": 21.6752, "lng": 39.1064 },

  "vision_2030_zone": null,

  "scraping_strategy": "rsc_chunks"
}
```

***

### Pay-per-event pricing

| Event | Price | Description |
|---|---|---|
| `apify-actor-start` | $0.01 | Per run start. Apify default. |
| `listing-fetched` | **$0.004** (= $4/1,000) | One normalized listing emitted to dataset. **Primary event.** |
| `proxy-fetch` | $0.001 (= $1/1,000) | Fires only when PropertyFinder.sa US-proxy fallback engages. Other platforms don't trigger this. |

**Free trial: first 10 chargeable events per run.**

#### Cost scenarios

| Scenario | Listings × platforms | Total cost |
|---|---|---|
| Solo broker scanning Aqar Riyadh apartments | 500 listings | **$2.01** |
| Mid-tier weekly Bayut+Aqar sweep | 5,000 listings | **$20.01** |
| REIT monthly full Saudi sweep (4 platforms) | 100,000 listings | **$400** |
| Vision 2030 entity quarterly intel (filtered) | 50,000 listings | **$200** |

vs Property Monitor ($135/mo UAE-only) + REIDIN ($1.5K–$5K/mo enterprise) + JLL bespoke reports ($5K–$50K). This actor is API-grade infrastructure at SMB pricing.

***

### Data fields (canonical NormalizedListing schema)

| Field | Type | Notes |
|---|---|---|
| `listing_id` | string | `${platform}:${platform_id}` |
| `platform` | enum | `bayut_sa` / `wasalt` / `aqar` / `pf_sa` |
| `platform_listing_id` | string | Native ID |
| `source_url` | string | Direct listing URL |
| `fetched_at` | ISO 8601 | When scraped |
| **`rega_license_number`** | string | null | **Cross-platform JOIN KEY.** Present on Bayut/Wasalt/PF, null on Aqar |
| `rega_license_url` | string | null | Direct link to rega.gov.sa registry (Bayut only) |
| `rega_license_expires_at` | ISO 8601 | null | License expiry (Bayut only) |
| `is_rega_verified` | bool | null | Platform's verified flag |
| **`price_sar`** | number | Canonical Saudi Riyal price |
| `rega_declared_price_sar` | number | null | REGA reference price (Aqar.fm exclusive) |
| `installment_plans` | object | null | `{months_2, months_4, months_12, monthly_rnpl}` (Aqar.fm exclusive) |
| `is_auction` | bool | |
| `listing_type` | enum | `sale` / `rent` / `off_plan` / `auction` |
| `rent_period` | enum | null | `daily` / `monthly` / `yearly` |
| `property_type` | enum | `apartment` / `villa` / `land` / `building` / `commercial` / `townhouse` / `penthouse` / `office` / `shop` / `hotel-apartment` / `other` |
| `area_sqm` | number | null | Built-up area in sqm |
| `plot_area_sqm` | number | null | Land area (Bayut detail-page) |
| `bedrooms` / `bathrooms` / `living_rooms` | number | null | Coerced to numbers (PF gives strings) |
| `furnished` | bool | null | |
| `amenities` | string\[] | Expanded from PF short codes ("WT" → "Water") |
| `age_of_listing_days` | number | null | Parsed from Wasalt Arabic relative time strings |
| `city_en` / `city_ar` | string | null | |
| `district_en` / `district_ar` | string | null | Normalized via top-50 KSA district dictionary |
| `region_en` / `region_ar` | string | null | |
| `location_path` | string\[] | Variable depth 2-5 levels |
| `coordinates` | `{lat, lng}` | null | |
| `street_direction` | enum | null | `N` / `NE` / `E` / `SE` / `S` / `SW` / `W` / `NW` (Aqar.fm exclusive) |
| `street_width_m` | number | null | Aqar.fm exclusive |
| **`vision_2030_zone`** | enum | null | `NEOM` / `Red Sea` / `Diriyah` / `ROSHN` / `Qiddiya` / `King Salman Park` |
| `agent_name_en` / `agent_name_ar` / `agent_phone` / `agent_email` / `agent_whatsapp` | strings | null | |
| `brokerage_name` / `brokerage_logo_url` | strings | null | |
| `agent_capacity` | enum | null | `individual` / `company_broker` / `developer` |
| `cover_photo_url` / `photo_urls[]` / `photo_count` / `video_count` / `panorama_count` | media | |
| `title_en` / `title_ar` / `description_en` / `description_ar` | strings | null | |
| `posted_at` / `updated_at` / `refreshed_at` | ISO 8601 | null | |
| `is_verified` / `is_premium` / `is_featured` | booleans | |
| `platform_score` | number | null | PF qs, Bayut indyScore, Wasalt totalScore |
| `scraping_strategy` | enum | `next_data` / `rsc_chunks` / `window_state_algolia` / `dom` / `graphql` |

***

### Tips

- **Pair with [Egyptian Real Estate Scraper](https://apify.com/constructive_calm/egypt-real-estate-scraper)** for MENA-wide coverage. Same NormalizedListing-equivalent shape.
- **Pair with [Gulf Used Cars](https://apify.com/constructive_calm/gulf-used-car-scraper)** if your buyer audience overlaps (Saudi consumers + brokers).
- **`fetchBayutRegaDetails: true`** triggers an extra detail-page fetch per Bayut listing to extract `permitNumber` + `permitUrl` + full amenities. Doubles Bayut fetch count.
- **`regaVerifiedOnly: true`** drops Aqar.fm listings (no REGA license exposed). Use when downstream KYB/compliance requires REGA verification.
- **Vision 2030 tagging is conservative** — only tags when description matches OR coordinates fall inside tight project bounds. Broader zones (NEOM, Red Sea) require text match; narrower zones (Diriyah, King Salman Park) accept coordinate-only.

***

### FAQ

**Q: Why no Sakan.co / OpenSooq KSA / Haraj?**
A: All three returned YELLOW on the platform spike — Sakan is DOM-only (no JSON state), OpenSooq's KSA finder returns 404 from non-KSA IPs, Haraj's GraphQL endpoint has introspection blocked and would require operation reverse-engineering. Deferred to v1.1+.

**Q: Why no Bayut UAE / PropertyFinder UAE / other GCC platforms?**
A: This actor is Saudi-positioned. For UAE/Qatar/Bahrain/Kuwait coverage, watch for a separate Gulf actor on its own roadmap.

**Q: REGA license verification — is the license actually valid?**
A: We extract and surface the license number + `permitUrl` (Bayut). We do NOT call rega.gov.sa to verify validity in v1 (REGA portal is geo-locked from non-KSA IPs). Manual verification via the surfaced `permitUrl` is straightforward. Programmatic REGA cross-reference is a v1.1 add.

**Q: Why does Aqar.fm have so few listings in my run?**
A: Aqar.fm's `?page=N` pagination doesn't behave like a flat list — pagination requires Server Actions / RSC streaming we don't yet replicate. v1 collects from `/en/all` and city-specific category paths. Full inventory walk is a v1.1 enhancement.

**Q: What does `agent_phone: null` mean?**
A: For platforms that gate phone behind a "click to reveal" UI (Aqar.fm, Wasalt), v1 surfaces null. Bayut.sa and PF.sa expose phone directly in the search-result payload.

***

### Legal disclaimer

This actor extracts publicly available real estate listings from Saudi real estate platforms. Use of the data is governed by each platform's terms of service. The actor does not verify the legitimacy of REGA licenses or the accuracy of listing details. Users are responsible for compliance with applicable Saudi regulations, including REGA, Ejar, and Sakani requirements where relevant. No warranty is provided on data quality or freshness.

**Data attribution:** Listings sourced from sa.aqar.fm, bayut.sa, wasalt.sa, propertyfinder.sa. Each source retains copyright in its original listing content; we provide a structured derivative for research and intelligence purposes.

# Actor input Schema

## `platforms` (type: `array`):

Pick one or more Saudi real estate platforms. Bayut.sa (72,468 listings) + Wasalt.sa (PIF-owned, 24,308 REGA-verified) + Aqar.fm (1.5M total, KSA #1) + PropertyFinder.sa.

## `cities` (type: `array`):

Filter by Saudi cities (optional). Common: Riyadh, Jeddah, Makkah, Madinah, Dammam, Khobar, Abha, Tabuk, Hail, Buraidah. Arabic names also accepted (الرياض, جدة, الدمام).

## `categories` (type: `array`):

Filter by property category. Accepted: apartment, villa, land, building, commercial, townhouse, penthouse, hotel-apartment, office, shop. Leave empty for all.

## `listingType` (type: `string`):

Sale, rent, off-plan, or auction. Default = sale.

## `maxListingsPerPlatform` (type: `integer`):

Cap how many listings to fetch from EACH selected platform. Total dataset rows = this × number of platforms selected. Range 1-5000.

## `priceMinSar` (type: `integer`):

Minimum price in Saudi Riyals (optional). Leave 0 for no lower bound.

## `priceMaxSar` (type: `integer`):

Maximum price in Saudi Riyals (optional). Leave 0 for no upper bound.

## `bedroomsMin` (type: `integer`):

Minimum bedroom count (optional). 0 = no filter.

## `bathroomsMin` (type: `integer`):

Minimum bathroom count (optional). 0 = no filter.

## `areaMinSqm` (type: `integer`):

Minimum area in square meters (optional). 0 = no filter.

## `regaVerifiedOnly` (type: `boolean`):

Filter to only listings with a verifiable REGA (Saudi Real Estate General Authority) license number. Excludes Aqar.fm listings since Aqar doesn't expose REGA license. Lower volume, higher trust.

## `vision2030ZonesOnly` (type: `boolean`):

Filter to listings tagged as NEOM, Red Sea, Diriyah Gate, ROSHN, Qiddiya, or King Salman Park. Auto-tagged via description regex + coordinate bounds.

## `fetchBayutRegaDetails` (type: `boolean`):

For Bayut.sa listings, do an extra detail-page fetch to extract permitNumber + permitUrl (cross-reference to rega.gov.sa). Adds ~1 extra request per Bayut listing.

## `useProxy` (type: `boolean`):

Route requests via Apify proxy. Required for PropertyFinder.sa pages 2+ (rate-limited from many IPs). Auto-engaged for PF.sa even when this is off. Other platforms work without proxy.

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

Apify proxy configuration (used when useProxy=true). Defaults to RESIDENTIAL with US country pin (BUYPROXIES94952 group, 27 IPs available).

## Actor input object example

```json
{
  "platforms": [
    "bayut_sa"
  ],
  "cities": [
    "Riyadh"
  ],
  "categories": [],
  "listingType": "sale",
  "maxListingsPerPlatform": 20,
  "priceMinSar": 0,
  "priceMaxSar": 0,
  "bedroomsMin": 0,
  "bathroomsMin": 0,
  "areaMinSqm": 0,
  "regaVerifiedOnly": false,
  "vision2030ZonesOnly": false,
  "fetchBayutRegaDetails": false,
  "useProxy": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "BUYPROXIES94952"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

## `listings` (type: `string`):

Saudi RE listings from selected platforms, normalized into a single schema. Includes REGA license number, installment plans, Vision 2030 zone tagging, Arabic + English titles + districts.

# 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 = {
    "platforms": [
        "bayut_sa"
    ],
    "cities": [
        "Riyadh"
    ],
    "maxListingsPerPlatform": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "BUYPROXIES94952"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("constructive_calm/saudi-real-estate-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 = {
    "platforms": ["bayut_sa"],
    "cities": ["Riyadh"],
    "maxListingsPerPlatform": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["BUYPROXIES94952"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("constructive_calm/saudi-real-estate-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "platforms": [
    "bayut_sa"
  ],
  "cities": [
    "Riyadh"
  ],
  "maxListingsPerPlatform": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "BUYPROXIES94952"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call constructive_calm/saudi-real-estate-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=constructive_calm/saudi-real-estate-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Saudi Real Estate — Bayut, Wasalt, Aqar.fm, PropertyFinder",
        "description": "Saudi-only real estate intelligence across 4 verified platforms: Bayut.sa (72K listings), Wasalt.sa PIF-owned (24K), Aqar.fm, PropertyFinder.sa. REGA license cross-reference, installment plans, Vision 2030 zone tagging, Arabic district normalization. $4/1K listings.",
        "version": "0.1",
        "x-build-id": "JCmFc82qwpKUji4jn"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/constructive_calm~saudi-real-estate-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-constructive_calm-saudi-real-estate-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/constructive_calm~saudi-real-estate-scraper/runs": {
            "post": {
                "operationId": "runs-sync-constructive_calm-saudi-real-estate-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/constructive_calm~saudi-real-estate-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-constructive_calm-saudi-real-estate-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "platforms"
                ],
                "properties": {
                    "platforms": {
                        "title": "Platforms",
                        "type": "array",
                        "description": "Pick one or more Saudi real estate platforms. Bayut.sa (72,468 listings) + Wasalt.sa (PIF-owned, 24,308 REGA-verified) + Aqar.fm (1.5M total, KSA #1) + PropertyFinder.sa.",
                        "items": {
                            "type": "string"
                        },
                        "default": [
                            "bayut_sa"
                        ]
                    },
                    "cities": {
                        "title": "Cities",
                        "type": "array",
                        "description": "Filter by Saudi cities (optional). Common: Riyadh, Jeddah, Makkah, Madinah, Dammam, Khobar, Abha, Tabuk, Hail, Buraidah. Arabic names also accepted (الرياض, جدة, الدمام).",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "categories": {
                        "title": "Property categories",
                        "type": "array",
                        "description": "Filter by property category. Accepted: apartment, villa, land, building, commercial, townhouse, penthouse, hotel-apartment, office, shop. Leave empty for all.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "listingType": {
                        "title": "Listing type",
                        "enum": [
                            "sale",
                            "rent",
                            "off_plan",
                            "auction",
                            "all"
                        ],
                        "type": "string",
                        "description": "Sale, rent, off-plan, or auction. Default = sale.",
                        "default": "sale"
                    },
                    "maxListingsPerPlatform": {
                        "title": "Max listings per platform",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Cap how many listings to fetch from EACH selected platform. Total dataset rows = this × number of platforms selected. Range 1-5000.",
                        "default": 200
                    },
                    "priceMinSar": {
                        "title": "Min price (SAR)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Minimum price in Saudi Riyals (optional). Leave 0 for no lower bound.",
                        "default": 0
                    },
                    "priceMaxSar": {
                        "title": "Max price (SAR)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Maximum price in Saudi Riyals (optional). Leave 0 for no upper bound.",
                        "default": 0
                    },
                    "bedroomsMin": {
                        "title": "Min bedrooms",
                        "minimum": 0,
                        "maximum": 20,
                        "type": "integer",
                        "description": "Minimum bedroom count (optional). 0 = no filter.",
                        "default": 0
                    },
                    "bathroomsMin": {
                        "title": "Min bathrooms",
                        "minimum": 0,
                        "maximum": 20,
                        "type": "integer",
                        "description": "Minimum bathroom count (optional). 0 = no filter.",
                        "default": 0
                    },
                    "areaMinSqm": {
                        "title": "Min area (sqm)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Minimum area in square meters (optional). 0 = no filter.",
                        "default": 0
                    },
                    "regaVerifiedOnly": {
                        "title": "REGA-verified listings only",
                        "type": "boolean",
                        "description": "Filter to only listings with a verifiable REGA (Saudi Real Estate General Authority) license number. Excludes Aqar.fm listings since Aqar doesn't expose REGA license. Lower volume, higher trust.",
                        "default": false
                    },
                    "vision2030ZonesOnly": {
                        "title": "Vision 2030 mega-project zones only",
                        "type": "boolean",
                        "description": "Filter to listings tagged as NEOM, Red Sea, Diriyah Gate, ROSHN, Qiddiya, or King Salman Park. Auto-tagged via description regex + coordinate bounds.",
                        "default": false
                    },
                    "fetchBayutRegaDetails": {
                        "title": "Fetch Bayut.sa detail-page REGA fields",
                        "type": "boolean",
                        "description": "For Bayut.sa listings, do an extra detail-page fetch to extract permitNumber + permitUrl (cross-reference to rega.gov.sa). Adds ~1 extra request per Bayut listing.",
                        "default": false
                    },
                    "useProxy": {
                        "title": "Use Apify proxy",
                        "type": "boolean",
                        "description": "Route requests via Apify proxy. Required for PropertyFinder.sa pages 2+ (rate-limited from many IPs). Auto-engaged for PF.sa even when this is off. Other platforms work without proxy.",
                        "default": false
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Apify proxy configuration (used when useProxy=true). Defaults to RESIDENTIAL with US country pin (BUYPROXIES94952 group, 27 IPs available).",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "BUYPROXIES94952"
                            ],
                            "apifyProxyCountry": "US"
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
