Cian RU – Property Listings, Search Filters & URLs
Pricing
from $1.50 / 1,000 dataset items
Cian RU – Property Listings, Search Filters & URLs
Collect property listings from Cian.ru by search filters or direct URLs. Returns structured rows with listing URL, title, price, address, rooms, area, floors, photos, visible contact fields, coordinates when available, and optional detail-page enrichment.
Pricing
from $1.50 / 1,000 dataset items
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
16
Total users
5
Monthly active users
2 hours ago
Last modified
Categories
Share
Cian.ru Property Scraper
Collect property listings from Cian by search filters or direct URLs. Every row comes fully populated in a single fast pass: listing URL, title, price, address, rooms, area, floors, photos, coordinates, and contact phones.
Input
mode: choosesearchfor filters orurlfor pasted Cian URLs.urls: Cian search-result URLs, used in URL mode. The filters below are ignored in URL mode, so encode filters in the URL itself.
The next group applies to search mode only:
location/regionId: search area. Moscow is region1, Saint Petersburg is region2.operationType:saleorrent.category: flats, rooms, houses, new buildings, and commercial categories.sort: default, price low→high, price per m² (asc/desc), area, newest, or walking time.rooms,includeStudio: room-count filters (studio supported).minPrice/maxPrice(RUB),minArea/maxArea,minFloor/maxFloor,minFloors/maxFloors.advancedFilters: JSON object of raw Cian query fields for power users, e.g.{"repair":{"type":"terms","value":[2,3]}}.
Output and limits (both modes):
maxItems: maximum rows to save. Fewer can be returned when results or filters match fewer live records.maxPages: leave0for no page limit. The run stops at Max items.fetchDetails: load each saved listing's own detail page for richer fields not on the search card — agent/agency name, total view count, BTI-verified build year, renovation type, window view, balcony count, bathroom counts, parking type, and amenities. Off by default. Billed as a detail-enrichment surcharge, charged only for listings whose detail page was actually fetched successfully.proxy: residential proxy is recommended for this site.
Input parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| mcpConnectors | array | (empty) | Pipe results into your apps via Model Context Protocol (MCP) connectors (Notion, Linear, Airtable, Apify). Items sent as condensed summaries; complete records stay in the dataset. Leave empty to skip. |
| notionParentPageUrl | string | (empty) | Notion connector only: URL or id of the Notion page under which item pages are created. Required for the Notion connector; ignored by other connectors. |
| maxNotifyListings | integer | 50 | Cap on items written to each connector per run. Does not affect the dataset. |
Resume & recurring updates
resumeFromRunId: continue ONE interrupted crawl. Paste a previous run ID (or dataset ID) and this run skips listings it already saved, appending only new ones.incrementalMode: for recurring/scheduled monitoring of the SAME search instead — remembers the previous run's results itself (keyed by your filters/URLs) and reports each listing aschangeTypeNEW/UPDATED/REAPPEARED/EXPIRED/UNCHANGED. Off by default.stateKey: optional manual key for the incremental baseline. Leave empty to derive one automatically from your mode/filters/URLs (excludingmaxItems/maxPages), so identical searches share a baseline and different ones never mix.emitUnchanged: also save (and charge for) listings that did not change. Off by default, so a recurring run only pays for what actually changed.emitExpired: also save (and charge for) a row for previously-tracked listings no longer found, markedchangeType: "EXPIRED". Only fires after a run that scanned the full tracked search — a capped, resumed, or partially-blocked run leaves previous state untouched instead of guessing.
resumeFromRunId and incrementalMode can combine to bootstrap a monitoring baseline from an interrupted crawl's dataset, but not once that baseline already has tracked listings (set a different stateKey for a separate campaign instead).
Output
Each dataset row includes:
id,url,sourceUrl,title,jkNameprice,priceValue,pricePerMeter,currencyaddress,district,metro,metroTimeroomsCount,totalArea,livingArea,kitchenArea,floorNumber,floorsCount,buildYear,materialTypedealType,category,offerType,isFromDeveloper,isPremiumdescription,phoneNumberslatitude,longitudeimageUrls,creationDate,addedLabel,scrapedAt
When fetchDetails is on, a successfully enriched row also carries (and sets detailStatus to ok; a failed detail fetch still ships the base row with detailStatus: "skipped" and no extra fields, at no extra charge):
agentName,agentCompanyName,agentType,agentIsPro,agentOffersCount,agentAvatarUrlviewsTotal,viewsTodayhouseBuildYear(BTI-verified, often populated when the search card's ownbuildYearis null),houseEntrances,houseFlatCount,houseLiftsTotal,houseHeatSupplyType,houseGasSupplyType,houseIsEmergencyrepairType,windowsViewType,balconiesCount,bathroomsCombined,bathroomsSeparate,parkingType,amenities
Incremental mode adds, only when incrementalMode is on:
changeType:NEW/UPDATED/REAPPEARED/EXPIRED/UNCHANGED(the last only whenemitUnchangedis on).changedFields: which fields differ from the previous run (empty forNEW/UNCHANGED/REAPPEARED/EXPIRED).firstSeenAt,lastSeenAt: when this actor first and most recently observed the listing.
Incremental change detection ignores scrapedAt (this actor's own per-fetch timestamp) and addedLabel (cian's relative "added" label, e.g. "вчера, 14:40" — it shifts with scrape time and the day boundary independently of any real listing change). Both fields are still present in every row; they are just excluded from the change comparison itself. Every other field, including imageUrls and phoneNumbers, is measured live and stays part of the comparison.
Send results into your apps (MCP connectors)
Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape — the Apify dataset is never changed.
What gets written to the connector: a condensed, human-readable summary of each record — not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
- For Notion, also set
notionParentPageUrlto the page where items should be created.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Notes
Use broad filters first, then narrow by price, rooms, and area. Phones, coordinates, descriptions, and photos are included on every row for free — no detail step needed for those. fetchDetails is only for the extra fields listed above (agent identity, view count, verified build year, and building/unit registry details) and is billed as a detail-enrichment surcharge. Residential proxy is recommended.
Verification note (2026-08-31)
URL and search modes re-verified against the live site on 2026-08-31 using the actor's own session warm-up plus search API path: a pasted https://www.cian.ru/kupit-kvartiru/ URL had its embedded jsonQuery extracted and replayed through the search API, returning 28 real Moscow listings; filter facets narrow server-side (one-room flats: 361,680 site total, adding a max price of 10M RUB narrowed it to 287,140, and the API result set for one-room flats shared only 6 of 28 page-1 ids with the unfiltered set). No defect found; version bumped so the Store listing carries a freshly dated, re-verified build.