# Dubizzle UAE $1💰 Property, Motors & Agent Listings (`abotapi/dubizzle-com-scraper`) Actor

From $1/1K. Scrape dubizzle.com across the UAE for property, motors, and agent listings. Search by filters or URLs with auto pagination. Returns price, beds, baths, area, agent/agency contacts, WhatsApp, email, GPS, photos, amenities, verification, and Dubai Land Department history.

- **URL**: https://apify.com/abotapi/dubizzle-com-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Categories:** Real estate, Lead generation, Automation
- **Stats:** 6 total users, 4 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 listing results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Dubizzle.com Scraper - UAE Property, Cars and Agents

Extract listings from dubizzle.com across the UAE (Dubai, Abu Dhabi, Sharjah, Ras Al Khaimah, Ajman, Fujairah, Umm Al Quwain, Al Ain). Pull property for sale and rent, used cars (motors), and the property agents directory, with full agent contact details, GPS coordinates, photo galleries, amenities, verification status, and (for Dubai property) Dubai Land Department transaction history. Two ways to drive it: pick a city and filters, or paste any Dubizzle URL you already refined in a browser.

### Why this scraper

- Covers four sections from one actor: property for sale, property for rent, motors (used cars), and the agents directory.
- Search mode builds the URL for you (city, section, property type, price, bedrooms, area, furnishing, completion status, sort), so you do not need to craft links by hand.
- Sort control built in: popular, newest, oldest, price low to high, price high to low, verified first.
- Returns every field on each listing card, including the full nested agent, agency and contact objects, so nothing is dropped.
- Optional detail mode adds the full description, categorized amenities, agent email, permit numbers, the full photo gallery, and the Dubai Land Department transaction history for Dubai property.
- A single, predictable result cap for every run - Max listings, not an artificial page limit.
- **Resumable runs.** Set `resumeFromRunId` to a previous run or dataset id to collect only listings that run doesn't already have (a delta) - combine both datasets for the full set. Long unlimited runs also checkpoint their own progress, so an Apify platform migration or a Resurrect of a failed run picks up where it left off instead of starting over.
- **Incremental mode for recurring monitoring.** Schedule the actor against the same search and turn on `incrementalMode` to get only NEW / UPDATED / REAPPEARED listings back on every run - the actor remembers the previous run itself, no need to paste a run id.
- Lat/lng, agent phone and WhatsApp are already on the card, so a fast run without detail mode still gives you geocoded, contactable listings.

### Data you get

> Sample shape: values are illustrative placeholders, not from a live listing.

| Field | Example |
|---|---|
| id | 00000001 |
| url | https://dubai.dubizzle.com/property-for-sale/residential/apartment/2026/1/1/sample-0/ |
| title | Sample Listing Title |
| price | 1500000 |
| currency | AED |
| section | property-for-sale |
| categorySlug | apartment |
| bedrooms | 2 |
| bathrooms | 2 |
| area | 1200 |
| areaUnit | sqft |
| city | Dubai |
| neighborhood | Sample Community |
| latitude | 25.0000 |
| longitude | 55.0000 |
| isVerified | true |
| agentName | Agent Name |
| agencyName | Sample Agency |
| phoneNumber | +971500000000 |
| whatsapp | +971500000000 |
| addedOn | 1700000000 |
| propertyReference | REF-0001 |
| hasDldHistory | true |
| photosCount | 12 |
| raw | { complete source listing object } |
| changeType | NEW (Incremental mode only - see below) |
| changedFields | \["price"] (Incremental mode only) |
| firstSeenAt | 2026-01-01T00:00:00Z (Incremental mode only) |
| lastSeenAt | 2026-02-01T00:00:00Z (Incremental mode only) |
| description | Full description text appears here when detail mode is on. |
| amenities | \[ categorized amenities, detail mode only ] |
| email | agent@example.com |
| dldHistory | \[ Dubai Land Department transactions, detail mode only ] |

### How to use

Search mode, basic:

```json
{
  "mode": "search",
  "locations": ["dubai"],
  "section": "property-for-sale",
  "propertyType": "residential",
  "maxListings": 20
}
```

Search mode with filters and sort:

