# Hepsiemlak Scraper - Turkey Property Listings & Prices (`sian.agency/hepsiemlak-property-scraper`) Actor

Scrape hepsiemlak.com across all 81 Turkish provinces: satılık and kiralık listings with price, m², room layout, building age, floor, district, agency and photos.

- **URL**: https://apify.com/sian.agency/hepsiemlak-property-scraper.md
- **Developed by:** [SIÁN OÜ](https://apify.com/sian.agency) (community)
- **Categories:** Real estate, Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.88 / 1,000 property searches

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Hepsiemlak Scraper - Turkey Property Listings & Prices 🇹🇷

[![Store SIÁN Agency](https://img.shields.io/badge/Store-SI%C3%81N%20Agency-1AE392)](https://apify.com/sian.agency?fpr=sian) [![Store Idealista](https://img.shields.io/badge/Store-Idealista-E60023)](https://apify.com/sian.agency/smart-idealista-scraper?fpr=sian) [![Store Bayut](https://img.shields.io/badge/Store-Bayut-93D500)](https://apify.com/sian.agency/bayut-property-scraper?fpr=sian) [![Store Zillow](https://img.shields.io/badge/Store-Zillow-1F4E79)](https://apify.com/sian.agency/zillow-property-scraper?fpr=sian)

#### 🎉 All 81 Turkish provinces, satılık and kiralık, ~23 listings per request

##### For analysts pricing the Turkish market, agencies building lead lists, and anyone tired of paging through hepsiemlak by hand

***

### 🔎 What is the Hepsiemlak Turkey Property Scraper — and when should you use it?

The **Hepsiemlak Turkey Property Scraper** turns public hepsiemlak.com property listings across all 81 Turkish provinces, for sale and to rent into clean, structured rows you can filter, export and feed straight into a spreadsheet, database or AI agent. No account, no portal API key, no browser automation to maintain.

**Use it when you need:** Turkish sale and rental listings as rows. Each carries the asking price in lira, gross area in square metres, the room layout in the Turkish notation (3+1 is three bedrooms and one living room), building age, floor, and the province, district and neighbourhood. Every row also names the agency that listed it, and the individual agent where the listing has one. Ask for the full record on a listing and you additionally get map coordinates, the complete advert text, every photo and the amenity list. It also carries the heating type, the bathroom count, the condition and occupancy status, and the agency's phone numbers. On a rental it adds the deposit the landlord is asking, which is the figure most yield models are missing. Coverage is all 81 provinces plus the Northern Cyprus section, read from the portal's own province list. İstanbul alone reported 31,718 listings for sale over 1,305 pages when it was measured.

**Use something else when:** the property is not in Türkiye. Use [Idealista Scraper](https://apify.com/sian.agency/smart-idealista-scraper?fpr=sian) for Spain, Italy and Portugal, sale and rental, from the region's largest portal. Use [Bayut Scraper](https://apify.com/sian.agency/bayut-property-scraper?fpr=sian) for the Gulf — the UAE, Saudi Arabia, Egypt, Bahrain and Qatar. Use [Zillow Scraper](https://apify.com/sian.agency/zillow-property-scraper?fpr=sian) for the United States, with market KPIs alongside the listings. This actor reads hepsiemlak.com and nothing else. It covers the six markets the portal publishes — for sale, to rent, seasonal rental, business transfer either way, and land-for-flat — across housing, commercial premises, land, timeshare and tourism businesses. It reads what the portal serves a visitor, so asking prices only: there is no sold-price history to return, because the portal does not publish one. Coordinates, the amenity list and agency phone numbers come from the listing page rather than the results page, so they arrive through the lookup mode and are honestly empty on a search row rather than filled for some searches and blank for others. A listing cannot be fetched by its number alone, because the portal has no lookup-by-number route and a listing's address encodes its province, district and property type.

### 🤖 Use with AI agents

Already connected to the [Apify MCP server](https://mcp.apify.com)? Just ask for this Actor by name: sian.agency/hepsiemlak-property-scraper

**Your agent can pay for its own runs.** This Actor is eligible for [agentic payments](https://docs.apify.com/platform/actors/publishing/monetize), so an agent can discover it, run it and settle the bill over [x402](https://www.x402.org/) (USDC on Base) or [Skyfire](https://www.skyfire.xyz/) — without an Apify account or API token of its own. Billing is the same either way: per successful row, never for errors.

Otherwise copy this prompt into Claude, ChatGPT, Cursor or any MCP-enabled assistant:

```text
I want Turkish property listings and asking prices from hepsiemlak.com using the Apify Actor `sian.agency/hepsiemlak-property-scraper`.

Use it when I need: Turkish sale and rental listings as rows. Each carries the asking price in lira, gross area in square metres, the room layout in the Turkish notation (3+1 is three bedrooms and one living room), building age, floor, and the province, district and neighbourhood. Every row also names the agency that listed it, and the individual agent where the listing has one. Ask for the full record on a listing and you additionally get map coordinates, the complete advert text, every photo and the amenity list. It also carries the heating type, the bathroom count, the condition and occupancy status, and the agency's phone numbers. On a rental it adds the deposit the landlord is asking, which is the figure most yield models are missing. Coverage is all 81 provinces plus the Northern Cyprus section, read from the portal's own province list. İstanbul alone reported 31,718 listings for sale over 1,305 pages when it was measured.

Don't use it when: the property is not in Türkiye — use smart-idealista-scraper or bayut-property-scraper or zillow-property-scraper instead.

How to call it: set `province` to one of the 82 entries (`istanbul`, `ankara`, `izmir`, `antalya`, `bursa` and the rest, plus `kibris`) and `market` to `satilik` for sale or `kiralik` to rent — the four other markets (`sezonluk-kiralik`, `devren-satilik`, `devren-kiralik`, `kat-karsiligi-satilik`) are real but far thinner. Narrow to a single district by putting its portal slug in `district` (`kadikoy`, `besiktas`, `cankaya`, `konak`, `muratpasa`); on this portal a district is searched on its own, so `district` replaces `province` rather than nesting under it, and a slug the portal does not recognise returns its not-found page, which the run reports as a bad address rather than as an empty market. `propertyType` picks one of sixteen residential types (`daire`, `villa`, `mustakil-ev`, `residence`, `yazlik` …) and `roomLayout` one of the Turkish layouts (`studyo`, `1-1`, `2-1`, `3-1`, `4-1` …). `minPrice`, `maxPrice`, `minAreaSqm`, `maxAreaSqm` and `postedWithin` are handed to the portal itself, so listings outside the range are never fetched and never billed — set `postedWithin` to `today` on a daily schedule and you collect only new stock. `maxItems` sets the depth; listings arrive about 23 to a page. To reach a filter the pickers do not expose, build the search on hepsiemlak.com and paste the address into `searchUrls`, where it is used verbatim. Switch `operation` to `detail` with `listingUrls` only when you need coordinates, the amenity list or agency phone numbers for listings you already hold: it fetches one listing at a time and costs ten times a search row, so search is the right default.

Start with this input:
{
  "operation": "search",
  "province": "istanbul",
  "market": "satilik",
  "propertyType": "daire",
  "roomLayout": "3-1",
  "minPrice": 5000000,
  "maxPrice": 12000000,
  "maxItems": 200
}

Ask me which province and which market I want, and whether I have a price ceiling, then run the Actor and summarise the results as a table.
```

**Things you can ask your agent for:**

- *Pull every apartment to rent in Kadıköy and rank the neighbourhoods by price per square metre*
- *List the agencies with the most villas on the market in Muğla*
- *Compare what a 2+1 rents for in Çankaya against Konak this month*
- *Track price cuts on İstanbul apartments week over week using the listing id*

Machine-readable API, MCP config and OpenAPI definition for this Actor are published at [apify.com/sian.agency/hepsiemlak-property-scraper.md](https://apify.com/sian.agency/hepsiemlak-property-scraper.md).

### 📋 Overview

**Türkiye's property market moves in Turkish, on a portal built for browsing rather than analysis.** This actor reads it for you and hands back rows you can sort.

**What you get:**

- ✅ **Nationwide coverage**: all 81 provinces plus the Northern Cyprus section, taken from the portal's own province list rather than a translated map.
- ⚡ **~23 listings per request**: a page of results arrives whole, so a hundred listings is four requests rather than a hundred.
- 🎯 **Filters applied by the portal**: price, area and recency go into the search itself, so listings outside your range are never fetched and never billed.
- 💰 **$0.001 per listing**: half what the next Hepsiemlak actor on this Store charges, and a quarter of the other two.
- 💎 **Both markets, same fields**: satılık and kiralık return identical columns, so a for-sale run and a rental run join cleanly on district, layout and area.
- ✨ **Turkish handled properly**: room layouts, heating types and property types come back in the portal's own vocabulary, with the dotted and dotless i intact.

***

### ✨ Features

- 🏙️ **Province or district**: search all of İstanbul, or just Kadıköy.
- 🏷️ **Six markets**: for sale, to rent, seasonal rental, business transfer either way, and land-for-flat.
- 🏡 **Sixteen property types**: apartment, villa, detached house, residence, summer house, whole building and more.
- 🛏️ **Room-layout filter**: Stüdyo through 6+2, in the portal's own notation.
- 💰 **Price and area windows**: minimum and maximum, in lira and m².
- 🗓️ **Recency filter**: today, three days, a week, a fortnight, a month, two months. This is how you schedule the run without re-paying for stock you already hold.
- 🔗 **Paste your own search URL**: build any search on the site and hand the address over as-is.
- 🧭 **Coordinates and agency phones**: on the listing-lookup mode, for both markets.
- 📄 **Run report**: an HTML summary in the key-value store with the numbers, any failures and exactly what the run cost.

***

### 🎬 Quick Start

Pick a province, pick a market, press Start. The run pages through results until it reaches your listing limit or the market runs out, and everything lands in a dataset you can export as JSON, CSV or Excel.

```bash
curl -X POST "https://api.apify.com/v2/acts/sian.agency~hepsiemlak-property-scraper/runs?token=YOUR_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"operation":"search","province":"istanbul","market":"satilik","maxItems":100}'
```

***

### 🚀 Getting Started (3 Simple Steps)

#### Step 1: Choose where

Pick a province from the list, or type a district slug such as `kadikoy` or `cankaya` into the District field.

#### Step 2: Choose what

Pick the market — for sale or to rent — and, if you want to narrow it, a property type, a room layout, a price window or an area window.

#### Step 3: Press Start

Set Maximum listings to how many you want and run it.

**That's it. In a couple of minutes you'll have:**

- A flat row per listing with price, area, layout, age, floor and location
- The agency behind each listing
- A run report showing what came back and what it cost

***

### 📥 Input Configuration

| Field | Type | Required | Description |
|---|---|---|---|
| `operation` | string | No | `search` (default) or `detail` |
| `province` | string | No | Province slug, e.g. `istanbul`, `ankara`, `izmir`. Default `istanbul` |
| `district` | string | No | District slug, e.g. `kadikoy`. Replaces the province |
| `market` | string | No | `satilik`, `kiralik`, `sezonluk-kiralik`, `devren-satilik`, `devren-kiralik`, `kat-karsiligi-satilik` |
| `propertyType` | string | No | `any`, `daire`, `villa`, `mustakil-ev`, `residence` and eleven more |
| `roomLayout` | string | No | `any`, `studyo`, `1-1`, `2-1`, `3-1`, `4-1` … `6-2` |
| `minPrice` / `maxPrice` | integer | No | Lira. `0` means no bound |
| `minAreaSqm` / `maxAreaSqm` | integer | No | Gross m². `0` means no bound |
| `postedWithin` | string | No | `any`, `today`, `last-three-days`, `last-one-week`, `last-fifteen-days`, `last-one-month`, `last-two-months` |
| `maxItems` | integer | No | Stop after this many listings. Default 100 |
| `searchUrls` | array | No | Paste hepsiemlak search URLs; overrides the fields above |
| `listingUrls` | array | No | For `detail`: listing page URLs |

**Example — 3+1 apartments for sale in İstanbul between 5M and 12M lira:**

```json
{
  "operation": "search",
  "province": "istanbul",
  "market": "satilik",
  "propertyType": "daire",
  "roomLayout": "3-1",
  "minPrice": 5000000,
  "maxPrice": 12000000,
  "maxItems": 200
}
```

**Example — your own search URL, used exactly as given:**

```json
{
  "operation": "search",
  "searchUrls": ["https://www.hepsiemlak.com/ankara-satilik/villa?minPrice=10000000"],
  "maxItems": 100
}
```

**Example — full records for listings you already hold:**

```json
{
  "operation": "detail",
  "listingUrls": [
    "https://www.hepsiemlak.com/istanbul-esenyurt-mehmet-akif-ersoy-satilik/daire/142108-196"
  ]
}
```

***

### 📤 Output

Every listing is one flat row. A search row carries the results-page fields; a listing lookup adds the rest.

| Field | Type | Description |
|---|---|---|
| `listingId` | string | Stable portal id, e.g. `142108-196` |
| `listingUrl` | string | Canonical listing page — paste straight back into `detail` |
| `listingTitle` | string | The advertiser's headline |
| `price` | number | Asking price |
| `currency` | string | `TL` |
| `market` | string | `satilik`, `kiralik`, … |
| `propertyType` | string | Daire, Villa, Müstakil Ev … |
| `roomLayout` | string | `3+1`, `2+1`, `Stüdyo` |
| `grossAreaSqm` | number | Gross area |
| `buildingAgeYears` | number | Building age in years |
| `floor` | string | e.g. `4. Kat`, `Kot 2` |
| `province` / `county` / `neighbourhood` | string | İstanbul / Kadıköy / Caferağa |
| `agencyName` / `agentName` | string | Who listed it |
| `publishedDate` | string | ISO date the listing was last posted |
| `imageUrl` / `photoCount` | string / number | Lead photo and how many there are |

**Listing lookup adds:** `latitude`, `longitude`, `netAreaSqm`, `agentPhones`, `depositAmount`, `heating`, `bathroomCount`, `isFurnished`, `buildingState`, `usageState`, `amenities`, `listingDescription`, `images`, `listingNo`, `updatedDate`.

**Example row:**

```json
{
  "listingId": "142108-196",
  "listingUrl": "https://www.hepsiemlak.com/istanbul-esenyurt-mehmet-akif-ersoy-satilik/daire/142108-196",
  "listingTitle": "Metrobüs Yakını Satılık Site İçi 1+1 Daire",
  "price": 2590000,
  "currency": "TL",
  "market": "satilik",
  "propertyType": "Daire",
  "roomLayout": "1+1",
  "grossAreaSqm": 60,
  "buildingAgeYears": 5,
  "floor": "4. Kat",
  "province": "İstanbul",
  "county": "Esenyurt",
  "neighbourhood": "Mehmet Akif Ersoy",
  "agencyName": "Uzmanlar Gayrimenkul",
  "publishedDate": "2026-09-08",
  "photoCount": 26
}
```

***

### 💼 Use Cases & Examples

#### 1. Turkish property market analysis

**Analysts and funds pricing Türkiye need medians, not listings.**

**Input:** A province, a market, a generous `maxItems`.
**Output:** Every listing with gross area and layout, so price per m² is arithmetic.
**Use:** Median price per m² by district, a 3+1 in Kadıköy against the same layout in Çankaya, and how the mix moves month to month on a schedule.

#### 2. Estate agency lead lists

**Agencies and proptech sales teams want the offices actively listing this week.**

**Input:** A district and the property types you sell into.
**Output:** The agency name on every search row; run `detail` on the ones you want and you get the office phone numbers and the individual agent.
**Use:** A contact list built from live stock rather than a directory compiled two years ago.

#### 3. Rental yield and deposit research

**Investors modelling yield need both sides of the same street.**

**Input:** The same district twice — once `satilik`, once `kiralik`.
**Output:** Two datasets that join on district, room layout and area, with the asked deposit from `detail`.
**Use:** The deposit is the number missing from every yield model built on asking prices alone.

#### 4. New-stock monitoring

**Buyers' agents want today's listings, not the whole market again.**

**Input:** `postedWithin: "today"`, on a daily schedule.
**Output:** Only what appeared since yesterday.
**Use:** A watchlist that costs pennies instead of re-reading and re-paying for stock you already hold.

#### 5. Investor sourcing across provinces

**Funds with a buy-box want a nationwide sweep, cheaply.**

**Input:** A price ceiling, a minimum area, and a run per province.
**Output:** Only listings inside the box — the portal filters before anything is fetched.
**Use:** A dozen manual browsing sessions collapse into one scheduled run.

#### 6. Feeding a property portal or CRM

**Product teams need an import job, not a scrape.**

**Input:** Anything; the shape is the same every run.
**Output:** One flat row per listing with a stable id, a canonical URL and ISO dates.
**Use:** Re-run and match on `listingId` to detect price changes and withdrawals without storing whole pages.

#### 7. Relocation and expat search

**People moving to Türkiye want a filtered shortlist, in English columns.**

**Input:** A district, a layout, a rent ceiling.
**Output:** Rows with layout, area, floor, building age and the agency to call.
**Use:** A shortlist you can sort in a spreadsheet instead of forty browser tabs in a language you are still learning.

***

### 🔗 Integration Examples

#### JavaScript/Node.js

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });

const run = await client.actor('sian.agency/hepsiemlak-property-scraper').call({
  operation: 'search',
  province: 'istanbul',
  market: 'satilik',
  propertyType: 'daire',
  maxItems: 100,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]);
```

#### Python

```python
from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')

run = client.actor('sian.agency/hepsiemlak-property-scraper').call(
    run_input={
        'operation': 'search',
        'province': 'ankara',
        'market': 'kiralik',
        'roomLayout': '2-1',
        'maxItems': 100,
    }
)

for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item['listingTitle'], item['price'], item['county'])
```

#### cURL

```bash
curl -X POST 'https://api.apify.com/v2/acts/sian.agency~hepsiemlak-property-scraper/runs?token=YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"operation":"search","province":"izmir","market":"satilik","maxItems":50}'
```

#### Automation Workflows (N8N / Zapier / Make)

1. **Trigger**: a daily schedule
2. **HTTP Request**: call the actor with `postedWithin: "today"`
3. **Process**: filter the JSON for your buy-box
4. **Action**: append to a sheet, push to your CRM, or send yourself the matches

***

### 📊 Performance & Pricing

#### FREE Tier (Try It Now)

- **25 listings** per run — every field, every filter, same quality
- No credit card required
- Enough to check the columns are what you need

#### PAID Tier (Production Ready)

- **Unlimited** listings per run, as deep as the market goes
- Pay per listing returned — a search that matches nothing costs nothing

💰 **$0.001 per listing** on the Bronze tier, and less as your plan tier rises. That is half what the next Hepsiemlak actor on this Store charges, and a quarter of the other two.

Listing lookup is priced separately because fetching one listing at a time genuinely costs more. Use search unless you need coordinates, amenities or agency phone numbers.

🔗 [View current pricing](https://apify.com/sian.agency/hepsiemlak-property-scraper?fpr=sian)

***

### ❓ Frequently Asked Questions

**Q: Do I need an API key, a login or a proxy?**
A: No. Pick a province and a market and press Start. Everything the run needs is wired into the actor.

**Q: How many listings does one request return?**
A: About 23. Set Maximum listings to what you need and the run pages through until it reaches that number or the market runs out.

**Q: What is the difference between Property Search and Listing Lookup?**
A: Search reads results pages, roughly 23 listings per request, with price, area, room layout, building age, floor, location, agency and photo count. Lookup fetches one listing page at a time and adds map coordinates, the full description, every photo, the amenity list, the deposit and the agency's phone numbers. Search is much cheaper per listing.

**Q: Are coordinates and phone numbers on search rows?**
A: No, and that is deliberate. Those fields are only reliably available on the listing page itself, and a column that fills for some searches and stays empty for others is worse than one that is honestly empty. Run Listing Lookup on the listings you care about.

**Q: What does 3+1 mean?**
A: Turkish listings count bedrooms plus living rooms. 3+1 is three bedrooms and one living room; Stüdyo is a studio. The output carries the portal's own notation.

**Q: Which currency are prices in?**
A: Turkish lira. Every price on the portal is quoted in TL. That held on 398 of 398 prices checked across for-sale and rental pages alike, and the currency field records it on each row anyway.

**Q: Can I search a district rather than a whole province?**
A: Yes. Put the district slug in the District field. On this portal a district is searched on its own rather than underneath its province, so the District field replaces the province.

**Q: Can I use a search URL I built on the site myself?**
A: Yes, and it is the best way to use a filter this actor does not expose. Build the search on hepsiemlak.com, copy the address bar, paste it in.

**Q: Do the price and area filters reduce what I pay?**
A: Yes. They are handed to the portal, so listings outside the range are never fetched and never billed.

**Q: How deep can a search go?**
A: As deep as the market. İstanbul for sale reported 31,718 listings over 1,305 pages, and page 50 of that set returned a full page of rows.

**Q: Can I look a listing up by its number alone?**
A: No, and no actor can. The portal has no lookup-by-number route, because a listing's address also encodes its province, district and property type. Use the `listingUrl` every search row carries.

**Q: What output formats are available?**
A: JSON, CSV, Excel and XML — export straight from the dataset or pull it over the API.

***

### 🐛 Troubleshooting

**The run says the address does not exist on the portal**

- Check the district spelling against the address bar on hepsiemlak.com. The portal wants its own slug: `kadikoy`, not `Kadıköy`.
- A district is searched on its own. Setting both Province and District uses the district.

**Fewer listings than I expected**

- The market may genuinely be that small. The run log prints how many listings the portal claims.
- Check your price and area windows. Both bounds apply, and `0` means no bound.

**A run returned no listings at all**

- Widen the price or area range, or clear the room-layout filter. Rare layouts in small provinces really do come back empty.
- The run report names which search it ran, so you can open the same address in a browser and compare.

**A listing lookup failed**

- Listings get withdrawn. Open it in a browser; if it is gone, re-run the search for a live set.

**The portal was challenging visitors**

- Nothing to change on your side. Retry in a few minutes, or put the run on a schedule so it retries on its own.

***

### ⚖️ Is it legal to scrape data?

Our actors are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what the user has chosen to share publicly. We therefore believe that our actors, when used for ethical purposes by Apify users, are safe.

However, you should be aware that your results could contain personal data. Personal data is protected by the **GDPR** in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

You can also read Apify's blog post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

***

### 🤝 Support

[![Telegram Support](https://img.shields.io/badge/Telegram-Support%20Group-0088cc?logo=telegram)](https://t.me/+vyh1sRE08sAxMGRi)

**Join our active support community**

- For issues or questions, open an issue on the actor's page
- Check the [SIÁN Agency Store](https://apify.com/sian.agency?fpr=sian) for more automation tools
- 📧 <apify@sian-agency.online>

***

Hepsiemlak and hepsiemlak.com are trademarks of their respective owners. This actor is not affiliated with, endorsed by, or sponsored by Hepsiemlak. It reads only publicly available listing pages.

**Built by [SIÁN Agency](https://www.sian-agency.online)** | **[More Tools](https://apify.com/sian.agency?fpr=sian)**

# Actor input Schema

## `operation` (type: `string`):

Property Search returns about 23 listings per page from a province or district, for sale or to rent. Listing Lookup takes listing URLs you already hold and fetches each one on its own, adding coordinates, the full description, every photo, the amenity list and the agency phone numbers. Search costs a fraction of Lookup per listing and carries every field the results page shows, so pick Lookup only when you need those extras.

## `province` (type: `string`):

Which province to search. All 81 provinces plus the Northern Cyprus section the portal carries, taken from the portal's own list. İstanbul, Ankara, İzmir, Antalya and Bursa hold the deepest inventory. Ignored when you paste your own search URLs below.

## `district` (type: `string`):

Narrow to one district instead of the whole province — for example kadikoy, besiktas, cankaya, konak, muratpasa. Use the portal's own slug: lowercase, no Turkish accents, words joined by hyphens. Leave empty to search the whole province. On this portal a district is searched on its own, not underneath its province, so setting this replaces the province rather than adding to it.

## `market` (type: `string`):

Which market to read. For sale and To rent are the two deep ones. The four others are real sections of the portal but carry far less inventory, so expect fewer pages.

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

Restrict the search to one residential property type. Leave on Any type to read every type in the market. Apartment and Villa carry the bulk of the inventory; the rarer types return only a handful of pages.

## `roomLayout` (type: `string`):

Turkish listings describe size as rooms plus living rooms — 3+1 means three bedrooms and one living room. Leave on Any layout to read every size. 2+1 and 3+1 are by far the most common.

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

Paste one or more hepsiemlak.com search URLs and they are used exactly as given, overriding every field above. Build the search you want on the site, copy the address bar, paste it here. Any filter the portal supports in a URL works this way, including the ones this actor does not expose as a field.

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

Stop after this many listings. Pages hold about 23 listings each, so 100 is a little over four pages. Raise it to read a whole market — İstanbul for sale held 31,718 listings when this was measured.

## `minPrice` (type: `integer`):

Only listings at or above this price, in Turkish lira. Leave at 0 for no minimum. Applied by the portal, so filtered-out listings are never fetched and never billed.

## `maxPrice` (type: `integer`):

Only listings at or below this price, in Turkish lira. Leave at 0 for no maximum. Applied by the portal, so filtered-out listings are never fetched and never billed.

## `minAreaSqm` (type: `integer`):

Only listings at or above this gross area. Leave at 0 for no minimum. Turkish listings quote both gross and net area; this filter and the area on a search row are both the gross figure.

## `maxAreaSqm` (type: `integer`):

Only listings at or below this gross area. Leave at 0 for no maximum.

## `postedWithin` (type: `string`):

Only listings first posted or refreshed inside this window. Useful on a schedule: run it daily with Today and you collect the new stock rather than re-reading the whole market.

## `listingUrls` (type: `array`):

For Listing Lookup only. Paste hepsiemlak listing page URLs — the listingUrl on every search row is exactly this, so the usual route is to run a search first and feed the URLs you want in here. Each one is fetched on its own and returns the full record with coordinates, description, photos, amenities and agency phone numbers. A bare listing number on its own is not enough: the portal's listing address also encodes the province, district and property type, and it has no lookup-by-number route.

## Actor input object example

```json
{
  "operation": "search",
  "province": "istanbul",
  "district": "",
  "market": "satilik",
  "propertyType": "any",
  "roomLayout": "any",
  "searchUrls": [],
  "maxItems": 100,
  "minPrice": 0,
  "maxPrice": 0,
  "minAreaSqm": 0,
  "maxAreaSqm": 0,
  "postedWithin": "any",
  "listingUrls": []
}
```

# Actor output Schema

## `hepsiemlakListings` (type: `string`):

Every listing this run returned.

## `scrapingSummary` (type: `string`):

HTML summary showing successful and failed results with key metrics

# 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 = {
    "operation": "search",
    "province": "istanbul",
    "district": "",
    "market": "satilik",
    "propertyType": "any",
    "roomLayout": "any",
    "searchUrls": [],
    "maxItems": 100,
    "minPrice": 0,
    "maxPrice": 0,
    "minAreaSqm": 0,
    "maxAreaSqm": 0,
    "postedWithin": "any",
    "listingUrls": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("sian.agency/hepsiemlak-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 = {
    "operation": "search",
    "province": "istanbul",
    "district": "",
    "market": "satilik",
    "propertyType": "any",
    "roomLayout": "any",
    "searchUrls": [],
    "maxItems": 100,
    "minPrice": 0,
    "maxPrice": 0,
    "minAreaSqm": 0,
    "maxAreaSqm": 0,
    "postedWithin": "any",
    "listingUrls": [],
}

# Run the Actor and wait for it to finish
run = client.actor("sian.agency/hepsiemlak-property-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 '{
  "operation": "search",
  "province": "istanbul",
  "district": "",
  "market": "satilik",
  "propertyType": "any",
  "roomLayout": "any",
  "searchUrls": [],
  "maxItems": 100,
  "minPrice": 0,
  "maxPrice": 0,
  "minAreaSqm": 0,
  "maxAreaSqm": 0,
  "postedWithin": "any",
  "listingUrls": []
}' |
apify call sian.agency/hepsiemlak-property-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sian.agency/hepsiemlak-property-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/c2xoIS9DLAsCXKtYB/builds/fSecQTFYVYoFD5q2D/openapi.json
