# OpenSooq Scraper | 20 Markets Sale & Rent (`lentic_clockss/opensooq-real-estate-scraper`) Actor

Scrape OpenSooq property listings across 20 MENA markets for sale or rent. Extract prices, beds, area, location & photos. OpenSooq API alternative.

- **URL**: https://apify.com/lentic\_clockss/opensooq-real-estate-scraper.md
- **Developed by:** [kane liu](https://apify.com/lentic_clockss) (community)
- **Categories:** Real estate, Lead generation, Automation
- **Stats:** 1 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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/docs.md):

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

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.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/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

**Scrape OpenSooq sale and rent property listings across 20 MENA & North Africa markets — then download structured real estate data as Excel, CSV, or JSON.**

This Actor is a practical **OpenSooq API alternative** for market research, investor screening, rental comps, and lead lists. Choose countries such as **Jordan**, **UAE**, **Egypt**, or **Saudi Arabia**, pick **Buy** or **Rent**, filter by **apartments**, **villas**, **land**, **offices**, and more — then get listing rows with prices, beds, baths, area, location, attributes, and photos when present on the detail page.

- Pull **homes for sale** and **apartments for rent** from [OpenSooq](https://www.opensooq.com/en) country sites (JO, AE, EG, SA, IQ, KW, LB, and 13 more)
- Enrich search results with **detail-page fields** (description, categories, geo, lister type, media)
- Filter by **property category** (apartments, villas, land, commercial, offices, …) — or paste known **search / detail URLs**
- Run **multi-market** or **all 20 markets** with fair-split `maxItems`
- Export to **Excel / CSV / JSON**, or connect Make, n8n, Zapier, Python, or MCP
- **Pay per event** — Actor start + each Dataset listing; no subscription

---

### What does the OpenSooq Scraper do?

It turns an OpenSooq property search into a clean Apify Dataset of listings across twenty country sites.

Under the hood, the Actor:

1. Builds the OpenSooq search URL for your market, channel, location, and property type
2. Fetches pages with **browser-like TLS** (`curl_cffi` Chrome impersonation) — bare HTTP clients get **403** from AWS ELB
3. Collects listing cards from SRP DOM (`a.postListItemData`) plus JSON-LD when present
4. Optionally opens detail pages and merges JSON-LD (`Residence` / `Apartment`) with attribute labels
5. Writes normalized records you can download or push into automations

Apify RESIDENTIAL proxy is recommended on cloud. National URLs (`/en/property/{slug}`) work without a city slug.

---

### What data can you extract from OpenSooq?

| Data point | Buy | Rent |
| --- | :---: | :---: |
| Title & listing URL | ✅ | ✅ |
| List price or rent + currency | ✅ | ✅ |
| Beds / baths / size (m²) | ✅ | ✅ |
| Property type & category | ✅ | ✅ |
| Market + currency | ✅ | ✅ |
| City / neighborhood / address | ✅ | ✅ |
| GPS coordinates (when shown) | ✅ | ✅ |
| Lister type / payment method | ✅ | ✅ |
| Furnished / floor / rental period | — | ✅ |
| Photo gallery | ✅ | ✅ |
| Description (detail page) | ✅ | ✅ |

Every Dataset row includes `scrapedAt` and `source` = `opensooq`. An `OUTPUT` / `RUN_SUMMARY` record in the key-value store reports counts, search URLs, and warnings.

---

### Why scrape OpenSooq property listings?

#### Market research and comps

Build sale and rent comps for Amman, Dubai, Cairo, Riyadh, Baghdad, and other OpenSooq markets without copy-pasting from the site.

#### Multi-country coverage

OpenSooq spans **20 country subdomains**. Use `market: "all"` or a `markets` list to fair-split collection across countries in one run.

#### Category-level inventory

Target apartments, villas, land, commercial units, offices, warehouses, hotels, and more — or expand every Buy/Rent leaf category with `expandAllCategories`.

#### Automations and AI agents

Schedule runs and send Datasets to Sheets, Slack, CRM, Make, n8n, Zapier, or an AI agent via Apify MCP / API.

---

### How to scrape OpenSooq (no code required)

1. Click **Try for free**
2. Choose a **market** (e.g. `JO`, `AE`, `EG`) or `all`
3. Choose a **channel** (Buy or Rent)
4. Optionally set **property type**, **location** city slug, max listings, and whether to open detail pages
5. Keep **Apify RESIDENTIAL** proxy enabled for cloud runs
6. Click **Start** — open the **Dataset** tab when the run finishes

Start with `maxItems: 5–10` and `scrapeDetails: false` to verify, then scale up.

<details>
<summary>For developers: minimal input</summary>

```json
{
  "market": "JO",
  "channel": "BUY",
  "propertyType": "apartment",
  "maxItems": 10,
  "maxPages": 1,
  "scrapeDetails": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
````

Multi-market × categories:

```json
{
  "markets": ["JO", "AE", "EG"],
  "channel": "BUY",
  "propertyTypes": ["apartment", "land"],
  "maxItems": 6,
  "scrapeDetails": true
}
```

All 20 markets (smoke):

```json
{
  "market": "all",
  "channel": "BUY",
  "propertyType": "all",
  "maxItems": 20,
  "scrapeDetails": false
}
```

</details>

***

### Markets covered

| Code | Site | Currency |
| --- | --- | --- |
| `AE` | [ae.opensooq.com](https://ae.opensooq.com/en) | AED |
| `BH` | [bh.opensooq.com](https://bh.opensooq.com/en) | BHD |
| `DZ` | [dz.opensooq.com](https://dz.opensooq.com/en) | DZD |
| `EG` | [eg.opensooq.com](https://eg.opensooq.com/en) | EGP |
| `IQ` | [iq.opensooq.com](https://iq.opensooq.com/en) | IQD |
| `JO` | [jo.opensooq.com](https://jo.opensooq.com/en) | JOD |
| `KW` | [kw.opensooq.com](https://kw.opensooq.com/en) | KWD |
| `LB` | [lb.opensooq.com](https://lb.opensooq.com/en) | LBP |
| `LY` | [ly.opensooq.com](https://ly.opensooq.com/en) | LYD |
| `MA` | [ma.opensooq.com](https://ma.opensooq.com/en) | MAD |
| `MR` | [mr.opensooq.com](https://mr.opensooq.com/en) | MRU |
| `OM` | [om.opensooq.com](https://om.opensooq.com/en) | OMR |
| `PS` | [ps.opensooq.com](https://ps.opensooq.com/en) | JOD |
| `QA` | [qa.opensooq.com](https://qa.opensooq.com/en) | QAR |
| `SA` | [sa.opensooq.com](https://sa.opensooq.com/en) | SAR |
| `SD` | [sd.opensooq.com](https://sd.opensooq.com/en) | SDG |
| `SY` | [sy.opensooq.com](https://sy.opensooq.com/en) | SYP |
| `TN` | [tn.opensooq.com](https://tn.opensooq.com/en) | TND |
| `TR` | [tr.opensooq.com](https://tr.opensooq.com/en) | TRY |
| `YE` | [ye.opensooq.com](https://ye.opensooq.com/en) | YER |

Default search is **national**: `/{locale}/property/{slug}`. Set `location` (e.g. `amman`, `dubai`) for city-scoped SRP URLs.

***

### Property categories

| Key | Buy slug | Rent slug |
| --- | --- | --- |
| `all` | property-for-sale | property-for-rent |
| `apartment` | apartments-for-sale | apartments-for-rent |
| `villa` | villas-palaces-for-sale | villas-palaces-for-rent |
| `land` | lands-for-sale | lands-for-rent |
| `commercial` / `office` / `shop` / … | matching `*-for-sale` | matching `*-for-rent` |
| `hotel-apartment` | — | hotel-apartments-and-suites |
| `shared-rooms` | — | shared-rooms-for-rent |

Use `expandAllCategories: true` with `propertyType: "all"` to fan out every leaf category supported for the channel. `maxItems` is fair-split across **markets × property types**.

***

### Pricing — how much does it cost to scrape OpenSooq?

**Pay per event. No subscription.**

| Event | Price | When charged |
| --- | ---: | --- |
| `apify-actor-start` (**Actor Start**) | **$0.005** | When a normal run starts (scaled by allocated memory GB; min 1 event) |
| `apify-default-dataset-item` (**result**) | **$2.50 / 1,000** ($0.0025 each) | Each listing written to the default Dataset |

**User pays platform usage costs: Yes** — compute, proxy, and other platform usage are billed to the user in addition to event charges.

#### Free Apify plan limits (set by this Actor's developer)

| Limit | Free Apify plan | Paid Apify plan |
| --- | --- | --- |
| Runs of this Actor | **10 runs total** | Unlimited |
| Results per run | **Up to 1,000** | Up to schema max (2,000) |

When the run cap is hit, the run finishes with a clear status message — not an Apify platform error. These limits are set by the Actor developer, not Apify.

**Example product charges (events only):**

| Scenario | Approx. event charge |
| --- | ---: |
| Canary: 10 listings | $0.005 + 10 × $0.0025 = **$0.030** |
| City scan: 100 listings | $0.005 + $0.25 = **$0.255** |
| 1,000 listings | $0.005 + $2.50 = **$2.505** |

Platform usage (proxy + memory × duration) is separate. Default memory is 1024 MB (≈ 1× Actor Start event).

***

### Input

| Field | Description |
| --- | --- |
| `market` / `markets` | One of 20 country codes, or `all` |
| `channel` | `BUY` (for sale) or `RENT` (for rent) |
| `propertyType` / `propertyTypes` | Category keys (`apartment`, `land`, …) or OpenSooq slugs |
| `expandAllCategories` | Expand `all` into every channel-supported leaf category |
| `location` | Optional city slug; empty → national `/property/` URL |
| `locale` | `en` / `ar` (default `en`) |
| `maxItems` / `maxPages` | Caps (1–2000 / 1–100); ≈30 listings per SRP page |
| `maxSearchUrls` | Cap on markets × property-types URL fan-out (default 60) |
| `scrapeDetails` | Enrich each card from the listing detail page |
| `failOnPartial` | Fail the run when SRP/LDP failure rate is high |
| `unlockerApiKey` | Optional ScraperAPI key (or `SCRAPERAPI_KEY` secret) for unlocker fallback |
| `startUrls` | Optional SRP or LDP URLs (overrides market/channel/type) |
| `proxyConfiguration` | Apify RESIDENTIAL when the worker does not supply its own proxy |
| `workerBaseUrl` | Advanced: per-run worker origin override (default: Actor env `WORKER_BASE_URL`) |

Open the **Input** tab in Console for the full form and tooltips.

Worker host migrations: update Actor env `WORKER_BASE_URL` (and `WORKER_AUTH` if the API key changed) — no Actor code change required.

***

### Output example

You can download the Dataset as **JSON, CSV, Excel, or HTML**.

```json
{
  "id": "284124770",
  "listingId": "284124770",
  "url": "https://jo.opensooq.com/en/search/284124770",
  "source": "opensooq",
  "sourceLayer": "srp+ldp",
  "market": "JO",
  "channel": "BUY",
  "category": "land",
  "title": "Residential land for sale in Amman",
  "price": "109,000 JOD",
  "priceAmount": 109000,
  "currency": "JOD",
  "propertyType": "Lands for Sale",
  "size": 975,
  "sizeUnit": "m2",
  "city": "Amman",
  "neighborhood": "Airport Road - Manaseer Gs",
  "latitude": 31.844116,
  "longitude": 35.855858,
  "scrapedAt": "2026-07-19T12:00:00+00:00"
}
```

***

### Is it legal to scrape OpenSooq?

Our scrapers are ethical and do not extract private user data such as emails unlocked behind CTAs, full phone numbers from “show phone” flows, or chat messages. They only extract what is publicly shown on listing pages (including masked phone snippets when visible on cards). Personal data may still appear in public listing text; personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason. If you are unsure, consult your lawyers. Always respect OpenSooq’s Terms of Use and robots rules for automated access.

This Actor does **not** click Call, Chat, or other lead CTAs to reveal hidden contact details.

***

### FAQ

#### Can I scrape OpenSooq Jordan apartments for sale?

Yes. Set `market` to `JO`, `channel` to `BUY`, and `propertyType` to `apartment`. Leave `location` empty for national results, or set `amman` for Amman-only.

#### Can I scrape OpenSooq UAE, Egypt, or Saudi Arabia?

Yes. Use `market: "AE"`, `"EG"`, or `"SA"`. You can also pass `markets: ["AE", "EG", "SA"]` or `market: "all"` for all twenty countries.

#### Does this work as an OpenSooq API?

There is no official public OpenSooq listings API for this use case. This Actor is a practical **OpenSooq API alternative** that returns structured Dataset rows you can call via the Apify API, schedules, or integrations.

#### Why not plain requests or curl?

OpenSooq’s edge returns **403 Forbidden** (`awselb/2.0`) for bare Python-requests / curl clients. This Actor uses Chrome TLS impersonation so browser-like requests receive SSR HTML and RSC detail pages.

#### What about Live View / Standby?

Standby mode exposes operational endpoints (`/`, `/health`, `/input-example`, `/openapi.json`) documented in the **Standby** tab OpenAPI schema. Run sale/rent collection through a normal Actor run — Standby is for readiness and input guidance, not full scrape traffic.

#### What if curl\_cffi is blocked?

Enable Apify RESIDENTIAL proxy first (or rely on the worker’s own `PROXY_URL`). Optionally set Actor secret `SCRAPERAPI_KEY` (or input `unlockerApiKey`) so blocked HTML pages can retry via ScraperAPI unlocker. Full browser (CloakBrowser) is not in the default image yet.

#### Why did my free-plan run stop after 10 runs?

This Actor allows **10 runs** and **up to 1,000 listings per run** for free Apify plan users. That policy is set by the Actor developer (not Apify). Upgrade to a paid Apify plan for unlimited runs. The run ends with status message `FREE_TIER_LIMIT` — it is not a platform crash.

#### Where can I get help?

Open an Issue on the Actor page in Apify Console with the Run ID, input JSON, and a short description of the failure. Include whether 403, empty SRP, or missing detail fields appeared in the log.

***

### Tips for better OpenSooq scraping

- Start small (`maxItems: 5`, `scrapeDetails: false`) to validate a market before large runs
- Prefer national URLs (empty `location`) for multi-market coverage
- Use specific `propertyType` values when you need a category; `all` uses the root property-for-sale/rent slug
- Enable `expandAllCategories` only when you intentionally want one fair-split quota per leaf category
- Raise concurrency carefully — OpenSooq may throttle aggressive detail fetching

# Actor input Schema

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

OpenSooq search (SRP) or listing detail (LDP) URLs. Search URLs override market/channel/location/type when provided. Supports national (/en/property/...) and city (/en/{city}/property/...) paths.

## `market` (type: `string`):

Primary country market (all 20 OpenSooq countries). Use all for every market. Ignored when markets is set.

## `markets` (type: `array`):

Optional multi-select of markets. Overrides market when non-empty. maxItems is fair-split across markets × property types.

## `channel` (type: `string`):

Sale or rent property channel.

## `propertyType` (type: `string`):

Single property category. Use all for root property-for-sale/rent. Rent-only: hotel-apartment, shared-rooms.

## `propertyTypes` (type: `array`):

Optional multi-select categories. Overrides propertyType when non-empty. Fair-split with markets.

## `expandAllCategories` (type: `boolean`):

When propertyType is all (and propertyTypes empty), expand into every category supported for the channel instead of using the root property-for-sale/rent URL.

## `location` (type: `string`):

Optional city URL slug (e.g. amman, dubai). Leave empty for national /en/property/... search (recommended for multi-market).

## `locale` (type: `string`):

URL locale prefix. Leave empty for market default (en).

## `maxItems` (type: `integer`):

Maximum property records to save (1–2,000; fair-split across markets × property types). Free Apify plan users: capped at 1,000 per run and limited to 10 total runs of this Actor (Actor developer policy).

## `maxPages` (type: `integer`):

Maximum SRP pages per search URL (~30 listings per page). Uses ?page=N.

## `maxSearchUrls` (type: `integer`):

Hard cap on markets × property-types search URL fan-out (prevents runaway runs).

## `scrapeDetails` (type: `boolean`):

Fetch each listing LDP and merge JSON-LD + attribute fields.

## `failOnPartial` (type: `boolean`):

When true, abort the run if SRP/LDP failure rate is high instead of returning SUCCEEDED\_PARTIAL.

## `requestDelayMillis` (type: `integer`):

Politeness delay between HTTP requests (adaptive throttle may raise this after blocks).

## `maxConcurrency` (type: `integer`):

Max concurrent HTTP fetches for detail pages.

## `unlockerApiKey` (type: `string`):

Optional ScraperAPI key for HTML unlocker fallback when curl\_cffi is blocked. Prefer SCRAPERAPI\_KEY secret on Actor.

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

Apify Proxy recommended on cloud when the worker does not supply PROXY\_URL. Country defaults per market when supported. Ignored when Actor env WORKER\_PROVIDES\_PROXY=1.

## `workerBaseUrl` (type: `string`):

Override worker origin for this run. Default: Actor env WORKER\_BASE\_URL. Production migrations should update WORKER\_BASE\_URL in Actor settings (no code change).

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://jo.opensooq.com/en/property/property-for-sale"
    }
  ],
  "market": "JO",
  "markets": [],
  "channel": "BUY",
  "propertyType": "all",
  "propertyTypes": [],
  "expandAllCategories": false,
  "location": "",
  "locale": "",
  "maxItems": 25,
  "maxPages": 1,
  "maxSearchUrls": 60,
  "scrapeDetails": true,
  "failOnPartial": false,
  "requestDelayMillis": 800,
  "maxConcurrency": 2,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

Normalized OpenSooq listing records from SRP and optional LDP enrichment.

## `runSummary` (type: `string`):

Counts, engine, and timestamps for the 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 = {
    "startUrls": [
        {
            "url": "https://jo.opensooq.com/en/property/property-for-sale"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lentic_clockss/opensooq-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 = { "startUrls": [{ "url": "https://jo.opensooq.com/en/property/property-for-sale" }] }

# Run the Actor and wait for it to finish
run = client.actor("lentic_clockss/opensooq-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 '{
  "startUrls": [
    {
      "url": "https://jo.opensooq.com/en/property/property-for-sale"
    }
  ]
}' |
apify call lentic_clockss/opensooq-real-estate-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "OpenSooq Scraper | 20 Markets Sale & Rent",
        "description": "Scrape OpenSooq property listings across 20 MENA markets for sale or rent. Extract prices, beds, area, location & photos. OpenSooq API alternative.",
        "version": "0.6",
        "x-build-id": "sPKYMdZnQLfh6fNXb"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/lentic_clockss~opensooq-real-estate-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-lentic_clockss-opensooq-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/lentic_clockss~opensooq-real-estate-scraper/runs": {
            "post": {
                "operationId": "runs-sync-lentic_clockss-opensooq-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/lentic_clockss~opensooq-real-estate-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-lentic_clockss-opensooq-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",
                "properties": {
                    "startUrls": {
                        "title": "Start URLs",
                        "type": "array",
                        "description": "OpenSooq search (SRP) or listing detail (LDP) URLs. Search URLs override market/channel/location/type when provided. Supports national (/en/property/...) and city (/en/{city}/property/...) paths.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "market": {
                        "title": "Market",
                        "enum": [
                            "AE",
                            "BH",
                            "DZ",
                            "EG",
                            "IQ",
                            "JO",
                            "KW",
                            "LB",
                            "LY",
                            "MA",
                            "MR",
                            "OM",
                            "PS",
                            "QA",
                            "SA",
                            "SD",
                            "SY",
                            "TN",
                            "TR",
                            "YE",
                            "all"
                        ],
                        "type": "string",
                        "description": "Primary country market (all 20 OpenSooq countries). Use all for every market. Ignored when markets is set.",
                        "default": "JO"
                    },
                    "markets": {
                        "title": "Markets",
                        "type": "array",
                        "description": "Optional multi-select of markets. Overrides market when non-empty. maxItems is fair-split across markets × property types.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "AE",
                                "BH",
                                "DZ",
                                "EG",
                                "IQ",
                                "JO",
                                "KW",
                                "LB",
                                "LY",
                                "MA",
                                "MR",
                                "OM",
                                "PS",
                                "QA",
                                "SA",
                                "SD",
                                "SY",
                                "TN",
                                "TR",
                                "YE"
                            ]
                        },
                        "default": []
                    },
                    "channel": {
                        "title": "Channel",
                        "enum": [
                            "BUY",
                            "RENT"
                        ],
                        "type": "string",
                        "description": "Sale or rent property channel.",
                        "default": "BUY"
                    },
                    "propertyType": {
                        "title": "Property type",
                        "enum": [
                            "all",
                            "residential",
                            "apartment",
                            "villa",
                            "townhouse",
                            "whole-building",
                            "farm-chalet",
                            "foreign-property",
                            "hotel-apartment",
                            "shared-rooms",
                            "commercial",
                            "office",
                            "shop",
                            "complex",
                            "showroom",
                            "restaurant-cafe",
                            "warehouse",
                            "supermarket",
                            "clinic",
                            "commercial-villa",
                            "full-floor",
                            "hotel",
                            "factory",
                            "staff-housing",
                            "land"
                        ],
                        "type": "string",
                        "description": "Single property category. Use all for root property-for-sale/rent. Rent-only: hotel-apartment, shared-rooms.",
                        "default": "all"
                    },
                    "propertyTypes": {
                        "title": "Property types",
                        "type": "array",
                        "description": "Optional multi-select categories. Overrides propertyType when non-empty. Fair-split with markets.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "all",
                                "residential",
                                "apartment",
                                "villa",
                                "townhouse",
                                "whole-building",
                                "farm-chalet",
                                "foreign-property",
                                "hotel-apartment",
                                "shared-rooms",
                                "commercial",
                                "office",
                                "shop",
                                "complex",
                                "showroom",
                                "restaurant-cafe",
                                "warehouse",
                                "supermarket",
                                "clinic",
                                "commercial-villa",
                                "full-floor",
                                "hotel",
                                "factory",
                                "staff-housing",
                                "land"
                            ]
                        },
                        "default": []
                    },
                    "expandAllCategories": {
                        "title": "Expand all categories",
                        "type": "boolean",
                        "description": "When propertyType is all (and propertyTypes empty), expand into every category supported for the channel instead of using the root property-for-sale/rent URL.",
                        "default": false
                    },
                    "location": {
                        "title": "Location slug",
                        "type": "string",
                        "description": "Optional city URL slug (e.g. amman, dubai). Leave empty for national /en/property/... search (recommended for multi-market).",
                        "default": ""
                    },
                    "locale": {
                        "title": "Locale",
                        "enum": [
                            "",
                            "en",
                            "ar"
                        ],
                        "type": "string",
                        "description": "URL locale prefix. Leave empty for market default (en).",
                        "default": ""
                    },
                    "maxItems": {
                        "title": "Max listings (max 2,000; free users capped at 1,000/run)",
                        "minimum": 1,
                        "maximum": 2000,
                        "type": "integer",
                        "description": "Maximum property records to save (1–2,000; fair-split across markets × property types). Free Apify plan users: capped at 1,000 per run and limited to 10 total runs of this Actor (Actor developer policy).",
                        "default": 25
                    },
                    "maxPages": {
                        "title": "Max search pages",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Maximum SRP pages per search URL (~30 listings per page). Uses ?page=N.",
                        "default": 1
                    },
                    "maxSearchUrls": {
                        "title": "Max search URLs",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Hard cap on markets × property-types search URL fan-out (prevents runaway runs).",
                        "default": 60
                    },
                    "scrapeDetails": {
                        "title": "Scrape detail pages",
                        "type": "boolean",
                        "description": "Fetch each listing LDP and merge JSON-LD + attribute fields.",
                        "default": true
                    },
                    "failOnPartial": {
                        "title": "Fail on partial collection",
                        "type": "boolean",
                        "description": "When true, abort the run if SRP/LDP failure rate is high instead of returning SUCCEEDED_PARTIAL.",
                        "default": false
                    },
                    "requestDelayMillis": {
                        "title": "Delay between requests (ms)",
                        "minimum": 0,
                        "maximum": 15000,
                        "type": "integer",
                        "description": "Politeness delay between HTTP requests (adaptive throttle may raise this after blocks).",
                        "default": 800
                    },
                    "maxConcurrency": {
                        "title": "Request concurrency",
                        "minimum": 1,
                        "maximum": 8,
                        "type": "integer",
                        "description": "Max concurrent HTTP fetches for detail pages.",
                        "default": 2
                    },
                    "unlockerApiKey": {
                        "title": "Unlocker API key (optional)",
                        "type": "string",
                        "description": "Optional ScraperAPI key for HTML unlocker fallback when curl_cffi is blocked. Prefer SCRAPERAPI_KEY secret on Actor."
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Apify Proxy recommended on cloud when the worker does not supply PROXY_URL. Country defaults per market when supported. Ignored when Actor env WORKER_PROVIDES_PROXY=1.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ]
                        }
                    },
                    "workerBaseUrl": {
                        "title": "Worker base URL (optional)",
                        "type": "string",
                        "description": "Override worker origin for this run. Default: Actor env WORKER_BASE_URL. Production migrations should update WORKER_BASE_URL in Actor settings (no code change)."
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
