# KV.ee Scraper — Estonian Real Estate Listings (`studio-amba/kv-ee-scraper`) Actor

Scrape real estate listings from KV.ee — Estonia's largest property portal. Extract apartments, houses, land, and commercial properties with prices, area, rooms, floor, location, and photos. Supports sale and rental listings across all Estonian counties. No login required.

- **URL**: https://apify.com/studio-amba/kv-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

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## KV.ee Scraper

Scrape real estate listings from KV.ee — Estonia's largest and oldest property portal, founded in 1999. Covers over 80% of available properties in Estonia including apartments, houses, land, and commercial real estate. No login or cookies required.

### How to scrape KV.ee data

1. Go to the [KV.ee Scraper](https://apify.com/studio-amba/kv-ee-scraper) page on Apify Store.
2. Click "Try for free" to open the actor in Apify Console.
3. Set your search filters — keyword (e.g., "Tallinn korter"), deal type (sale or rent), and maximum results.
4. Alternatively, paste one or more KV.ee search URLs directly into the Start URLs field for full control over filters like county, price range, and room count.
5. Click "Start" and wait for the run to complete.
6. Download your data as JSON, CSV, or Excel from the Dataset tab.

You can also call this actor via the [Apify API](https://docs.apify.com/api/v2) to integrate KV.ee property data into your own applications and workflows.

### Why use this actor?

Real estate investors, relocation agencies, and proptech companies need reliable Estonian property data. This actor extracts structured listing data from KV.ee including prices, area in m2, room counts, floor info, location details, property photos, and listing descriptions — ready for market analysis, price tracking, or portfolio monitoring.

KV.ee is operated by Kinnisvaraportaal AS (part of Postimees Grupp) and is the dominant real estate portal in Estonia. This actor uses a headless browser (Playwright) to render pages exactly as a real user would see them, ensuring reliable data extraction.

### Input

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `startUrls` | Array | No | KV.ee search result URLs. Overrides other filters. |
| `searchQuery` | String | No | Free text search (e.g., `Tallinn korter`, `Tartu maja`). Default: `Tallinn korter` |
| `dealType` | String | No | `all` (default), `sale`, or `rent` |
| `maxResults` | Integer | No | Maximum results to return (default: 100) |
| `proxyConfiguration` | Object | No | Proxy settings (Estonian residential proxy recommended) |

#### Using Start URLs

For the most control, go to [kv.ee/en/search](https://www.kv.ee/en/search), apply your desired filters (county, deal type, price range, property type, rooms, etc.), and paste the resulting URL into the Start URLs field. This lets you use all of KV.ee's native filters including:

- County and city selection
- Price range (min/max)
- Room count range
- Property area range
- Construction year
- Property condition
- Energy label

### Output

Each result contains:

| Field | Type | Example |
|-------|------|---------|
| `listingTitle` | String | `"3-toaline korter Tallinnas, Kristiine"` |
| `price` | Number | `185000` |
| `currency` | String | `"EUR"` |
| `area` | Number | `67.5` |
| `rooms` | Number | `3` |
| `floor` | String | `"3/5"` |
| `location` | String | `"Tallinn, Kristiine"` |
| `propertyType` | String | `"apartment"` |
| `transactionType` | String | `"sale"` |
| `imageUrl` | String | Primary listing photo URL |
| `url` | String | Full listing URL on KV.ee |
| `listingDescription` | String | Property description text |
| `listingId` | String | KV.ee listing ID |
| `scrapedAt` | String | `"2026-06-09T12:00:00.000Z"` |

### Example output

```json
{
    "listingTitle": "3-toaline korter Tallinnas, Kristiine linnaosas",
    "price": 185000,
    "currency": "EUR",
    "area": 67.5,
    "rooms": 3,
    "floor": "3/5",
    "location": "Tallinn, Kristiine",
    "propertyType": "apartment",
    "transactionType": "sale",
    "imageUrl": "https://www.kv.ee/uploads/objects/12345/photo_1.jpg",
    "url": "https://www.kv.ee/en/12345678",
    "listingDescription": "Müüa korter Kristiine linnaosas, renoveeritud...",
    "listingId": "12345678",
    "scrapedAt": "2026-06-09T12:00:00.000Z"
}
````

### Cost estimate

This actor uses PlaywrightCrawler (headless browser) for reliable rendering. Expect approximately **2-4 compute units per 100 results**. At standard Apify pricing, that's roughly **$0.10-0.20 per 100 listings**.

### Tips for best results

- **Use Estonian keywords** — KV.ee is an Estonian site. Search for "Tallinn korter" instead of "Tallinn apartment" for best results.
- **Start URLs give full filter control** — Apply price range, room count, county, and other filters on kv.ee, then paste the URL.
- **Residential proxies are required** — KV.ee blocks datacenter IPs. The default proxy configuration uses Estonian residential proxies.
- **Empty input works** — Running with no input at all defaults to searching properties in Tallinn.

### Common search keywords

| Estonian | English | What it finds |
|----------|---------|---------------|
| `korter` | apartment | Apartments/flats |
| `maja` | house | Houses, detached homes |
| `maa` | land | Land plots, building plots |
| `krunt` | plot | Building plots |
| `büroo` | office | Office spaces |
| `äripind` | commercial | Commercial real estate |
| `garaaž` | garage | Garages, parking |

### Limitations

- Data is scraped from the public website and may change without notice if KV.ee updates their page structure.
- Full listing descriptions may be truncated in search results — run with individual listing URLs for complete text.
- KV.ee may rate-limit aggressive scraping; the actor handles retries automatically.
- GPS coordinates are not available from search results (only on individual listing pages when provided).

### Use cases

- **Market analysis** — track asking prices, price-per-m2, and inventory across Tallinn, Tartu, and other Estonian cities.
- **Relocation research** — compare rental and sale prices across Tallinn districts or between cities.
- **Real-estate CRM enrichment** — import listings with area, rooms, floor info, and photos into your pipeline.
- **Investor dashboards** — build rental-yield and ROI models on fresh Estonian property inventory.
- **Competitor monitoring** — watch how nearby listings are priced and positioned.
- **Academic research** — study Estonian housing market trends, gentrification patterns, and seasonal price movements.

### Support

Hit a bug or a missing field? Open an issue on the Actor page — we respond fast and ship fixes within 24 hours. Every published scraper in the Studio AMBA catalog is monitored daily; broken runs trigger an automatic heal cycle.

# Actor input Schema

## `startUrls` (type: `array`):

One or more KV.ee search result URLs. Go to kv.ee, set your filters, and paste the URL(s) here. Overrides other search filters when provided.

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

Free-text search query (e.g., 'Tallinn korter', 'Tartu maja', 'Pärnu'). Used only when no startUrls are provided.

## `dealType` (type: `string`):

Transaction type filter. Used only when no startUrls are provided.

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

Maximum number of listings to return.

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

Proxy settings. Residential proxies recommended for reliability.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.kv.ee/en/search?deal_type=&county=1"
    }
  ],
  "searchQuery": "Tallinn korter",
  "dealType": "all",
  "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 = {
    "startUrls": [
        {
            "url": "https://www.kv.ee/en/search?deal_type=&county=1"
        }
    ],
    "searchQuery": "Tallinn korter",
    "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/kv-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 = {
    "startUrls": [{ "url": "https://www.kv.ee/en/search?deal_type=&county=1" }],
    "searchQuery": "Tallinn korter",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "EE",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/kv-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 '{
  "startUrls": [
    {
      "url": "https://www.kv.ee/en/search?deal_type=&county=1"
    }
  ],
  "searchQuery": "Tallinn korter",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "EE"
  }
}' |
apify call studio-amba/kv-ee-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "KV.ee Scraper — Estonian Real Estate Listings",
        "description": "Scrape real estate listings from KV.ee — Estonia's largest property portal. Extract apartments, houses, land, and commercial properties with prices, area, rooms, floor, location, and photos. Supports sale and rental listings across all Estonian counties. No login required.",
        "version": "0.1",
        "x-build-id": "0NZdsiCEOj9sbalWa"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/studio-amba~kv-ee-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-studio-amba-kv-ee-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/studio-amba~kv-ee-scraper/runs": {
            "post": {
                "operationId": "runs-sync-studio-amba-kv-ee-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/studio-amba~kv-ee-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-studio-amba-kv-ee-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "startUrls": {
                        "title": "Start URLs",
                        "type": "array",
                        "description": "One or more KV.ee search result URLs. Go to kv.ee, set your filters, and paste the URL(s) here. Overrides other search filters when provided.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "searchQuery": {
                        "title": "Search Query",
                        "type": "string",
                        "description": "Free-text search query (e.g., 'Tallinn korter', 'Tartu maja', 'Pärnu'). Used only when no startUrls are provided."
                    },
                    "dealType": {
                        "title": "Deal Type",
                        "enum": [
                            "all",
                            "sale",
                            "rent"
                        ],
                        "type": "string",
                        "description": "Transaction type filter. Used only when no startUrls are provided.",
                        "default": "all"
                    },
                    "maxResults": {
                        "title": "Max Results",
                        "minimum": 1,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Maximum number of listings to return.",
                        "default": 100
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Proxy settings. Residential proxies recommended for reliability."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