```json
{
  "mode": "search",
  "locations": ["dubai", "abu-dhabi"],
  "section": "property-for-rent",
  "propertyType": "apartment",
  "minPrice": 50000,
  "maxPrice": 150000,
  "minBedrooms": 1,
  "maxBedrooms": 2,
  "furnishing": "furnished",
  "sortBy": "newest",
  "maxListings": 50
}
```

Motors (used cars):

```json
{
  "mode": "search",
  "locations": ["dubai"],
  "section": "motors",
  "maxListings": 30
}
```

URL mode, multiple links:

```json
{
  "mode": "url",
  "urls": [
    "https://dubai.dubizzle.com/en/property-for-sale/residential/",
    "https://uae.dubizzle.com/en/property-agents/"
  ],
  "maxPages": 3,
  "maxListings": 100
}
```

Detail mode with Dubai Land Department history:

```json
{
  "mode": "search",
  "locations": ["dubai"],
  "section": "property-for-sale",
  "fetchDetails": true,
  "includeDldHistory": true,
  "maxListings": 10
}
```

Resume a previous run, collecting only listings it doesn't already have:

```json
{
  "mode": "search",
  "locations": ["dubai"],
  "section": "property-for-sale",
  "maxListings": 0,
  "resumeFromRunId": "<a previous run id or dataset id from this account>"
}
```

