# Aqarmap Scraper with Contacts & Description (`fatihtahta/aqarmap-property-scraper`) Actor

Extract Aqarmap property listings across Egypt with rich property detail, contact data, pricing, media, developers, and flexible market filters. Built for enterprise-grade Egypt real estate intelligence, lead enrichment, inventory monitoring, and automated analytics pipelines.

- **URL**: https://apify.com/fatihtahta/aqarmap-property-scraper.md
- **Developed by:** [Fatih Tahta](https://apify.com/fatihtahta) (community)
- **Categories:** Real estate, Lead generation, Agents
- **Stats:** 2 total users, 1 monthly users, 50.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 property 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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

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

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

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

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

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

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

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

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

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

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

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


# README

## Aqarmap Scraper

**Slug:** `fatihtahta/aqarmap-scraper`

### Overview

Aqarmap Scraper collects structured public property listing records from Aqarmap, including listing identity, location, pricing, property attributes, media, contact details when available, and related party information. [Aqarmap](https://aqarmap.com.eg) is a major real-estate marketplace for Egypt, making its public listings useful for market discovery, inventory monitoring, competitive analysis, and operational reporting. The actor helps teams turn public listing pages into repeatable JSON records that are easier to review, compare, export, and sync into downstream systems. Users can scope runs by location, keyword, listing mode, property category, price, area, amenities, compound status, enrichment depth, and output limit. Results are delivered as structured dataset records suitable for review, export, analytics, ETL pipelines, AI-agent workflows, and downstream APIs. The actor is designed for dependable recurring data acquisition without requiring users to manually copy listing details from the website.

### Who Should Use This Actor

- **Market research and analytics teams:** compare public supply, pricing, property categories, locations, amenities, and listing availability across repeatable market segments.
- **Real-estate operators and investment teams:** build structured monitoring workflows for selected geographies, property types, price bands, and inventory segments.
- **Product, marketplace, and catalog teams:** normalize public property listings into a consistent dataset for search, matching, quality review, and internal catalog enrichment.
- **Developers and data engineering teams:** feed predictable nested JSON records into warehouses, APIs, search indexes, vector stores, and enrichment pipelines.
- **AI agents and workflow automations:** collect a scoped property dataset, summarize changes, identify records for review, and route outputs to the next workflow step.
- **Sales, lead generation, and CRM teams:** review public listing contacts, agencies, developers, and property attributes when those fields are available in the output.
- **Monitoring and operations teams:** schedule recurring runs for reporting, alerts, QA review, and downstream sync checks.

### Common Use Cases

- **Market intelligence:** monitor public property supply, pricing, property types, amenities, locations, and listing details for selected Aqarmap segments.
- **Competitive monitoring:** track public listing activity across categories, price bands, geographies, compounds, or broker-visible records.
- **Lead review and enrichment:** identify public listing records with contact details, agent names, agency names, developer names, media, and property attributes.
- **Catalog and directory building:** populate internal property datasets with structured public listing records and stable source identifiers.
- **Data enrichment:** add current public listing attributes to CRM, BI, research, or valuation datasets.
- **Recurring reporting:** schedule repeat runs for dashboards, alerts, inventory snapshots, and market movement analysis.
- **Agentic research workflows:** let an internal agent collect a scoped dataset, compare it with previous records, summarize notable changes, and queue records for human review.
- **Map-based inspection:** use saved listing coordinates when available to review geographic coverage and listing clusters.

### Real-World Questions This Data Can Answer

- Which public Aqarmap listings match a specific location, property category, deal type, keyword, price band, area range, or amenity profile?
- Which property listings appear in a selected market segment today, and which fields are available for review or export?
- Which listings include useful public signals for outreach, enrichment, or operational review?
- Which properties are new, removed, or changed when repeated runs are compared by stable listing identifiers?
- How do prices, floor areas, property types, and visible amenities vary across selected locations or categories?
- Which records include media, contact details, coordinates, or related party information that can support downstream workflows?
- Which optional fields are populated often enough to power dashboards, alerts, or human review queues?

### Quick Start

1. Choose a market scope. Use `location` for a targeted search, or leave it empty for broader discovery.
2. Select the listing mode, property category, language, and any filters that define the segment you want to collect.
3. Set a small `limit` for the first validation run, such as 10 or 25 records.
4. Run the actor in Apify Console.
5. Inspect the first dataset records to confirm the output shape and field coverage match your use case.
6. Increase the limit, adjust filters, export the dataset, or schedule the actor once the output is verified.

### Input Parameters

Configure Aqarmap property listing collection by selecting a market scope, listing mode, property category, optional filters, enrichment depth, and result limit.

| Parameter | Type | Description | Default |
| --- | --- | --- | --- |
| `location` | string | Optional location phrase for targeted market discovery, such as `great cairo`, `new cairo`, or `sheikh zayed`. Leave empty for a broad category search. | - |
| `keyword` | string | Optional free-text term used to narrow discovery to listings matching a phrase, feature, project, or local search intent. | - |
| `language` | string | Requested Aqarmap language. Allowed values: `english`, `arabic`. | `english` |
| `deal_type` | string | Listing mode. Allowed values: `buy`, `rent`. Use `buy` for sale listings and `rent` for rental listings. | `buy` |
| `property_type` | string | Property category. Allowed values: `property-type`, `apartment`, `furnished-apartment`, `chalet`, `villa`, `land-or-farm`, `building`, `commercial`, `administrative`, `medical`, `land-or-commercial`. | `property-type` |
| `min_price` | integer | Optional minimum listing price in EGP. Use it to remove listings below a target budget band. | - |
| `max_price` | integer | Optional maximum listing price in EGP. Use it to keep exports within a target affordability or investment range. | - |
| `min_area` | integer | Optional minimum floor area in square meters. Minimum accepted value is 10. | - |
| `max_area` | integer | Optional maximum floor area in square meters. Minimum accepted value is 10 and maximum accepted value is 5000. | - |
| `amenities` | array of strings | Optional amenities that listings should include. Allowed values: `balcony`, `security`, `elevator`, `maid_room`, `water_meter`, `pets_allowed`, `landline_phone`, `swimming_pool`, `private_garden`, `kids_play_area`, `air_conditioning`, `covered_parking`, `electricity_meter`, `natural_gas_meter`, `kitchen_appliances`. | `[]` |
| `inside_compound` | boolean | When enabled, focuses collection on listings inside compounds for compound-level monitoring or premium inventory review. | `false` |
| `enrich_data` | boolean | When enabled, collects richer listing details when available, such as descriptions, photos, features, contact values, and related parties. Disable for faster standard listing records. | `true` |
| `limit` | integer | Maximum number of records to save. Use a smaller value for validation and a larger value for scheduled exports or downstream ingestion. | - |

### Choosing Inputs

Use `location` when you need a targeted market dataset, such as a city, district, neighborhood, or compound-adjacent search area. Leave `location` empty when the goal is broad discovery across a property category or listing mode.

Use `deal_type` to separate sale and rental workflows. Keeping sale and rental runs separate usually makes pricing analysis, monitoring, and downstream comparison cleaner.

Use `property_type` to control the real-estate segment. The broad `property-type` value is useful for discovery, while specific categories such as `apartment`, `villa`, `chalet`, or `commercial` are better for operational reporting and category-level monitoring.

Use `keyword` for project names, features, neighborhood phrases, or other text-based intent. Keywords can make datasets more relevant, but they can also reduce coverage if the source has few matching records.

Use price, area, amenities, and compound filters when you already know the segment you want. Narrower filters produce more targeted datasets; broader filters improve discovery and help reveal the available market.

Use `enrich_data` when richer fields matter for review, CRM enrichment, map artifacts, media inspection, or AI summarization. Use a lower `limit` first when enrichment is enabled, then scale after validating the field coverage.

Use `limit` as a workflow control. Start small for QA, then increase after confirming that the selected scope returns useful records.

### Input Recipes

- **Validation run:** choose one listing mode, one property category, optional location, and a low `limit`. Use this to inspect field coverage before scaling.
- **Targeted market collection:** provide a `location`, select `deal_type`, choose a specific `property_type`, and add price or area filters for a focused operational dataset.
- **Broad discovery:** leave `location`, `keyword`, and most filters empty, choose a property category, and set a conservative `limit` to review the available market.
- **Compound-focused monitoring:** enable `inside_compound`, choose the relevant property category, and repeat the same input on a schedule for comparable snapshots.
- **Amenities-based lead review:** select one or more `amenities`, enable `enrich_data`, and review records with contact details or related party fields when available.
- **Segmented analysis:** run separate jobs by geography, property type, deal type, or price band so each dataset maps cleanly to a downstream report or warehouse partition.

### Example Inputs

#### Example: Broad villa discovery

```json
{
  "language": "english",
  "deal_type": "buy",
  "property_type": "villa",
  "enrich_data": true,
  "limit": 10
}
````

#### Example: Targeted apartment search in Greater Cairo

```json
{
  "location": "great cairo",
  "language": "english",
  "deal_type": "buy",
  "property_type": "apartment",
  "min_price": 200000,
  "max_price": 30000000,
  "limit": 25
}
```

#### Example: Rental monitoring with amenities

```json
{
  "location": "new cairo",
  "language": "arabic",
  "deal_type": "rent",
  "property_type": "furnished-apartment",
  "amenities": ["balcony", "security"],
  "inside_compound": true,
  "limit": 50
}
```

### Output

#### Output Destination

The actor writes results to an Apify dataset as JSON records. The dataset is designed for direct consumption by analytics tools, ETL pipelines, AI agents, and downstream APIs with minimal post-processing.

The current output shape is a `property_listing` record. If additional entity types are added in the future, each shape should be documented separately.

The actor also exposes an output link for the default dataset and, when available, an interactive listing map artifact built from saved records with valid coordinates.

#### Record Envelope And Stable Identifiers

Each saved record uses `record_type` to identify the normalized output family and `record_id` for the source listing identifier when available. The recommended idempotency key is `record_id` when present, with `entity.url` or `source_context.canonical_url` as a fallback.

For conservative warehouse or CRM upserts, use a composite key such as `source_context.source_domain + record_id`, or fall back to `source_context.source_domain + entity.url` when a listing ID is unavailable. Stable identifiers make records easier to merge, deduplicate, sync, and compare across repeated runs.

The `source_context` object carries provenance fields such as source name, domain, source URL, canonical URL, result position, country, and requested language. Use these fields for audit links, QA, and source-aware downstream routing.

#### Example: Listing Record

```json
{
  "record_type": "property_listing",
  "record_id": "7045172",
  "source_context": {
    "source_id": "aqarmap_property_scraper",
    "source": "aqarmap",
    "source_domain": "aqarmap.com.eg",
    "source_url": "https://aqarmap.com.eg/en/listing/7045172-for-sale-cairo-new-cairo-example/",
    "canonical_url": "https://aqarmap.com.eg/en/listing/7045172-for-sale-cairo-new-cairo-example/",
    "position": 1,
    "country": "Egypt",
    "language": "english"
  },
  "entity": {
    "title": "Apartment 1 in New Cairo with balcony and security",
    "description": "Enriched listing description with payment plan, delivery timing, amenities, and neighborhood context.",
    "url": "https://aqarmap.com.eg/en/listing/7045172-for-sale-cairo-new-cairo-example/",
    "external_ids": {
      "listing_id": "7045172"
    },
    "status": "active"
  },
  "location": {
    "address": "Greater Cairo / New Cairo - 5th Settlement / New Narges",
    "city": "New Cairo",
    "region": "Greater Cairo",
    "neighborhood": "New Narges",
    "country": "Egypt",
    "latitude": 30.02,
    "longitude": 31.21
  },
  "pricing": {
    "price": 4750000,
    "price_text": "4750000",
    "currency": "EGP",
    "original_price": 4875000,
    "price_per_area": 43181.82,
    "fees": {
      "maintenance_text": "Included when available"
    }
  },
  "property": {
    "property_id": "7045172",
    "property_type": "apartment",
    "bedrooms": 2,
    "bathrooms": 1,
    "floor_area": 110,
    "area_unit": "sqm",
    "features": [
      "Balcony",
      "Security",
      "Elevator",
      "Private Garden"
    ],
    "floor": 1,
    "finishing": "Super Lux"
  },
  "listing": {
    "listing_id": "7045172",
    "deal_type": "buy",
    "enrichment_status": "enriched",
    "published_text": "Recently listed"
  },
  "media": {
    "main_image_url": "https://img-2.aqarmap.com.eg/new-aqarmap-media/search-thumb/7045172-main.jpg",
    "image_urls": [
      "https://img-2.aqarmap.com.eg/new-aqarmap-media/search-thumb/7045172-main.jpg",
      "https://img-2.aqarmap.com.eg/new-aqarmap-media/search-thumb/7045172-living.jpg",
      "https://img-2.aqarmap.com.eg/new-aqarmap-media/search-thumb/7045172-balcony.jpg"
    ]
  },
  "contact_details": {
    "phones": [
      "01000000000"
    ]
  },
  "relationships": {
    "agent": {
      "name": "Owner contact"
    },
    "agency": {
      "name": "Example Brokerage"
    },
    "developer": {
      "name": "Example Developer"
    }
  },
  "attributes": {
    "detail_attributes": {
      "Delivery": "Ready to move",
      "Payment Method": "Cash or installments",
      "View": "Garden view",
      "Compound": "Inside compound"
    },
    "raw_attributes": {
      "source_badge": "Featured"
    }
  }
}
```

### Field Reference

#### Record Envelope

- **record\_type** *(string, required)*: Normalized record family. Aqarmap listing rows use `property_listing`.
- **record\_id** *(string, optional)*: Stable listing identifier when available. Use it for matching, deduplication, and upserts.

#### source\_context

- **source\_context.source\_id** *(string, optional)*: Source identifier that produced the record.
- **source\_context.source** *(string, optional)*: Short source name, usually `aqarmap`.
- **source\_context.source\_domain** *(string, optional)*: Public source domain associated with the listing.
- **source\_context.source\_url** *(string, optional)*: Source URL used for listing review or audit workflows.
- **source\_context.canonical\_url** *(string, optional)*: Canonical listing URL when available.
- **source\_context.position** *(integer, optional)*: Result position assigned within the parsed listing set.
- **source\_context.country** *(string, optional)*: Country associated with the listing.
- **source\_context.language** *(string, optional)*: Requested or inferred page language, such as `english` or `arabic`.

#### entity

- **entity.title** *(string, optional)*: Listing title or display name.
- **entity.description** *(string, optional)*: Longer listing description when available.
- **entity.url** *(string, optional)*: Public Aqarmap listing URL.
- **entity.external\_ids.listing\_id** *(string, optional)*: Source listing ID.
- **entity.status** *(string, optional)*: Listing status label when available.

#### location

- **location.address** *(string, optional)*: Source-provided location text or area path.
- **location.city** *(string, optional)*: City-level location when available.
- **location.region** *(string, optional)*: Region or market area when available.
- **location.neighborhood** *(string, optional)*: Neighborhood or local area when available.
- **location.country** *(string, optional)*: Listing country.
- **location.latitude** *(number, optional)*: Latitude when valid coordinates are available.
- **location.longitude** *(number, optional)*: Longitude when valid coordinates are available.

#### pricing

- **pricing.price** *(number, optional)*: Numeric listing price when parseable.
- **pricing.price\_text** *(string, optional)*: Source price text after cleanup.
- **pricing.currency** *(string, optional)*: Currency code, commonly `EGP`.
- **pricing.original\_price** *(number, optional)*: Original price when the source exposes it.
- **pricing.price\_per\_area** *(number, optional)*: Price divided by area when available.
- **pricing.fees.maintenance\_text** *(string, optional)*: Maintenance or fee text when available.

#### property

- **property.property\_id** *(string, optional)*: Property-level identifier when available.
- **property.property\_type** *(string, optional)*: Normalized property category.
- **property.bedrooms** *(number, optional)*: Bedroom count.
- **property.bathrooms** *(number, optional)*: Bathroom count.
- **property.floor\_area** *(number, optional)*: Property area value.
- **property.area\_unit** *(string, optional)*: Area unit, usually `sqm`.
- **property.features** *(array of strings, optional)*: Feature or amenity labels.
- **property.floor** *(number, optional)*: Floor number when available.
- **property.finishing** *(string, optional)*: Finishing quality label when available.

#### listing

- **listing.listing\_id** *(string, optional)*: Aqarmap listing identifier.
- **listing.deal\_type** *(string, optional)*: Listing mode, such as `buy` or `rent`.
- **listing.enrichment\_status** *(string, optional)*: Indicates whether richer listing details were added.
- **listing.published\_text** *(string, optional)*: Source publication timing text when available.

#### media

- **media.main\_image\_url** *(string, optional)*: Primary listing image URL.
- **media.image\_urls** *(array of strings, optional)*: Image URLs associated with the listing.

#### contact\_details

- **contact\_details.phones** *(array of strings, optional)*: Public phone strings associated with the listing contact when available.

#### relationships

- **relationships.agent.name** *(string, optional)*: Visible agent or contact name.
- **relationships.agency.name** *(string, optional)*: Agency or brokerage name.
- **relationships.developer.name** *(string, optional)*: Developer name when available.

#### attributes

- **attributes.detail\_attributes** *(object, optional)*: Source-specific key-value property facts such as delivery, payment method, view, or compound labels.
- **attributes.raw\_attributes** *(object, optional)*: Additional meaningful source attributes preserved for review or source-specific downstream use.

### Data Model Notes

- **Identity fields:** use `record_id` as the primary matching key when present. Use `entity.url` or `source_context.canonical_url` as fallback identifiers.
- **Source and provenance fields:** use `source_context.source_domain`, `source_context.source_url`, and `source_context.canonical_url` to trace a record back to its public source.
- **Business attributes:** `pricing`, `property`, `location`, `listing`, `relationships`, and `contact_details` carry the main operational value for real-estate workflows.
- **Nested objects:** related values are grouped to reduce top-level field sprawl and make JSON-first ETL, review, and AI usage easier.
- **Optional fields:** detail-rich values such as coordinates, contact details, media, floor, finishing, related parties, and raw attributes depend on what each listing publicly provides.
- **Repeated runs:** compare records across runs with stable identifiers plus Apify run metadata, saved input configuration, and run date stored alongside your exports.

### Data Quality, Guarantees, And Handling

- **Structured records:** results are normalized into predictable JSON objects for downstream use.
- **Best-effort extraction:** fields may vary by region, availability, account visibility, UI experiments, or source-side changes.
- **Optional fields:** null-check optional values in downstream code, dashboards, and agent workflows.
- **Deduplication:** use `record_id` when present, with `entity.url` or `source_context.canonical_url` as a fallback.
- **Freshness:** results reflect the publicly available data at run time.
- **Repeated runs:** use the recommended idempotency key when syncing data into warehouses, CRMs, search indexes, vector stores, or monitoring systems.
- **Schema awareness:** downstream systems should rely on documented fields and handle newly missing optional fields gracefully.

### Tips For Best Results

- Start with a small `limit` to validate the output shape before scaling up.
- Use one location, property category, deal type, or price band per run when you need cleaner comparison.
- Leave optional filters empty when the goal is broad discovery.
- Add filters gradually to understand how each field changes coverage.
- Enable `enrich_data` when descriptions, media, contact values, and related party fields matter.
- Schedule recurring runs for monitoring workflows instead of relying on manual one-off exports.
- Use stable identifiers for deduplication when storing results over time.
- Keep a saved copy of the input configuration used for each recurring workflow.

### How to Run on Apify

1. Open the Actor in Apify Console.
2. Configure the available input fields for the target scope.
3. Set `limit` to control the maximum number of output records.
4. Click **Start** and wait for the run to finish.
5. Open the dataset and inspect the first records.
6. Download results in JSON, CSV, Excel, or another supported format.

### Agentic And API-First Usage

Aqarmap Scraper can be used as a structured data acquisition step inside larger automated workflows. Agents and workflow builders can select a scoped input, run the actor, read the dataset, validate records against the field reference, and route listings into enrichment, alerting, review, or storage systems.

Agent workflow pattern:

1. Generate or select a scoped input from the supported schema.
2. Run the actor manually, on a schedule, or through Apify platform automation.
3. Wait for completion and read the dataset records.
4. Validate records against the field reference.
5. Upsert records into the downstream system using the recommended idempotency key.
6. Trigger analysis, enrichment, alerts, or human review.

Practical notes for agentic use:

- Keep prompts and automations grounded in the documented input parameters.
- Start with small validation runs before allowing broad automated collection.
- Feed the Field Reference and a small output sample to downstream AI steps.
- Treat optional fields as nullable instead of asking agents to infer missing values.
- Store run ID, input configuration, and dataset export metadata outside the record when building audit trails.

### Scheduling & Automation

#### Scheduling

**Automated Data Collection**

Schedule runs to keep market snapshots current for dashboards, alerts, review queues, and recurring downstream syncs. Use the same input configuration for comparable monitoring, or create separate schedules for different locations, property types, and price bands.

- Navigate to **Schedules** in Apify Console.
- Create a new schedule, such as daily, weekly, or a custom cron interval.
- Configure input parameters.
- Enable notifications for run completion.
- Add webhooks for automated processing.

#### Integration Options

- **CRM enrichment:** sync public listing identifiers, contact values, related parties, property attributes, and source links into lead or account records.
- **BI dashboards:** monitor pricing, property types, locations, availability snapshots, and optional field coverage over time.
- **Warehouses and lakehouses:** store normalized property listing records for historical analysis, segmentation, and change detection.
- **Google Sheets or Airtable:** review smaller validation runs, QA samples, and market snapshots with non-technical stakeholders.
- **Webhooks:** trigger ingestion, notifications, validation checks, or enrichment workflows after each completed run.
- **Alerts and scheduled reporting:** notify teams when new listings, changed prices, populated contact fields, or selected property segments appear.
- **Search or vector indexes:** index titles, descriptions, locations, attributes, and source links for discovery, retrieval, and AI-agent context.

### Export Formats And Downstream Use

- **JSON:** for APIs, applications, AI agents, and data pipelines that preserve nested objects.
- **CSV or Excel:** for spreadsheet workflows, stakeholder review, lightweight analysis, and manual QA.
- **API access:** for automated ingestion into internal systems and workflow platforms.
- **BI and warehouses:** for reporting, dashboards, historical analysis, market segmentation, and monitoring.
- **Search or vector indexes:** for listing discovery, semantic search, retrieval workflows, and agent context.

### Downstream Pipeline Guide

- **Idempotency:** use `record_id` for upserts when available, with `entity.url` or `source_context.canonical_url` as a fallback.
- **Null handling:** treat optional fields such as `location.latitude`, `location.longitude`, `contact_details.phones`, `relationships.agency.name`, and `media.image_urls` as nullable.
- **Type handling:** preserve numbers, booleans, arrays, and nested objects when exporting to JSON-first systems.
- **Flattening:** if exporting to CSV or Excel, flatten nested objects deliberately and keep the original JSON export for full fidelity.
- **Partitioning:** store run date, input segment, location, property category, deal type, or workflow name outside or alongside records for easier analysis.
- **Change detection:** compare repeated runs by stable key and selected business fields such as `pricing.price`, `entity.status`, `listing.published_text`, `property.features`, or `media.image_urls`.
- **Quality checks:** monitor record count, duplicate rate, required identifiers, source URL availability, coordinate fill rate, contact fill rate, and media fill rate.
- **Human review:** route records with missing critical fields, unusual price values, changed status, or newly populated contact details into a review queue when needed.
- **Retention:** decide how long to keep raw exports versus normalized warehouse tables based on your reporting, audit, and enrichment needs.

### Performance

Estimated run times:

- **Small runs (< 1,000 outputs):** ~3-5 minutes.
- **Medium runs (1,000-5,000 outputs):** ~5-15 minutes.
- **Large runs (5,000+ outputs):** ~15-30 minutes.

Execution time varies based on filters, result volume, target availability, and how much information is returned per record. Highly filtered runs can finish faster, while broad discovery or detail-rich records may take longer.

### Limitations

- Availability depends on what `https://aqarmap.com.eg` publicly exposes at run time.
- Some optional fields may be missing on sparse listings or in faster non-enriched runs.
- Very broad searches may take longer or require higher limits.
- Target-side changes can affect field availability, labels, or naming.
- Regional, account, visibility, or availability differences may change visible results.
- The actor provides structured public data, not business advice, legal advice, valuation advice, or guaranteed completeness.
- Contact details are included only when they are publicly available in the collected listing context.

### Troubleshooting

- **No results returned:** check filters, location spelling, property category, listing mode, and whether Aqarmap has matching public records.
- **Fewer results than expected:** broaden filters, raise `limit`, or verify that the target segment contains enough matching public listings.
- **Some fields are empty:** optional fields depend on what each listing publicly provides and whether enrichment is enabled.
- **Duplicate-looking records:** compare `record_id`, `entity.url`, and `source_context.canonical_url` to decide whether records represent the same listing or related variants.
- **Run takes longer than expected:** reduce scope, lower `limit` for validation, or split broad collection into smaller segments.
- **Output changed:** compare the current output with the Field Reference and include a small sample if support is needed.
- **Downstream import failed:** check JSON validity, nullable fields, nested objects, and whether your destination expects flattened columns.

### FAQ

#### What data does this actor collect?

It collects public Aqarmap property listing records, including listing identity, source links, title, description, location, pricing, property attributes, media, contact details when available, related parties, and additional source-specific attributes.

#### Can I filter by location, category, price, keyword, amenities, or listing mode?

Yes. Supported inputs include `location`, `keyword`, `deal_type`, `property_type`, `min_price`, `max_price`, `min_area`, `max_area`, `amenities`, and `inside_compound`.

#### Is location required?

No. Provide `location` for a targeted market search, or leave it empty for a broader category search.

#### Why did I receive fewer results than my limit?

The selected filters may have fewer matching public listings than the requested limit, or some records may not expose enough usable information to save.

#### How should I choose a limit for my first run?

Start with a small `limit`, such as 10 or 25, inspect the dataset, then increase the value once the output shape and field coverage match your workflow.

#### Can I schedule recurring runs?

Yes. Use Apify schedules to run the same input daily, weekly, or on a custom cadence for monitoring and reporting.

#### How do I avoid duplicates across runs?

Use `record_id` when present. If it is unavailable, use `entity.url` or `source_context.canonical_url` as the fallback key.

#### What is the best field to use as a unique key?

The strongest key is `record_id` for listing records. For extra safety, combine it with `source_context.source_domain`.

#### Can I use the output with AI agents or automated workflows?

Yes. The dataset is structured JSON with stable field groups, making it suitable for agentic research, summarization, enrichment, alerting, and downstream routing.

#### Can I export the data to CSV, Excel, or JSON?

Yes. Apify datasets can be exported in JSON, CSV, Excel, and other supported formats.

#### Does this actor collect private data?

The actor is intended for publicly available Aqarmap listing information. Users are responsible for using collected data in accordance with applicable laws, regulations, and platform terms.

#### What should I include when reporting an issue?

Include the input used, run ID, expected behavior, actual behavior, a small output sample if helpful, and the downstream destination or export format if the issue is pipeline-related.

### Compliance & Ethics

#### Responsible Data Collection

This actor collects publicly available property listing information from `https://aqarmap.com.eg` for legitimate business purposes, including:

- **Real-estate** research and market analysis.
- **Inventory monitoring** and operational reporting.
- **Lead review, enrichment, and competitive intelligence** workflows.

This section is informational and not legal advice.

#### Best Practices

- Use collected data in accordance with applicable laws, regulations, and the target site’s terms.
- Respect individual privacy and personal information.
- Use data responsibly and avoid disruptive or excessive collection.
- Do not use this actor for spamming, harassment, discrimination, or other harmful purposes.
- Follow relevant data protection requirements where applicable, such as GDPR, CCPA, or sector-specific rules.
- Review your own retention, access control, and data-sharing policies before operationalizing the dataset.

### Support

For help, use the Issues tab or the actor page support options. Include the redacted input used, run ID, expected versus actual behavior, a small output sample if relevant, and the downstream destination or export format if the issue is pipeline-related.

# Actor input Schema

## `deal_type` (type: `string`):

Choose whether to collect properties listed for sale or properties listed for rent. Keeping sale and rental runs separate makes monitoring, pricing analysis, and downstream comparison cleaner.

## `language` (type: `string`):

Select whether Aqarmap pages should be requested in English or Arabic. Use one language consistently for recurring workflows when downstream comparison matters.

## `property_type` (type: `string`):

Choose the property family to include. Keep the default for broad discovery across supported property types, or choose a category such as apartments, villas, chalets, or commercial listings for cleaner segmentation.

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

Enter an Aqarmap market phrase such as great cairo, new cairo, or sheikh zayed to focus the run on a territory. Leave empty for a broader category search across Aqarmap.

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

Optional free-text term for project names, features, neighborhoods, or other search intent. Use it when a phrase should narrow the result set beyond category and location filters.

## `min_price` (type: `integer`):

Optional lower price bound in EGP. Use it to remove listings below the target budget, investment, or qualification range.

## `max_price` (type: `integer`):

Optional upper price bound in EGP. Use it to keep exports focused on a practical affordability, acquisition, or monitoring band.

## `min_area` (type: `integer`):

Optional minimum unit size in square meters. Use it with maximum area when comparing similarly sized properties.

## `max_area` (type: `integer`):

Optional maximum unit size in square meters. Use it to keep results within a practical size band for valuation, monitoring, or ETL imports.

## `amenities` (type: `array`):

Optional amenities that listings should include. More selected amenities usually produce a narrower, more targeted dataset for lead review, inventory refreshes, or compound-focused analysis.

## `inside_compound` (type: `boolean`):

Enable this when the run should focus on listings inside compounds for community comparisons, premium inventory review, or compound-level monitoring.

## `enrich_data` (type: `boolean`):

Enable this for more complete property listing records, including richer descriptions, photos, features, contact values, and related party details when available. Turn it off for faster validation runs when standard listing fields are enough.

## `limit` (type: `integer`):

Choose the maximum number of property listing records to save. Start with a small value for validation, then increase it once the selected filters and output shape match your workflow.

## Actor input object example

```json
{
  "deal_type": "buy",
  "language": "english",
  "property_type": "property-type",
  "location": "great cairo",
  "amenities": [],
  "inside_compound": false,
  "enrich_data": true,
  "limit": 100
}
```

# Actor output Schema

## `results` (type: `string`):

Structured Aqarmap property listing records saved by this run.

## `resultsMap` (type: `string`):

Standalone HTML map built from saved property listings with valid coordinates.

# 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 = {
    "deal_type": "buy",
    "language": "english",
    "property_type": "property-type",
    "location": "great cairo",
    "keyword": "",
    "limit": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("fatihtahta/aqarmap-property-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 = {
    "deal_type": "buy",
    "language": "english",
    "property_type": "property-type",
    "location": "great cairo",
    "keyword": "",
    "limit": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("fatihtahta/aqarmap-property-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 '{
  "deal_type": "buy",
  "language": "english",
  "property_type": "property-type",
  "location": "great cairo",
  "keyword": "",
  "limit": 100
}' |
apify call fatihtahta/aqarmap-property-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Aqarmap Scraper with Contacts & Description",
        "description": "Extract Aqarmap property listings across Egypt with rich property detail, contact data, pricing, media, developers, and flexible market filters. Built for enterprise-grade Egypt real estate intelligence, lead enrichment, inventory monitoring, and automated analytics pipelines.",
        "version": "0.1",
        "x-build-id": "t2qbpqKf4CotOgRha"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/fatihtahta~aqarmap-property-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-fatihtahta-aqarmap-property-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/fatihtahta~aqarmap-property-scraper/runs": {
            "post": {
                "operationId": "runs-sync-fatihtahta-aqarmap-property-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/fatihtahta~aqarmap-property-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-fatihtahta-aqarmap-property-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": {
                    "deal_type": {
                        "title": "Choose Deal Type",
                        "enum": [
                            "buy",
                            "rent"
                        ],
                        "type": "string",
                        "description": "Choose whether to collect properties listed for sale or properties listed for rent. Keeping sale and rental runs separate makes monitoring, pricing analysis, and downstream comparison cleaner.",
                        "default": "buy"
                    },
                    "language": {
                        "title": "Choose Result Language",
                        "enum": [
                            "english",
                            "arabic"
                        ],
                        "type": "string",
                        "description": "Select whether Aqarmap pages should be requested in English or Arabic. Use one language consistently for recurring workflows when downstream comparison matters.",
                        "default": "english"
                    },
                    "property_type": {
                        "title": "Choose Property Category",
                        "enum": [
                            "property-type",
                            "apartment",
                            "furnished-apartment",
                            "chalet",
                            "villa",
                            "land-or-farm",
                            "building",
                            "commercial",
                            "administrative",
                            "medical",
                            "land-or-commercial"
                        ],
                        "type": "string",
                        "description": "Choose the property family to include. Keep the default for broad discovery across supported property types, or choose a category such as apartments, villas, chalets, or commercial listings for cleaner segmentation.",
                        "default": "property-type"
                    },
                    "location": {
                        "title": "Set Optional Market Location",
                        "type": "string",
                        "description": "Enter an Aqarmap market phrase such as great cairo, new cairo, or sheikh zayed to focus the run on a territory. Leave empty for a broader category search across Aqarmap."
                    },
                    "keyword": {
                        "title": "Add Keyword Search Text",
                        "type": "string",
                        "description": "Optional free-text term for project names, features, neighborhoods, or other search intent. Use it when a phrase should narrow the result set beyond category and location filters."
                    },
                    "min_price": {
                        "title": "Set Minimum Price",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Optional lower price bound in EGP. Use it to remove listings below the target budget, investment, or qualification range."
                    },
                    "max_price": {
                        "title": "Set Maximum Price",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Optional upper price bound in EGP. Use it to keep exports focused on a practical affordability, acquisition, or monitoring band."
                    },
                    "min_area": {
                        "title": "Set Minimum Area",
                        "minimum": 10,
                        "type": "integer",
                        "description": "Optional minimum unit size in square meters. Use it with maximum area when comparing similarly sized properties."
                    },
                    "max_area": {
                        "title": "Set Maximum Area",
                        "minimum": 10,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Optional maximum unit size in square meters. Use it to keep results within a practical size band for valuation, monitoring, or ETL imports."
                    },
                    "amenities": {
                        "title": "Select Required Amenities",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Optional amenities that listings should include. More selected amenities usually produce a narrower, more targeted dataset for lead review, inventory refreshes, or compound-focused analysis.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "balcony",
                                "security",
                                "elevator",
                                "maid_room",
                                "water_meter",
                                "pets_allowed",
                                "landline_phone",
                                "swimming_pool",
                                "private_garden",
                                "kids_play_area",
                                "air_conditioning",
                                "covered_parking",
                                "electricity_meter",
                                "natural_gas_meter",
                                "kitchen_appliances"
                            ],
                            "enumTitles": [
                                "Balcony",
                                "Security",
                                "Elevator",
                                "Maid Room",
                                "Water Meter",
                                "Pets Allowed",
                                "Landline Phone",
                                "Swimming Pool",
                                "Private Garden",
                                "Kids Play Area",
                                "Air Conditioning",
                                "Covered Parking",
                                "Electricity Meter",
                                "Natural Gas Meter",
                                "Kitchen Appliances"
                            ]
                        },
                        "default": []
                    },
                    "inside_compound": {
                        "title": "Require Inside Compound",
                        "type": "boolean",
                        "description": "Enable this when the run should focus on listings inside compounds for community comparisons, premium inventory review, or compound-level monitoring.",
                        "default": false
                    },
                    "enrich_data": {
                        "title": "Collect Richer Listing Details",
                        "type": "boolean",
                        "description": "Enable this for more complete property listing records, including richer descriptions, photos, features, contact values, and related party details when available. Turn it off for faster validation runs when standard listing fields are enough.",
                        "default": true
                    },
                    "limit": {
                        "title": "Set Maximum Records",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Choose the maximum number of property listing records to save. Start with a small value for validation, then increase it once the selected filters and output shape match your workflow."
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
