# Zameen Scraper \[From $0.9💰] | Listings | Agencies | PK Data (`ahmed_jasarevic/zameen-scraper`) Actor

Extract Zameen.com property listings and real estate agency data for property price monitoring, rental yield analysis and Pakistan real estate market research. Prices in PKR, areas in marla and kanal, structured rows via API.

- **URL**: https://apify.com/ahmed_jasarevic/zameen-scraper.md
- **Developed by:** [Ahmed Jasarevic](https://apify.com/ahmed_jasarevic) (community)
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 listings

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Zameen Scraper — Pakistan Property Listings & Agent Data From zameen.com

Extract **~237,490 active Zameen.com listings** and **~15,423 agencies** into structured JSON — price in PKR, area in marla / kanal / sq ft, beds & baths, society / block, photos, full descriptions and agent mobile / landline / WhatsApp numbers — by querying Zameen's own Elasticsearch search backend directly. Built for property price monitoring, Pakistan property databases and real-estate lead generation — no browser, no anti-bot bypass.

***

### Main Use Cases: Property Price Monitoring, Pakistan Property Database & Real Estate Lead Generation

- **Property price monitoring** — pull the freshest sale and rent asking prices (`sort: newest`, `purpose`, `priceMin` / `priceMax`) city by city (Lahore, Karachi, Islamabad, …), then diff runs on `listingId` + `pricePkr` to catch price drops.
- **A Pakistan property database** — sweep the full ~237,490-listing index with `search_after` pagination (no 10,000-result ceiling) and export JSON, CSV or Excel from the Apify dataset.
- **Real estate market research** — filter by purpose, category, rooms, price, area and `createdAt`; `city`, `society`, `block` and `locationPath[]` structure rows for city- and society-level analysis (DHA Lahore plot rates, Karachi commercial rates, Islamabad rents).
- **Real estate lead generation** — `mode: agencies` returns up to 15,423 agencies with mobile, landline and WhatsApp numbers, listing counts, licenses and tier.
- **Rental yield analysis** — sale and rent rows share one schema (`purpose`, `rentFrequency`, `pricePkr`, `areaMarla`) — gross-yield tables are a join away.
- **Overseas Pakistani property investment research** — PKR prices, marla/kanal areas and coordinates for PK/Gulf investor analysts, no browser needed.

***

### How The Zameen Scraper Works (Elasticsearch Backend, No Browser)

Zameen is a Next.js-style server-rendered app: any plain HTTP GET returns the full application state inline as `window.state`. This Actor calls the search cluster it describes — Zameen's own Elasticsearch `_search` API — over plain HTTP with `size: 1000` pages and `search_after` pagination, maps each `_source` document to one dataset row, and optionally (`fetchFullDetails: true`) runs a CheerioCrawler pass over the property pages' `window.state` blobs to add the full description, every photo URL and the complete phone set. No Playwright/Puppeteer, no Cloudflare challenge, no paid anti-bot API. Rows are `recordType: "property"` or `recordType: "agency"`.

***

### Input Parameters

All fields are optional (no required input); the defaults below run immediately.

| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
| `mode` | `search` | `detail` | `agencies` | No | `search` | `search` = listings, `detail` parses `propertyUrls`, `agencies` = agent/agency directory. |
| `purpose` | `for-sale` | `for-rent` | No | — (UI prefill `for-sale`) | Empty = both sale and rent. |
| `city` | string | No | — | Exact Zameen location name: `Lahore`, `Karachi`, `Islamabad`, `Rawalpindi`, `Multan`, `Faisalabad`, `Peshawar`, `Gujranwala`, … |
| `category` | string | No | — | Property category, e.g. `Homes`, `Plots`, `Offices`, `Commercial`, `Agricultural`, `Industrial`. |
| `bedroomsMin` | integer | No | — | Minimum bedrooms (0–20). |
| `bedroomsMax` | integer | No | — | Maximum bedrooms (0–20). |
| `bathsMin` | integer | No | — | Minimum bathrooms (0–20). |
| `bathsMax` | integer | No | — | Maximum bathrooms (0–20). |
| `priceMin` | number | No | — | Absolute PKR, e.g. `20000000` = 2 crore (min 0). |
| `priceMax` | number | No | — | Absolute PKR, e.g. `50000000` = 5 crore (min 0). |
| `areaMinSqft` | number | No | — | Square feet; converted to m² internally (1 marla = 225 sq ft, 1 kanal = 4,500 sq ft). |
| `areaMaxSqft` | number | No | — | Square feet; converted to m² internally (same factors). |
| `keyword` | string | No | — | Free-text match against title, short description, keywords and location path (e.g. `DHA`). |
| `sort` | `newest` | `oldest` | `price-asc` | `price-desc` | `area-desc` | No | `newest` | `newest` = freshest inventory, best for lead-gen and price tracking. |
| `maxListings` | integer | No | `100` | Hard cap for `mode: search` (1–20,000); `search_after` scales past the 10k window. Free plans cap 10 rows. |
| `maxAgencies` | integer | No | `25` | Hard cap for `mode: agencies` (1–5,000; Zameen publishes ~15,400 agencies). |
| `maxDetailPages` | integer | No | `20` | Property pages getting the Cheerio full-detail pass (1–500). Free plans cap 10. |
| `fetchFullDetails` | boolean | No | `false` | Enrich each listing with full description, all photo URLs, video/panorama counts and contact numbers — still no browser (`window.state` blob). |
| `propertyUrls` | string\[] | No | `[]` | Required only for `mode: "detail"` — explicit `https://www.zameen.com/Property/...html` URLs. |
| `proxy` | object | No | `{ "useApifyProxy": false }` | Standard Apify proxy picker — choose group/country in the UI. Not needed by default: the backend is unauthenticated-by-WAF. |

***

### Output Fields

The shipped dataset schema declares an empty `fields` map and one table view — **Overview** — with columns `recordType` (Type), `title` (Title), `name` (Agency), `city` (City), `purposeLabel` (For), `priceFormatted` (Price), `areaMarla` (Area), `bedrooms` (Beds), `bathrooms` (Baths), `url` (Listing URL) and `profileUrl` (Agency URL). Every row carries `recordType: "property"` or `"agency"`.

**Property row — 58 fields**, grouped:

- **Identity** — `listingId`, `externalId`, `dldPropertySK`, `referenceNumber`, `url`, `slug`, `title`, `titleUrdu`
- **Deal** — `purpose` (`"for-sale"` | `"for-rent"`), `purposeLabel`, `pricePkr`, `priceFormatted`, `rentFrequency`, `category`, `subCategory`
- **Area** — `areaSqm`, `areaSqft`, `areaMarla`, `areaKanal`
- **Rooms** — `bedrooms`, `bathrooms`
- **Location** — `country`, `province`, `city`, `society`, `block`, `locationName`, `locationHierarchy`, `locationPath[]`, `geoLat`, `geoLng`
- **Status** — `completionStatus`, `furnishingStatus`, `occupancyStatus`, `ownershipStatus`
- **Media & tags** — `amenities[]`, `keywords[]`, `photoCount`, `coverPhotoUrl`, `photos[{url,id,title,order}]`, `videoCount`, `panoramaCount`
- **Text** — `shortDescription`, `description`, `descriptionHtml`
- **Contact** — `contact { contactName, mobile, phone, whatsapp, allPhoneNumbers[], allMobileNumbers[] }`
- **Listing agency** — `agency { agencyId, externalId, name, slug, profileUrl, logoUrl, type, product, tier, tr }`
- **Flags & meta** — `isVerified`, `verificationStatus`, `product`, `state`, `createdAt`, `updatedAt`, `reactivatedAt`, `scrapedAt`

**Agency row** — `agencyId`, `name`, `slug`, `profileUrl`, `logoUrl`, `city`, `cities[]`, `geoLat`/`geoLng`, `licenses[]`, `agentsCount`, `listingsTotal` / `listingsForSale` / `listingsForRent`, `contact { mobile, phone, allPhoneNumbers[], allMobileNumbers[] }`.

#### Area units (marla, kanal, sq ft)

Zameen stores `area` in **square metres** (verified against live documents):

| Document | `area` (raw) | Correct |
|---|---|---|
| 5 marla house | `104.51592` | 1,125 sq ft |
| 20 marla plot | `418.06368` | 4,500 sq ft = 1 kanal |
| 8 kanal commercial | `3344.50944` | 36,000 sq ft |

It emits `areaSqft`, `areaMarla` (1 marla = 225 sq ft) and `areaKanal` (1 kanal = 20 marla) alongside `areaSqm`.

***

### Example Input And Output

Freshest Lahore sale listings with full descriptions:

```json
{
  "mode": "search",
  "purpose": "for-sale",
  "city": "Lahore",
  "sort": "newest",
  "maxListings": 500,
  "fetchFullDetails": true,
  "maxDetailPages": 50
}
```

3–4 bed homes between 2 and 5 crore in Karachi:

```json
{ "mode": "search", "purpose": "for-sale", "city": "Karachi", "category": "Homes",
  "bedroomsMin": 3, "bedroomsMax": 4, "priceMin": 20000000, "priceMax": 50000000, "maxListings": 200 }
```

Agency lead list:

```json
{ "mode": "agencies", "city": "Lahore", "maxAgencies": 500 }
```

One property row:

```json
{
  "recordType": "property",
  "listingId": 2961458,
  "url": "https://www.zameen.com/Property/Islamabad-G-13-5-Marla-House-for-sale-2961458.html",
  "title": "5 Marla House for sale in G-13, Islamabad",
  "purpose": "for-sale",
  "purposeLabel": "For Sale",
  "pricePkr": 27000000,
  "priceFormatted": "PKR 2.7 Crore",
  "category": "Homes",
  "areaSqm": 104.51592,
  "areaSqft": 1125,
  "areaMarla": 5,
  "areaKanal": 0.25,
  "bedrooms": 3,
  "bathrooms": 4,
  "city": "Islamabad",
  "society": "G-13",
  "locationName": "G-13, Islamabad",
  "geoLat": 33.668,
  "geoLng": 72.986,
  "photoCount": 12,
  "shortDescription": "Well-located 5 marla house in G-13 near amenities.",
  "contact": {
    "contactName": "Example Realtor",
    "mobile": "+92 300 1234567",
    "whatsapp": "+92 300 1234567",
    "allPhoneNumbers": ["+92 300 1234567"]
  },
  "agency": {
    "agencyId": 48215,
    "name": "Example Estates",
    "profileUrl": "https://www.zameen.com/agents/example-estates/"
  },
  "isVerified": true,
  "scrapedAt": "2026-10-07T09:15:00.000Z"
}
```

***

### Zameen API Alternative — Structured Property Listings Data From zameen.com

There is no official Zameen developer API. A plain `curl` of any page returns the application state inline as `window.state`, carrying the connection details of the search cluster **Zameen's own frontend queries**:

```bash
curl -s https://www.zameen.com/ | grep -o 'window.state = .\{0,900\}'
```

The state key is named `algolia` (historical) but `activeBackendName` is `"elastic"` — the live backend is a **self-hosted Elasticsearch cluster on AWS**, not Algolia; the dns-prefetched Algolia DSN serves type-ahead only.

**Exact endpoints:**

| Purpose | Index | Endpoint |
|---|---|---|
| Property listings | `zameen-production-ads-en` | `POST https://search-zameen-live-kiqsqbqxiuzpzkqbjwkboe32g4.eu-west-1.es.amazonaws.com/zameen-production-ads-en/_search` |
| Agencies / agents | `zameen-production-agencies-en` | `POST https://search-zameen-live-kiqsqbqxiuzpzkqbjwkboe32g4.eu-west-1.es.amazonaws.com/zameen-production-agencies-en/_search` |

**Auth:** HTTP Basic with the credentials Zameen publishes in `window.state` — over plain-HTTP JSON `_search`, **not** behind Cloudflare, the web WAF, cookies, tokens or any browser challenge.

**Why this beats rendering the site:**

| | Site HTML (browser) | This Actor's backend |
|---|---|---|
| Requests per 1,000 listings | ~1,000 page loads | **1** `_search` (`size: 1000`) |
| Anti-bot | Cloudflare + possible challenge | none |
| Memory / compute | full Chrome (~1 GB+) | plain HTTP client (**256 MB**) |
| Enrichment | client-side fetch | full record already in `_source` |

**Verified cluster capabilities:** `size` up to `5000` (Actor uses `1000` per page); `search_after` deep pagination → **no 10,000 `result_window` ceiling**, so a full 237k sweep is possible; `aggregations` for facet discovery (e.g. `location.name` gives every city / society); filterable fields `purpose`, `state`, `location.name`, `category.name`, `rooms`, `baths`, `price`, `area`, `createdAt`; sortable fields `createdAt`, `price`, `area`, `id` (listings) and `stats.adsCount`, `id` (agencies).

> Field-mapping gotchas already handled in code: `location.name` / `category.name` are the mapped paths (there is **no** `.keyword` sub-field — a `.keyword` term query silently returns 0 hits), and the agency sort field is `stats.adsCount` (no root-level `adsCount`).

**Secondary source — CheerioCrawler, still no browser.** The listings index only carries a truncated `shortDescription`; the full text and every photo URL live in the property page's `window.state` blob (`state.property.data` = description, `photos[]`, floorPlans, panoramas, videos, primaryPhoneNumber, …). With `fetchFullDetails: true` the Actor runs a CheerioCrawler (plain HTTP + JSON parse, no DOM scraping) over the first `maxDetailPages` listings — property pages return HTTP 200 to a plain `got-scraping` request, so no browser is needed.

Public URL shapes:

- Listing detail: `https://www.zameen.com/Property/{slug}.html` (field: `link`; carried per row as `url` + `slug`)
- Agency profile: `https://www.zameen.com/agents/{slug}/` (verified live: `/agents/<slug>/` → 200, `/agency/<slug>` → 404)

**Maintainability.** If Zameen rotates the cluster or credentials, update two constants in `src/routes.ts` (`ES_URL`, `ES_CREDENTIALS`) plus the index names in the same file, then re-discover them with the `window.state` curl above. If the blob ever moves, the Actor degrades gracefully: search-cluster rows still return (short description + cover photo) without the enrichment pass.

***

### Run Zameen Scraper From The Apify API, Console Or Schedule

Start runs from the Console or through the API:

```bash
curl -X POST "https://api.apify.com/v2/acts/6HsHbEjMz6yeJ1pRn/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode":"search","city":"Lahore","sort":"newest","maxListings":200}'
```

Then poll `GET /v2/actor-runs/<runId>` and read rows from `GET /v2/datasets/<datasetId>/items?format=json`. The dataset UI exports JSON, CSV, Excel; Google Sheets via Zapier / Make.

**Cost & limits:**

- **Memory:** `256 MB` (max `512 MB`) — plain HTTP, no browser.
- **Free vs paid:** free accounts are capped at **10 rows** per dataset via `APIFY_USER_IS_PAYING`; paying accounts run the full configured caps.
- **Runaway protection:** hard caps in code (`HARD_MAX_LISTINGS`, `HARD_MAX_AGENCIES`, `HARD_MAX_DETAIL_PAGES`), `maxRequestsPerCrawl`, `maxRequestRetries: 2`, timeouts, and terminating `search_after` pagination.
- **No paid anti-bot API required** — the Elasticsearch backend is unauthenticated-by-WAF.

**Pay-per-event billing:**

| Event | Price |
|---|---|
| `Listing` | $0.0009 per property row |
| `Agency` | $0.0009 per agency row |
| `Actor Start` | $0.00005 per run |

***

### Integrations & Automation

- **Apify API** — start, poll and read results programmatically.
- **Webhooks** — fire on `actor.succeeded` / `actor.failed` to push rows into a warehouse, Google Sheets or Slack.
- **Zapier / Make** — turn a new dataset item into a CRM record or deal-alert email without code.
- **Schedules** — run **daily** for price monitoring (e.g. cron `0 6 * * *`) or **weekly** for a market digest; keep `maxListings` stable so dataset diffs stay meaningful.

***

### Related Actors

- [zameen-scraper](https://apify.com/haketa/zameen-scraper)
- [zameen-scraper](https://apify.com/solidcode/zameen-scraper)
- [zameen-property-scraper](https://apify.com/logiover/zameen-property-scraper)
- [zameen-real-estate-scraper](https://apify.com/crawlerbros/zameen-real-estate-scraper)
- [zameen-com-scraper](https://apify.com/shahidirfan/zameen-com-scraper)

***

### FAQ

#### Does Zameen.com have an official API?

No — a public API-marketplace FAQ asks that verbatim and answers "no official developer API". This Actor queries the site's own Elasticsearch `_search` backend — the endpoint the Zameen frontend consumes — returning the same records as dataset rows.

#### Why use this actor instead of the official API?

There is no official API. Versus rendering the site yourself: **1** `_search` request (`size: 1000`) covers what costs ~1,000 page loads, memory stays at 256 MB instead of ~1 GB+ of Chrome, no Cloudflare challenge is ever hit, the full record already sits in `_source`, and `search_after` removes the 10,000-result window so a full ~237,490-listing sweep is possible.

#### How do I check property prices in Lahore, Karachi and Islamabad?

Set `city` to the exact Zameen name (`Lahore`, `Karachi`, `Islamabad`, `Rawalpindi`, `Multan`, `Faisalabad`, `Peshawar`, `Gujranwala`) and sort with `price-asc` / `price-desc`, or `newest` for current inventory. Rows carry `pricePkr`, `priceFormatted`, `areaMarla` / `areaKanal` / `areaSqft` and `society` / `block` for city-level price tables.

#### How do I get property prices in DHA Lahore?

Run `mode: "search"` with `city: "Lahore"` and `keyword: "DHA"` (the keyword matches the location path, so DHA phases surface), then group rows by `society` / `block` or filter `locationPath[]`.

#### How can I export Zameen listings to CSV, JSON or Google Sheets?

Run `mode: "search"`, then export the Apify dataset as JSON, CSV or Excel, or push rows to Google Sheets via Zapier / Make.

#### How do I monitor new listings and price drops?

Schedule daily or weekly (`sort: "newest"`, stable `maxListings`), diff datasets on `listingId` + `pricePkr` + `updatedAt`, and use webhooks to alert on completion.

#### Is Zameen.com data reliable for property valuations?

Treat it as **asking-price** evidence, not transaction prices — analysts warn portal figures are asking-price proxies, and Pakistan has no central open transaction registry, so listing-portal aggregates are the de-facto source.

#### What is the rental yield in Lahore, Karachi or Islamabad?

Run both purposes (`purpose` empty = sale + rent), then compute gross yield as annualised rent ÷ sale price from `pricePkr`, `rentFrequency` and `areaMarla`.

#### How do I get real estate agent phone numbers in Pakistan?

`mode: "agencies"` returns up to ~15,423 agencies with `contact.mobile`, `contact.phone`, `whatsapp`, licenses, listing counts and tier, plus `city` / `cities[]`. Business contact details published for marketing — B2B lead generation, not unsolicited consumer outreach.

#### What are the alternatives to Zameen Scraper?

Portals: **Graana**, **OLX Pakistan**'s property vertical and **eproperty.pk**. Store actors: `haketa/zameen-scraper`, `solidcode/zameen-scraper`, `logiover/zameen-property-scraper`, `crawlerbros/zameen-real-estate-scraper`, `shahidirfan/zameen-com-scraper`.

***

### SEO Keywords

zameen scraper, zameen api, zameen property listings data, zameen data export, zameen alternative, pakistan property database, real estate data extraction, property price monitoring, real estate market research, rental yield analysis, real estate lead generation, real estate agent contact list pakistan, property price tracking, pakistan real estate market, pakistan property portal, lahore property prices, karachi property prices, islamabad property prices, property prices in dha lahore, plot for sale, commercial property rates karachi, rent prices islamabad, overseas pakistani property investment

### For AI Agents & LLM Apps

**Purpose:** query Zameen.com's own Elasticsearch backend (optionally its public property pages) → one JSON row per property listing (58 fields) or agency: PKR prices, marla/kanal/sq ft areas, contact details — no browser.

Minimal input:

```json
{ "mode": "search", "city": "Lahore", "maxListings": 25 }
```

Variant — agency directory mode:

```json
{ "mode": "agencies", "city": "Karachi", "maxAgencies": 100 }
```

Output fields: `recordType`; property rows — listingId, externalId, dldPropertySK, referenceNumber, url, slug, title, titleUrdu, purpose, purposeLabel, pricePkr, priceFormatted, rentFrequency, category, subCategory, areaSqm, areaSqft, areaMarla, areaKanal, bedrooms, bathrooms, country, province, city, society, block, locationName, locationHierarchy, locationPath, geoLat, geoLng, completionStatus, furnishingStatus, occupancyStatus, ownershipStatus, amenities, keywords, photoCount, coverPhotoUrl, photos, videoCount, panoramaCount, shortDescription, description, descriptionHtml, contact{contactName, mobile, phone, whatsapp, allPhoneNumbers, allMobileNumbers}, agency{agencyId, externalId, name, slug, profileUrl, logoUrl, type, product, tier, tr}, isVerified, verificationStatus, product, state, createdAt, updatedAt, reactivatedAt, scrapedAt; agency rows — agencyId, name, slug, profileUrl, logoUrl, city, cities, geoLat, geoLng, licenses, agentsCount, listingsTotal, listingsForSale, listingsForRent, contact{...}.

Behaviors an agent should know:

- `mode` defaults to `search`; `mode: "detail"` requires `propertyUrls`; `"agencies"` switches rows to agency records (billed as `Agency`).
- Empty `purpose` means both sale and rent; `sort` defaults to `newest`.
- Caps: `maxListings` 100 (max 20,000), `maxAgencies` 25 (max 5,000), `maxDetailPages` 20 (max 500). Free plans return only 10 rows regardless of input (`APIFY_USER_IS_PAYING`).
- `fetchFullDetails` defaults to `false`; `true` adds one plain-HTTP request per enriched listing, capped by `maxDetailPages` — still no browser.
- `priceMin`/`priceMax` are absolute PKR; `areaMinSqft`/`areaMaxSqft` convert to m² internally (1 marla = 225 sq ft, 1 kanal = 4,500 sq ft).
- `city` must match Zameen's exact spelling; this backend has no `.keyword` sub-field — filter via the Actor's inputs.
- Proxy is off by default (`useApifyProxy: false`) and normally unnecessary — the backend is not behind Cloudflare/WAF.

Billing: pay-per-event — `Listing` $0.0009 per property row + `Agency` $0.0009 per agency row + `Actor Start` $0.00005 per run.

### Legal & Compliance Disclaimer

This Actor is an independent project and is **not affiliated with, endorsed by or sponsored by** Zameen.com or its operators.

It accesses only publicly available, unauthenticated data that Zameen renders for anonymous visitors — plain-HTTP reads of public search results and property pages (`window.state` JSON and Elasticsearch `_search` responses). No browser, no login, no authentication or anti-bot bypass; the Actor does not touch `/api/userEvents`, `/account`, `/nfpage/` or `/captchaChallenge`.

You are responsible for complying with Zameen.com's Terms of Service and applicable data-protection law — including Pakistan's PDPL and, where relevant, UAE PDPL — before commercial redistribution; respect `robots.txt` and rate-limit usage.

The output includes agent and agency phone numbers — business contact details published by Zameen for public viewing. They must not be used for unsolicited commercial outreach in violation of applicable law; this Actor targets B2B lead generation, not consumer cold-outreach.

# Actor input Schema

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

`search` = property listings from Zameen's Elasticsearch search backend. `detail` = parse explicit `propertyUrls`. `agencies` = agent/agency directory with phone numbers.

## `purpose` (type: `string`):

Leave empty to include both. `for-sale` = sale listings, `for-rent` = rent listings.

## `city` (type: `string`):

Exact Zameen location name, e.g. `Lahore`, `Karachi`, `Islamabad`, `Rawalpindi`, `Multan`, `Faisalabad`, `Peshawar`, `Gujranwala`.

## `category` (type: `string`):

Property category name, e.g. `Homes`, `Plots`, `Offices`, `Commercial`, `Agricultural`, `Industrial`.

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

Minimum number of bedrooms.

## `bedroomsMax` (type: `integer`):

Maximum number of bedrooms.

## `bathsMin` (type: `integer`):

Minimum number of bathrooms.

## `bathsMax` (type: `integer`):

Maximum number of bathrooms.

## `priceMin` (type: `number`):

Absolute PKR amount, e.g. 20000000 for 2 crore.

## `priceMax` (type: `number`):

Absolute PKR amount, e.g. 50000000 for 5 crore.

## `areaMinSqft` (type: `number`):

Converted to m² internally. 1 marla = 225 sq ft, 1 kanal = 4500 sq ft.

## `areaMaxSqft` (type: `number`):

Converted to m² internally. 1 marla = 225 sq ft, 1 kanal = 4500 sq ft.

## `keyword` (type: `string`):

Free-text match against title, short description, keywords and location path.

## `sort` (type: `string`):

`newest` gives freshest inventory - best for lead-gen and price tracking.

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

Hard cap for `mode: search`. Enumeration uses search_after pagination, so it scales past the 10k window. Free plans are capped at 10 rows.

## `maxAgencies` (type: `integer`):

Hard cap for `mode: agencies` (Zameen publishes ~15,400 agencies).

## `maxDetailPages` (type: `integer`):

How many property pages to fetch with CheerioCrawler for the FULL description + every photo URL. Free plans are capped at 10.

## `fetchFullDetails` (type: `boolean`):

When true, each returned listing is enriched with a CheerioCrawler request to its Zameen page to pull the complete description, all photo URLs, video/panorama counts and contact numbers (still no browser - the data lives in the page's `window.state` JSON blob).

## `propertyUrls` (type: `array`):

Required only for `mode: detail`. Explicit zameen.com property URLs, e.g. `https://www.zameen.com/Property/...html`.

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

Select proxies to be used by your crawler.

## Actor input object example

```json
{
  "mode": "search",
  "purpose": "for-sale",
  "sort": "newest",
  "maxListings": 100,
  "maxAgencies": 25,
  "maxDetailPages": 20,
  "fetchFullDetails": false,
  "propertyUrls": [],
  "proxy": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (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 = {
    "purpose": "for-sale",
    "proxy": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("ahmed_jasarevic/zameen-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 = {
    "purpose": "for-sale",
    "proxy": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("ahmed_jasarevic/zameen-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "purpose": "for-sale",
  "proxy": {
    "useApifyProxy": false
  }
}' |
apify call ahmed_jasarevic/zameen-scraper --silent --output-dataset

```

## MCP server setup

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

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/6HsHbEjMz6yeJ1pRn/builds/bUgTVaYZWmN3gMuKW/openapi.json
