{
  "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": "X75JJe1eDANbnOacb"
  },
  "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: wasalt (Wasalt.sa, PIF-owned, REGA-verified), pf_sa (PropertyFinder.sa), aqar (Aqar.fm), bayut_sa (Bayut.sa). Bayut.sa is read through its search API (rebuilt October 2026). Common spellings are accepted (e.g. bayut, propertyfinder, pf, aqar_fm); unknown values are ignored with a warning.",
            "items": {
              "type": "string"
            },
            "default": [
              "wasalt",
              "pf_sa"
            ]
          },
          "cities": {
            "title": "Cities",
            "type": "array",
            "description": "Saudi cities to include (optional; empty = whole Kingdom). English or Arabic, any common spelling: Riyadh / الرياض, Jeddah / جدة, Makkah / Mecca / مكة, Madinah / Medina / المدينة, Dammam / الدمام, Khobar / الخبر, Taif / Taef, Hail / Hael, Khamis Mushait, Buraidah / Burayda, Unaizah, Al Ahsa / Hofuf, Jubail, Diriyah, Al Qunfudhah and 96 Saudi cities in total. Each platform filters by city on its own servers; a city a platform does not list is skipped on that platform (never widened to the whole Kingdom). Every row is re-checked before output: a row whose city is not one of yours (or is unknown) is dropped and not charged.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "districts": {
            "title": "Districts (neighbourhoods)",
            "type": "array",
            "description": "Optional. District names in English or Arabic, e.g. Al Narjis / النرجس, Al Olaya / العليا, Ash Shulah / الشعلة. Best combined with Cities. Wasalt.sa and PropertyFinder.sa resolve them to their own district ids and filter server-side; every row is then re-checked against district_en / district_ar and dropped (not charged) if it does not match. Without Cities, Wasalt looks the names up in Riyadh, Jeddah, Makkah, Madinah, Dammam and Khobar.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "categories": {
            "title": "Property categories",
            "type": "array",
            "description": "Property categories to include (optional; empty = all residential). Accepted values: apartment, villa, land, building, commercial, townhouse, office, shop, hotel-apartment, penthouse (plurals like \"apartments\" also work). Aqar.fm-only kinds: warehouse, farm, studio, floor, rest-house, chalet, room, hotel, tower, complex (other platforms fetch nothing for these). Each value is matched server-side where the platform supports it and enforced on the output. Notes: apartment includes whole-floor units (Full Floor / دور); commercial = offices, shops/showrooms, warehouses and other commercial units; farms, agricultural plots and rest houses are classed as 'other', not land. If none of your values is recognised the run fails instead of returning every category.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "listingType": {
            "title": "Listing type",
            "enum": [
              "sale",
              "rent",
              "off_plan",
              "auction",
              "all"
            ],
            "type": "string",
            "description": "Sale, rent, off-plan, auction, or all (= sale + rent). Default = sale. Off-plan: Bayut.sa listings under construction (sale) and Aqar.fm where available; Wasalt.sa and PropertyFinder.sa have no off-plan search filter and fetch nothing. Auction: no Saudi platform covered here currently exposes auctions; it returns 0 rows at no cost. With \"all\", sale and rent are collected side by side, so a run stopped early still has both.",
            "default": "sale"
          },
          "maxListingsPerPlatform": {
            "title": "Max listings per platform",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "Cap on emitted rows from EACH selected platform (after all filters). Split evenly across your cities x categories (x sale/rent when Listing type = all). 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": "Keep only listings that carry a REGA (Saudi Real Estate General Authority) ad license number. Wasalt.sa, PropertyFinder.sa and Aqar.fm expose it in their results; listings without one are dropped (not charged). Bayut.sa rows qualify only when fetchBayutRegaDetails is on AND Bayut allows permit lookups from the run's IP; otherwise Bayut is skipped with a note and nothing is fetched or billed for it. Lower volume, higher trust.",
            "default": false
          },
          "postedWithinDays": {
            "title": "Posted within the last N days",
            "minimum": 0,
            "maximum": 3650,
            "type": "integer",
            "description": "Keep only listings whose posted_at is within the last N days (0 = no time filter). Listings without a posting date are dropped while this is on. PropertyFinder.sa is then read newest-first so the run stops early. Use 30 / 90 / 365 for price-index time windows.",
            "default": 0
          },
          "includePriceOnRequest": {
            "title": "Include \"price on request\" listings",
            "type": "boolean",
            "description": "Off (default): listings without a usable price (price_sar 0 / hidden) are dropped and not charged, so averages and price_per_sqm_sar are not poisoned. Turn on to receive them anyway (price_sar = 0, price_per_sqm_sar = null).",
            "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 REGA permit + details",
            "type": "boolean",
            "description": "For Bayut.sa listings, fetch the REGA advertising permit (rega_license_number), permit URL (rega_license_url), full description and all photos. Adds 2 small API calls per emitted Bayut listing. Speed: roughly 40-60 Bayut rows per minute through the residential proxy (much faster from IPs Bayut does not block), so allow about 2 minutes per 100 Bayut listings on top of the normal run time; if the run timeout arrives first, the remaining rows are still delivered, without permits, and the SUMMARY reports the permit fill count. Bayut search results carry no permit number. Bayut.sa blocks these permit lookups from many server IPs (including Apify's own), so they are retried automatically through an Apify residential (Saudi) proxy; measured 100% permit fill on Apify cloud (about 2 proxy-fetch events per row). If every route is blocked, Bayut rows are delivered without permit, permit URL and description, the run's SUMMARY says so, and failed proxy attempts that never succeed are capped at the larger of 6 or 2% of the planned lookups, plus at most 9 already in flight (failed attempts that are retried successfully don't count toward that cap, but every proxy-routed request, including retries, is billed as proxy-fetch). If a lookup is challenged, it is retried through an Apify residential (Saudi) proxy and each such request is billed as a proxy-fetch event ($0.001).",
            "default": false
          },
          "useProxy": {
            "title": "Use Apify proxy",
            "type": "boolean",
            "description": "Route every platform's requests through the Apify proxy (configured below). Not needed normally: PropertyFinder.sa already falls back to the proxy automatically when a direct request is blocked. Every request routed through an Apify proxy is billed as one proxy-fetch event ($0.001): any platform's requests while this is on, PropertyFinder.sa's automatic US-proxy fallback, and Bayut.sa's detail-API fallback after a bot challenge (lookups and retries included).",
            "default": false
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Apify proxy used for proxy-routed requests (useProxy, PropertyFinder.sa's automatic fallback, Bayut.sa's challenge fallback). Default: datacenter group BUYPROXIES94952, US. Every request routed through an Apify proxy is billed as one proxy-fetch event ($0.001): any platform's requests while this is on, PropertyFinder.sa's automatic US-proxy fallback, and Bayut.sa's detail-API fallback after a bot challenge (lookups and retries included).",
            "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}