How to Scrape 99acres Property Listings and Prices
99acres is one of India's largest property portals, which makes it a rich public source of real estate data: price, size, configuration, locality, and listing details across sale and rent. This guide covers what a listing holds, where the data lives, the challenges of collecting it cleanly, and how to turn it into a monitoring feed. The worked example uses a real 99acres search.
What data a 99acres listing holds
A search results page carries a row per property, dense with detail. On a real search, one listing read: Hiranandani Meadows Celio, a 3 BHK, priced at 4.5 crore (45,000,000 rupees), with a super built-up area of 2,000 square feet, listed for sale, along with the city, locality, price per unit area, bathrooms, facing, floor, furnishing, and age. The price, size, configuration, and locality are the fields that matter, and the results page carries them all keyed to a property id.
Where the data actually lives
99acres serves its search results through an internal JSON API, for example 99acres.com/api-aggregator/srp/search, which returns a properties array where each object carries the price, area, bedroom and bathroom counts, locality, transaction type, and a property id. Reading that JSON is far cleaner than parsing the rendered cards, since it hands you every field as structured data, and the property id is the stable key you deduplicate on across runs.
Skip the build, get the feed
Send us your 99acres target and we will scrape a real sample and send it back, no signup.
Get a free sampleThe practical challenges
99acres varies what it serves by region and throttles automated access, so collection often needs the right location context and careful pacing. The same property can appear from multiple agents and owners, so deduplication matters. Prices mix crore and lakh formatting and per-unit figures, so normalising them into one number is part of the job. A scraper that works today can return blanks after an API or layout change, which is why monitoring and maintenance matter more than the first build.
Turning it into a monitoring feed
For property monitoring you want one row per property id, captured per city and locality, keeping the price, size, configuration, locality, and transaction type, refreshed on a schedule. Store each run with a date so you can track new listings and price changes over time, which is often the signal that matters more than a single snapshot of today's market.
Build it yourself or have it delivered
For one city, a careful script against the search API can get you a sample. At scale the location handling, the paging, the price normalisation, and the upkeep turn it into a standing maintenance job. A done-for-you feed is usually cheaper than the maintenance once you track more than a locality or two. You tell us the cities and localities, and we deliver a clean property feed keyed on the listing id and keep it running.
Where each field lives in the search JSON
99acres returns its results as a properties array, and knowing the keys is what makes a parse reliable. Each property object carries PROP_NAME and SOCIETY_NAME (the listing and society), PRICE (the display price, for example 4.5 Cr) alongside MIN_PRICE (the numeric value, 45,000,000), BEDROOM_NUM and BATHROOM_NUM (the configuration), the built-up area with its unit, PRICE_PER_UNIT_AREA, CITY and LOCALITY, TRANSACT_TYPE (sale or rent), FURNISH, FACING, AGE, and floor fields, all keyed to a PROP_ID. That PROP_ID is the stable key you deduplicate on across runs, and because the display price mixes crore and lakh formatting, normalising against MIN_PRICE rather than the display string is what keeps the numbers comparable.
Step by step: reading a 99acres search
99acres serves its search results from an internal JSON API, so the cleanest read is that response. Here it is on a real search, where each property came back as a structured object with price, size, and configuration.
import requests
# 99acres loads its search results from an internal JSON API.
url = "https://www.99acres.com/api-aggregator/srp/search"
params = {"city": "...", "property_type": "1"} # plus the site's own search params
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}
data = requests.get(url, params=params, headers=headers).json()
for p in data["properties"]:
print(p["PROP_NAME"], p["BEDROOM_NUM"], p["PRICE"], p["LOCALITY"])| Property | Hiranandani Meadows Celio |
|---|---|
| Configuration | 3 BHK |
| Price | Rs 4.5 Cr |
| Built-up area | 2,000 sq ft |
| Transaction | Sale |
A sample of the clean data we deliver for one product.
The response is clean and structured. The work is that 99acres varies what it serves by region and throttles automated access, the same property surfaces from multiple agents so you deduplicate on the property id, and crore, lakh, and per-unit prices need normalising into one number. Handling that at scale and keeping it working as the API changes is the real job. We run it and deliver a clean property feed keyed on the listing id.
Fields worth capturing from 99acres
- Property / society name
- Transaction type (sale / rent)
- Price
- Price per unit area
- Configuration (BHK)
- Built-up area
- Bathrooms
- City
- Locality
- Furnishing
- Facing
- Floor
- Property ID
Frequently asked questions
Related service: Catalog & Assortment Tracking
Want a 99acres feed without the build?
Send us the products or pages you need, and we will deliver a clean feed and maintain it. Start with a free sample.
Get a Free Sample