# 99acres City & BHK Property Listing Scraper (`dataspryva/99acres-city-and-bhk-property-listing-scraper`) Actor

Search 99acres by city, BHK size, property type, locality, and price range to get structured buy and rent listings across 25 major Indian cities, with price, area, location, and poster details.

- **URL**: https://apify.com/dataspryva/99acres-city-and-bhk-property-listing-scraper.md
- **Developed by:** [Dataspryva](https://apify.com/dataspryva) (community)
- **Categories:** Real estate, E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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

## 99acres City & BHK Property Listing Scraper

Pull live 99acres sale and rent listings for a city, BHK size, property type, locality, and price band. Every row is a structured property record with the asking price, area, seller details, photos, amenity IDs, floor, furnishing, and map coordinates — plus optional new-launch project cards.

### What this actor does

- Searches 99acres for **sale or rent** across 25 Indian cities, from Delhi and Mumbai to Noida, Pune, Bangalore, Gurugram, and Kochi.
- Filters by **BHK, residential property type, locality, furnishing, and price**. Localities are resolved to 99acres' own location IDs, so names like `Sector 43` work instead of silently returning the whole city.
- Returns **one row per listing** with title, price text and numeric INR value, area in square feet and square metres, BHK, bathrooms, property type, locality, city, project/society, seller name and type, posted date, images, video, amenity IDs, floor, furnishing, availability, coordinates, and RERA registration flags.
- Adds **new-launch project cards** when `includeProjects` is on; each project row has its builder, price range, configurations, construction status where the card shows it, possession, photos, and project URL. Listings are collected first; project cards are appended only up to 20% of `maxItems`, so they never crowd out individual listings.
- Accepts **pasted 99acres search URLs** for filters configured on the site, and supports 99acres' date-descending (recently updated) sort.
- Omits fields 99acres does not show for a listing instead of writing `null` or a placeholder.

### Output per property

- `propertyId`, `propId` — 99acres listing identifiers
- `title`, `propertyType`, `bedrooms`, `bathrooms`, `balconies`
- `price` (as displayed), `priceValue`, `priceMaxValue`, `pricePerSqft`
- `area` (as displayed), `areaSqft`, `areaSqm`, `areaType`
- `city`, `locality`, `projectName`
- `postedBy`, `sellerName`, `sellerCompany`, `sellerType`
- `postedAt`, `updatedAt`, `availability`, `statusTags`
- `furnishing`, `floor`, `totalFloors`, `facing`
- `description`, `images[]`, `imageCount`, `videoUrl`
- `amenityIds[]`
- `latitude`, `longitude`
- `reraRegistered`, `reraDealerRegistered`
- `transactionType`, `dealType`
- `propertyUrl`, `sourceUrl`
- `recordType: "property"`, `scrapedAt`

With `includeDetails: true`, property rows also include: `reraNumber`, `dealerReraNumber`, `amenities[]` (labels), `carpetAreaSqft`, `superBuiltupAreaSqft`, `floorLabel`, `furnishingDetails`, `flooring`, `ownership`, `ageLabel`, `deposit`, `priceNegotiable`, `powerBackup`, `waterSource`, `petFriendly`, `brokerage`, `availabilityText`, `availabilityDate`, `detailsEnriched`.

### Output per project (`includeProjects: true`)

`recordType: "project"`, `projectId`, `title`, `subtitle`, `builder`, `priceMin`, `priceMax`, `priceLabel`, `pricePerSqft`, `areaType`, `configurations[]` (`bhk`, `area`, `price`), `constructionStatus` (when shown), `possession`, `locality`, `city`, `latitude`, `longitude`, `images[]`, `imageCount`, `tags[]`, `description`, `projectUrl`, `isNewLaunch`, `reraTag`, `scrapedAt`.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `searchForSale` | `searchForSale` or `searchForRent` |
| `city` | string | `Delhi` | One of the 25 supported Indian cities |
| `propertyType` | string | `Residential Apartment` | Residential apartment, independent house, villa, plot, independent floor, studio, or farm house |
| `bedrooms` | string | any | `1`–`4` or `5+` BHK |
| `locality` | string | – | One locality name within the city |
| `localities` | array | – | Multiple locality names |
| `priceMin` | integer | – | Minimum price in INR |
| `priceMax` | integer | – | Maximum price in INR |
| `furnishing` | string | any | Furnished, unfurnished, or semi-furnished |
| `sortBy` | string | `relevance` | `relevance` or `newest` |
| `includeProjects` | boolean | `true` | Add new-launch project cards (they count toward `maxItems`; set `false` for listings only) |
| `searchUrls` | array | – | Full 99acres `/property-in-<city>-ffid?...` search URLs |
| `maxItems` | integer | `50` | Record cap, 1–1,000 |

#### Example: 2 BHK rentals in Noida

```json
{
  "mode": "searchForRent",
  "city": "Noida",
  "propertyType": "Residential Apartment",
  "bedrooms": "2",
  "maxItems": 30
}
```

#### Example: family homes in a locality

```json
{
  "mode": "searchForSale",
  "city": "Bangalore",
  "propertyType": "Independent House",
  "bedrooms": "3",
  "localities": ["HSR Layout", "Koramangala"],
  "priceMin": 10000000,
  "priceMax": 30000000,
  "maxItems": 50
}
```

#### Example: newest furnished rentals

```json
{
  "mode": "searchForRent",
  "city": "Pune",
  "bedrooms": "2",
  "furnishing": "Semi-furnished",
  "sortBy": "newest",
  "includeProjects": false,
  "maxItems": 40
}
```

#### Example: enrich property details

```json
{
  "mode": "searchForRent",
  "city": "Noida",
  "bedrooms": "2",
  "includeProjects": false,
  "includeDetails": true,
  "maxItems": 5
}
```

#### Example: reuse a search URL

```json
{
  "searchUrls": [
    "https://www.99acres.com/property-in-mumbai-ffid?preference=R&res_com=R&bedroom_num=2&page=1"
  ],
  "maxItems": 25
}
```

### Use cases

- **Market research** — compare asking prices and inventory across cities, BHK sizes, and localities.
- **Investment screening** — build a shortlist by price band, property type, and furnishing.
- **Rental tracking** — refresh a neighbourhood feed with current rents and new listings.
- **Lead sourcing** — collect public seller names, seller types, and active listing URLs.
- **PropTech feeds** — populate dashboards, comparison pages, or CRMs with clean listing records.
- **New-launch monitoring** — track project price ranges and possession dates alongside resale inventory.

### FAQ

**Do I need a 99acres login or cookies?**
No. The actor reads public search results and needs no account, cookie, or API key.

**Do I need to configure a proxy?**
No. The actor chooses a working connection to 99acres automatically. Just fill in the input and run it.

**Why are some fields missing from a record?**
99acres does not show every field for every listing. Missing values are omitted rather than sent as `null` or a placeholder.

**What does `includeDetails` add, and what does it cost?**
It fetches the individual property page for RERA numbers, amenity labels, carpet area, floor and furnishing details, and coordinates. Each property needs one extra residential request, so keep `maxItems` small when it is on.

**Why does a price filter sometimes take longer?**
99acres ignores price query parameters, so the actor applies your price range while it scans result pages. A narrow band may need more pages than a broad one.

**What is the difference between a property row and a project row?**
`recordType: "property"` is an individual resale or rental listing. `recordType: "project"` is a new-launch project card with a builder, price range, and unit configurations. Set `includeProjects` to `false` for listings only.

**Why do some localities return no rows?**
The actor resolves locality names from the city's own locality list, not from the filtered result page. A name can resolve correctly and still return no rows if that BHK, property type, furnishing, or price band has no listings there. The actor says so instead of returning the whole city.

**Why doesn't "Newest first" match the posted date?**
99acres' date sort is a **recently updated** order. Use `updatedAt` when you need to compare the sort order; `postedAt` is the original listing date.

**Does the actor support commercial property?**
This revision covers residential sale and rent. Commercial property types are not exposed yet.

**Is this actor affiliated with 99acres?**
No. This is an independent, third-party actor that reads 99acres' public search pages and is not operated by or affiliated with 99acres.com.

# Actor input Schema

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

Search properties for sale or for rent.

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

Indian city to search in.

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

Residential property type to search for.

## `bedrooms` (type: `string`):

Number of bedrooms. Choose '5+' for five or more.

## `locality` (type: `string`):

Optional locality or sector name within the city, e.g. 'Sector 43'. The actor looks up the 99acres locality ID.

## `localities` (type: `array`):

Optional list of locality names; each is resolved to a 99acres locality ID.

## `priceMin` (type: `integer`):

Minimum price in Indian Rupees. Applied while scanning pages because 99acres ignores price query parameters.

## `priceMax` (type: `integer`):

Maximum price in Indian Rupees. Applied while scanning pages because 99acres ignores price query parameters.

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

Filter by furnishing status.

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

Result order. 'Newest' is 99acres' recently-updated order (updatedAt), not the original posting date (postedAt).

## `includeProjects` (type: `boolean`):

Include new-launch project cards alongside individual listings. Project rows have recordType 'project'.

## `includeDetails` (type: `boolean`):

Fetch each property's detail page for RERA numbers, amenity labels, carpet area, floor, furnishing details, and coordinates. Off by default because it adds one residential request per property.

## `searchUrls` (type: `array`):

Optional 99acres search URLs: /property-in-<city>-ffid?... or /<n>-bhk-flats-in-<city>-ffid?... When provided, city and filter fields are ignored.

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

Maximum number of property and project records to return.

## Actor input object example

```json
{
  "mode": "searchForRent",
  "city": "Noida",
  "propertyType": "Residential Apartment",
  "bedrooms": "2",
  "furnishing": "",
  "sortBy": "relevance",
  "includeProjects": true,
  "includeDetails": false,
  "maxItems": 3
}
```

# Actor output Schema

## `properties` (type: `string`):

Dataset containing all scraped 99acres property and project records.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "searchForRent",
    "city": "Noida",
    "propertyType": "Residential Apartment",
    "bedrooms": "2",
    "furnishing": "",
    "sortBy": "relevance",
    "includeProjects": false,
    "includeDetails": false,
    "maxItems": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("dataspryva/99acres-city-and-bhk-property-listing-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "searchForRent",
    "city": "Noida",
    "propertyType": "Residential Apartment",
    "bedrooms": "2",
    "furnishing": "",
    "sortBy": "relevance",
    "includeProjects": False,
    "includeDetails": False,
    "maxItems": 3,
}

# Run the Actor and wait for it to finish
run = client.actor("dataspryva/99acres-city-and-bhk-property-listing-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 '{
  "mode": "searchForRent",
  "city": "Noida",
  "propertyType": "Residential Apartment",
  "bedrooms": "2",
  "furnishing": "",
  "sortBy": "relevance",
  "includeProjects": false,
  "includeDetails": false,
  "maxItems": 3
}' |
apify call dataspryva/99acres-city-and-bhk-property-listing-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dataspryva/99acres-city-and-bhk-property-listing-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/2TFMROZoJNU2eMqGS/builds/GfLPEtbM3CuOX9T6U/openapi.json
