# City24 Estonia Scraper - Real Estate Listings & Prices (`studio-amba/city24-ee-scraper`) Actor

Scrape real estate listings from City24.ee, Estonia leading property portal. Get sale and rent prices, addresses, rooms, area, floor, build year, coordinates and agency info. No login or cookies required.

- **URL**: https://apify.com/studio-amba/city24-ee-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** Real estate
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 result scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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

## City24 Estonia Scraper

Scrape real estate listings from **City24.ee**, Estonia's leading property
portal. Get apartments and houses for sale and for rent with prices, addresses,
room counts, living area, floor, build year, energy label, geo coordinates,
photos and the listing agency. No login, no cookies, no browser automation.

### What this actor does

City24.ee is the largest real estate marketplace in Estonia and part of the
Baltic City24 platform. This actor pulls structured listing data straight from
City24's own search API and returns it as clean JSON or a table you can export
to Excel, CSV, JSON, or feed into your own database.

You give it a location (a city or county), whether you want sale or rent
listings, and a property type. It returns every matching listing up to your
result limit, one row per property.

### Why use it

- **Market research** — track asking prices and rents across Tallinn, Tartu,
  Narva, Pärnu and the rest of Estonia.
- **Price monitoring** — watch price per square meter by district over time.
- **Lead lists** — collect listings and the agencies behind them.
- **Investment analysis** — filter by area, rooms, build year and location, then
  compute yield from sale vs rent data in the same schema.
- **Data enrichment** — every listing includes latitude and longitude for
  mapping and geospatial joins.

No login or cookies are required. The actor talks to City24's public search API,
so results match what you see on the site.

### How to scrape City24 Estonia data

1. Set **Location** to an Estonian city or county, for example `Tallinn`,
   `Tartu`, `Narva`, `Pärnu`, or `Harju maakond`. Leave it empty to search all
   of Estonia. Unknown names fall back to a country-wide search filtered by name.
2. Choose **Listing Type**: `sale` or `rent`.
3. Choose **Property Type**: apartment, house, commercial, land, cottage, or
   garage.
4. Set **Max Results** to the number of listings you want.
5. Provide a **Bright Data API key** (see below) or set the
   `BRIGHT_DATA_API_KEY` environment variable.
6. Run the actor. Results appear in the dataset, ready to export.

City24 sits behind Cloudflare, so this actor routes its API calls through Bright
Data Web Unlocker. One request returns up to 500 listings, so large runs stay
fast and cheap.

### Input

| Field | Type | Description |
|-------|------|-------------|
| `location` | string | Estonian city or county. Default `Tallinn`. Empty = all Estonia. |
| `searchQuery` | string | Optional alias for `location`. |
| `listingType` | string | `sale` or `rent`. Default `sale`. |
| `propertyType` | string | apartment, house, commercial, land, cottage, garage. Default apartment. |
| `maxResults` | integer | Maximum listings to return. Default 100. |
| `brightDataApiKey` | string (secret) | Bright Data Web Unlocker key. Required (or set `BRIGHT_DATA_API_KEY`). |
| `proxyConfiguration` | object | Proxy settings (documented fallback; the working transport is Bright Data). |

#### Example input

```json
{
  "location": "Tallinn",
  "listingType": "sale",
  "propertyType": "apartment",
  "maxResults": 100
}
```

### Output

Each listing is a flat JSON object:

| Field | Type | Example |
|-------|------|---------|
| `friendlyId` | string | `"4910395"` |
| `listingTitle` | string | `"Apartment — Uus-Volta tn 7-41, Põhja-Tallinna linnaosa, Tallinn"` |
| `price` | number | `557500` |
| `pricePerUnit` | number | `6106.24` |
| `currency` | string | `"EUR"` |
| `listingType` | string | `"sale"` |
| `propertyType` | string | `"Apartment"` |
| `address` | string | `"Uus-Volta tn 7-41, Põhja-Tallinna linnaosa, Tallinn, Harju maakond"` |
| `city` | string | `"Tallinn"` |
| `district` | string | `"Põhja-Tallinna linnaosa"` |
| `county` | string | `"Harju maakond"` |
| `street` | string | `"Uus-Volta tn 7-41"` |
| `rooms` | number | `3` |
| `area` | number | `91.3` |
| `lotSize` | number | `null` |
| `floor` | number | `3` |
| `totalFloors` | number | `3` |
| `buildYear` | number | `2025` |
| `condition` | string | `"new_building"` |
| `energyLabel` | string | `"C"` |
| `latitude` | number | `59.4485437` |
| `longitude` | number | `24.7220664` |
| `agencyName` | string | `"Endover OÜ"` |
| `imageUrl` | string | primary image URL |
| `imageUrls` | array | all image URLs |
| `datePublished` | string | `"2026-06-19T16:09:01+03:00"` |
| `url` | string | full City24.ee listing URL |
| `scrapedAt` | string | ISO 8601 scrape timestamp |