### Input parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| mode | string | search | "search" builds the URL from filters; "url" scrapes pasted URLs. |
| locations | array | \["dubai"] | City slugs (dubai, abu-dhabi, sharjah, ras-al-khaimah, ajman, fujairah, umm-al-quwain, al-ain). Search mode. |
| section | string | property-for-sale | property-for-sale, property-for-rent, motors, or property-agents. Search mode. |
| propertyType | string | residential | Property sub-type for the property sections. Search mode. |
| minPrice / maxPrice | integer | empty | Price bounds in AED. Search mode. |
| minBedrooms / maxBedrooms | integer | empty | Bedroom bounds. Property sections. |
| minArea / maxArea | integer | empty | Built-up area bounds in sqft. Property sections. |
| furnishing | string | any | any, furnished, unfurnished. Property sections. |
| completionStatus | string | any | any, completed, off-plan. Property sections. |
| sortBy | string | popular | popular, newest, oldest, price-asc, price-desc, verified. Search mode. |
| urls | array | example URL | Full Dubizzle URLs. URL mode. Filter fields are ignored here. |
| maxPages | integer | 0 | Optional bound on pages per search. 0 = walk as deep as the source serves (stops on its own at the storefront's reported total or a repeat page). Does not cap listings; use Max listings for that. |
| maxListings | integer | 20 | The single result cap. 0 = unlimited (bounded by Max pages / the storefront total). |
| fetchDetails | boolean | false | Include the full record for each listing. |
| includeDldHistory | boolean | true | In detail mode, also pull Dubai Land Department history for Dubai property. |
| resumeFromRunId | string | empty | ID of a previous run (or dataset) of this actor. Listings already in that dataset are skipped, so this run returns only new listings. The actor also checkpoints its own progress automatically, so a platform migration or a Resurrect of a failed/aborted run continues that same run without re-collecting or re-charging what it already pushed. |
| incrementalMode | boolean | false | For a scheduled/recurring run against the same search. The actor remembers the previous run itself and classifies every listing as NEW, UPDATED, REAPPEARED, or UNCHANGED. See "Incremental mode" below. |
| stateKey | string | empty | Names the monitoring campaign so it keeps its own baseline. Leave empty to auto-derive one from your search filters (caps like Max pages/Max listings never affect it). Incremental mode only. |
| emitUnchanged | boolean | false | Also emit UNCHANGED rows (still returns and bills every listing every run - leave off for the normal delta behavior). Incremental mode only. |
| emitExpired | boolean | false | Emit a one-time EXPIRED row for a tracked listing that has disappeared. Only fires after a run that reached the natural end of every search/URL with no cap hit and no Resume. Incremental mode only. |
| proxy | object | Residential AE | Proxy configuration. Residential, country AE recommended. |

### Output example

> Sample shape: values are illustrative placeholders, not from a live listing.

```json
{
  "id": "00000001",
  "url": "https://dubai.dubizzle.com/property-for-sale/residential/apartment/2026/1/1/sample-0/",
  "title": "Sample Listing Title",
  "price": 1500000,
  "currency": "AED",
  "section": "property-for-sale",
  "categorySlug": "apartment",
  "bedrooms": 2,
  "bathrooms": 2,
  "area": 1200,
  "areaUnit": "sqft",
  "city": "Dubai",
  "neighborhood": "Sample Community",
  "latitude": 25.0000,
  "longitude": 55.0000,
  "isVerified": true,
  "agentName": "Agent Name",
  "agencyName": "Sample Agency",
  "phoneNumber": "+971500000000",
  "whatsapp": "+971500000000",
  "addedOn": 1700000000,
  "propertyReference": "REF-0001",
  "hasDldHistory": true,
  "photosCount": 12,
  "raw": { "external_id": 1, "name": { "en": "Sample Listing Title" } }
}
```

### Incremental mode (recurring updates)

Schedule this actor against the same search on a recurring basis and turn on `incrementalMode` to get only what changed since the last run, instead of the full result set every time.

```json
{
  "mode": "search",
  "locations": ["dubai"],
  "section": "property-for-sale",
  "maxListings": 0,
  "incrementalMode": true
}
```

- The first incremental run classifies every listing as `NEW`. Every run after that compares against the state saved from the previous run and returns `NEW` / `UPDATED` / `REAPPEARED` listings; `UNCHANGED` listings are skipped (not pushed, not billed) unless `emitUnchanged` is on.
- **What defines "the same search"** (the state key): `mode`, `locations`, `section`, `propertyType`, `minPrice`, `maxPrice`, `minBedrooms`, `maxBedrooms`, `minArea`, `maxArea`, `furnishing`, `completionStatus`, `sortBy`, `urls`, `fetchDetails`, `includeDldHistory`. Raising or lowering `maxPages`, `maxListings`, or `maxNotifyListings` between runs never forks a new baseline or re-bills your whole search - only a real filter change does. Set `stateKey` to name the campaign explicitly instead of relying on the auto-derived key.
- `emitExpired` adds a one-time `EXPIRED` row for a tracked listing that no longer appears. It only fires after a run that reached the natural end of every search/URL with no cap hit and no `resumeFromRunId` - a capped or resumed run cannot tell "delisted" apart from "not reached yet", so EXPIRED detection is skipped that run (previous state is kept as-is) and retried on a future complete run.
- Combining `incrementalMode` with `resumeFromRunId` on a search that already has saved incremental state fails fast with a clear message; combining them when incremental mode has no prior state yet (a fresh monitoring campaign, bootstrapped from an existing dataset) is supported.
- What counts as a change: the comparison runs over the full listing record as returned, except `scrapedAt` (always differs, excluded by design), `detailRaw` (verbatim upstream detail payload), and `dldHistory` (Dubai Land Department transaction history) - both were measured churning between two back-to-back runs of the same, unchanged search and are excluded from the comparison. **`dldHistory` is real, meaningful data, not noise** - a genuinely new transaction added to a listing's history will not, by itself, flag that listing `UPDATED`; only a change to another field (price, description, ...) alongside it will. `raw` (the verbatim upstream *search* hit, distinct from `detailRaw`) is NOT excluded - any difference inside it is still reported as `UPDATED`.
- A detail page fetch that fails on a given run (`fetchDetails` on) does not erase that listing's detail fields (description, amenities, email, photos, ...) from the tracked baseline, and does not report their absence as the listing having changed - the previous run's detail data is carried forward internally until a detail fetch lands again. Symmetrically, a listing's first successful detail fetch after one or more failed attempts is not reported as those fields suddenly changing.
- State is stored in a dedicated key-value store, one JSON record per tracked listing (`raw` + fingerprint + first/last seen). It never re-touches dubizzle.com, so tracking costs no extra requests/proxy spend. Each store has a compressed-size cap; a very large `search` without `fetchDetails` fits roughly 1,900+ tracked listings, and with `fetchDetails` on (larger per-listing payload) roughly 650+, before the actor logs a clear error and stops saving state (narrow the search or split it across a few `stateKey`s). These are representative estimates sized off this actor's own field shapes, not a live-measured ceiling.
- Proxy country affects locale: this actor always requests the English (`en`) listing pages regardless of `apifyProxyCountry`, and price/currency are always AED, so a change in proxy exit country alone should not flip currency or field values already in a record and should not by itself produce spurious `UPDATED` rows.

### Send results into your apps (MCP connectors)

Optionally pipe results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify, Settings, Integrations, then select it in the input. Notion gets a page per item; other connectors get a best-effort write. The connector receives a condensed, human-readable summary per item (title plus key fields), not the full JSON. The complete record always stays in the Apify dataset. Set notionParentPageUrl when using Notion. Leave the field empty to skip; it never changes the dataset output. Supported: Notion, Linear, Airtable, Apify.

### Plan requirement

Dubizzle serves data most reliably to UAE residential connections. Use Apify Residential proxy with country AE (Starter plan or higher includes Residential proxy access). Datacenter proxies and free-tier accounts often return few or no items; the actor prints a clear warning at run start when it is not on residential. You can also supply your own residential gateway through the BACKUP\_PROXY\_URL secret.

# Actor input Schema

## `mode` (type: `string`):

Search mode = pick city + section + filters below and the scraper builds the URL for you. URL mode = paste any dubizzle.com listing URL(s) you already refined in a browser. URL mode supports multiple URLs.

## `locations` (type: `array`):

One or more UAE city slugs as Dubizzle writes them in the URL: 'dubai', 'abu-dhabi', 'sharjah', 'ras-al-khaimah', 'ajman', 'fujairah', 'umm-al-quwain', 'al-ain'. For sub-areas use the city slug; refine further with neighborhood in URL mode.

## `section` (type: `string`):

Which Dubizzle vertical to search. Property for sale / rent, used motors (cars), or property agents directory.

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

Property sub-type. 'residential' includes everything residential. Applies only to the property sections.

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

Minimum price filter in AED. Leave empty for no minimum. Search mode only.

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

Maximum price filter in AED. Leave empty for no maximum. Search mode only.

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

Minimum bedrooms (0 = studio). Property sections only.

## `maxBedrooms` (type: `integer`):

Maximum bedrooms. Property sections only.

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

Minimum built-up area in square feet. Property sections only.

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

Maximum built-up area in square feet. Property sections only.

## `furnishing` (type: `string`):

Furnishing filter. Property sections only.

## `completionStatus` (type: `string`):

Completed = ready to move in. Off-plan = under construction / pre-launch. Property sections only.

## `sortBy` (type: `string`):

How to order results. Search mode only - in URL mode the sort is taken from your pasted URL.

## `urls` (type: `array`):

One or more full dubizzle.com URLs (property, motors, or agents). Multi-URL supported. Filter-mode fields (city, section, price, beds, etc.) are ignored in URL mode - paste the URL exactly as Dubizzle produced it, including any filters. A URL ending with `?page=N` starts from that page.

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

Optional bound on result pages walked per location / URL. Dubizzle returns ~35 listings per page. Default 0 = walk as deep as the source serves: the run stops on its own once the storefront's reported total is reached or a page returns no new listings. This does NOT cap the number of listings; use Max listings for that.

## `maxListings` (type: `integer`):

The single cap on this run. Default 20 keeps first runs cheap and fast. Set 0 for unlimited (then the run stops at the storefront total / Max pages).

## `fetchDetails` (type: `boolean`):

Adds the full description, categorized amenities, agent email + agency license, the full photo gallery (vs SERP cover photo only), RERA/Trakheesi permit, off-plan payment plans, and (for Dubai property) the Dubai Land Department transaction history. Turn off for a faster, cheaper run with just the SERP fields (which already include lat/lng, agent phone, WhatsApp, and basic agency info). Each detail page is an extra fetch, so this run costs a per-item surcharge when enabled.

## `includeDldHistory` (type: `boolean`):

When detail mode is on, also pull the Dubai Land Department transaction history for Dubai property listings (past sale prices and dates for the building). Ignored when detail mode is off or for non-Dubai listings.

## `resumeFromRunId` (type: `string`):

Optional. ID of a previous run of this actor (or a dataset ID). Listings already in that dataset are skipped, so this run returns only NEW listings not seen before. Combine both runs' datasets for the full set. Max listings then counts only the new listings. The actor also checkpoints its own progress automatically, so a platform migration or a Resurrect of a FAILED/ABORTED run continues that same run without re-collecting or re-charging what it already pushed. For a recurring/scheduled monitoring campaign against the SAME search instead, use Incremental mode below - the two are complementary, not interchangeable, and combining them on a search with no prior incremental state bootstraps that state from this resumed dataset.

## `incrementalMode` (type: `boolean`):

For a scheduled/recurring run against the SAME search. When on, the actor remembers the previous run's listings itself (keyed on your filters, see State key) and classifies every listing as NEW, UPDATED, REAPPEARED, or UNCHANGED - UNCHANGED listings are skipped (not pushed, not charged) unless Emit unchanged is on. This is different from Resume above, which continues one specific interrupted run from a pasted run/dataset ID rather than remembering state itself.

## `stateKey` (type: `string`):

Optional. Name this monitoring campaign so it keeps its own baseline regardless of which caps you happen to pass. Leave empty to auto-derive one from your search filters (city, section, price, bedrooms, etc. - Max pages/Max listings never affect it, so raising or lowering those does not fork a new baseline or re-bill your whole search). Only relevant when Incremental mode is on.

## `emitUnchanged` (type: `boolean`):

When off (default), a listing identical to the last incremental run is skipped entirely - not pushed, not charged. Turn on to also emit UNCHANGED rows in the dataset (still marked changeType: UNCHANGED). This returns and bills every listing every run, defeating the point of incremental mode for most users - leave off unless you specifically need the full set every time. Only relevant when Incremental mode is on.

## `emitExpired` (type: `boolean`):

When on, a listing tracked by a previous incremental run that no longer appears is emitted once as changeType: EXPIRED (this returns and bills one extra row per delisted listing). Only fires after a run that reached the natural end of every search/URL with no cap hit and no Resume - a capped or resumed run cannot tell "delisted" apart from "not reached yet", so it is skipped that run and retried next time. Only relevant when Incremental mode is on.

## `proxy` (type: `object`):

Apify residential proxy with country=AE is strongly recommended. Datacenter proxies and free-tier accounts often return empty pages; residential UAE IPs give the most reliable results. The scraper rotates the exit IP and refreshes its session automatically on rejection.

## `mcpConnectors` (type: `array`):

Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON - the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

## `notionParentPageUrl` (type: `string`):

URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

## Actor input object example

```json
{
  "mode": "search",
  "locations": [
    "dubai"
  ],
  "section": "property-for-sale",
  "propertyType": "residential",
  "furnishing": "any",
  "completionStatus": "any",
  "sortBy": "popular",
  "urls": [
    "https://dubai.dubizzle.com/en/property-for-sale/residential/"
  ],
  "maxPages": 0,
  "maxListings": 20,
  "fetchDetails": false,
  "includeDldHistory": true,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "AE"
  },
  "maxNotifyListings": 50
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# 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 = {
    "mode": "search",
    "locations": [
        "dubai"
    ],
    "urls": [
        "https://dubai.dubizzle.com/en/property-for-sale/residential/"
    ],
    "maxPages": 0,
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "AE"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/dubizzle-com-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 = {
    "mode": "search",
    "locations": ["dubai"],
    "urls": ["https://dubai.dubizzle.com/en/property-for-sale/residential/"],
    "maxPages": 0,
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "AE",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/dubizzle-com-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 '{
  "mode": "search",
  "locations": [
    "dubai"
  ],
  "urls": [
    "https://dubai.dubizzle.com/en/property-for-sale/residential/"
  ],
  "maxPages": 0,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "AE"
  }
}' |
apify call abotapi/dubizzle-com-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/1PiyqbXmQ5emYCCyI/builds/MKeNuLMyg3ziiZsEO/openapi.json