#### Example output

```json
{
  "friendlyId": "4910395",
  "listingTitle": "Apartment — Uus-Volta tn 7-41, Põhja-Tallinna linnaosa, Tallinn",
  "price": 557500,
  "pricePerUnit": 6106.24,
  "currency": "EUR",
  "listingType": "sale",
  "propertyType": "Apartment",
  "city": "Tallinn",
  "district": "Põhja-Tallinna linnaosa",
  "county": "Harju maakond",
  "rooms": 3,
  "area": 91.3,
  "floor": 3,
  "totalFloors": 3,
  "buildYear": 2025,
  "condition": "new_building",
  "energyLabel": "C",
  "latitude": 59.4485437,
  "longitude": 24.7220664,
  "agencyName": "Endover OÜ",
  "url": "https://www.city24.ee/real-estate/apartments-for-sale/tallinn/4910395"
}
```

### Supported locations

Major cities resolve to exact City24 areas: Tallinn, Tartu, Narva, Pärnu,
Kohtla-Järve, Sillamäe, Haapsalu, Keila, Maardu, Viimsi, Rae, Saku, Saue, Harku,
Kuressaare (Saaremaa). Counties also work: Harju, Tartu, Pärnu, Ida-Viru, Saare,
Võru, Lääne, Jõgeva, Järva, Lääne-Viru, Rapla, Valga maakond. Any other name
triggers a country-wide search filtered by the name you entered.

### Cost estimate

The actor reads City24's search API in pages of up to 500 listings per request,
so it is fast and light. Bright Data Web Unlocker cost per listing is a fraction
of a cent because one request covers hundreds of results. A typical run of a few
hundred listings finishes in under a minute.

### Limitations and known issues

- Requires a Bright Data Web Unlocker key because City24 is behind Cloudflare.
- `condition` and `energyLabel` use City24's own codes (for example
  `new_building`, `no_certificate`, energy class letters).
- `floor` and `totalFloors` are only present when the seller filled them in.
- Detail-page URLs are built from the numeric listing ID and resolve on
  City24.ee; the visible slug may differ slightly from the on-site one.

### Related scrapers

Part of a European real estate collection:

- [Hemnet Scraper](https://apify.com/studio-amba/hemnet-scraper) — Sweden
- [Funda Scraper](https://apify.com/studio-amba/funda-scraper) — Netherlands
- [Idealista Scraper](https://apify.com/studio-amba/idealista-scraper) — Spain
- [Otodom Scraper](https://apify.com/studio-amba/otodom-scraper) — Poland
- [ImmoScout24 Scraper](https://apify.com/studio-amba/immoscout24-scraper) — Germany
- [Zimmo Scraper](https://apify.com/studio-amba/zimmo-scraper) — Belgium

### Disclaimer

Use this actor responsibly and in line with City24's terms and applicable law.
Scrape public data only and respect rate limits.

# Actor input Schema

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

Estonian city or county to search (e.g. 'Tallinn', 'Tartu', 'Narva', 'Pärnu', 'Harju maakond'). Leave empty for all of Estonia. Unknown names fall back to a country-wide search filtered by name.

## `searchQuery` (type: `string`):

Optional alias for Location. If set, it is used as the location to search.

## `listingType` (type: `string`):

Whether to scrape properties for sale or for rent.

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

Type of property to search for.

## `maxResults` (type: `integer`):

Maximum number of listings to return.

## `brightDataApiKey` (type: `string`):

Bright Data API key for Web Unlocker. City24 sits behind a Cloudflare managed challenge, so a Web Unlocker key is required. Can also be supplied via the BRIGHT\_DATA\_API\_KEY environment variable. Get one at https://brightdata.com

## `proxyConfiguration` (type: `object`):

Proxy settings. The working transport is Bright Data Web Unlocker; this is kept as a documented fallback.

## Actor input object example

```json
{
  "location": "Tallinn",
  "listingType": "sale",
  "propertyType": "apartment",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "EE"
  }
}
```

# 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 = {
    "location": "Tallinn",
    "listingType": "sale",
    "propertyType": "apartment",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "EE"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/city24-ee-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 = {
    "location": "Tallinn",
    "listingType": "sale",
    "propertyType": "apartment",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "EE",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/city24-ee-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 '{
  "location": "Tallinn",
  "listingType": "sale",
  "propertyType": "apartment",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "EE"
  }
}' |
apify call studio-amba/city24-ee-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/D8F5HLwQGv6CDOPW5/builds/akiaYII8EaQndqHL2/openapi.json
