# Etuovi.com Real Estate Scraper (`crawlerbros/etuovi-scraper`) Actor

Scrape property listings from Etuovi.com, Finland's largest real estate portal. Search apartments, houses, plots, holiday homes, and farms/forest estates by city or region, with filters for price, size, rooms, construction year, and more.

- **URL**: https://apify.com/crawlerbros/etuovi-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Automation, Lead generation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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

## Etuovi.com Real Estate Scraper

Scrape **Etuovi.com** — Finland's largest real estate marketplace (part of Alma Media). Search apartments, houses, plots, holiday homes, and farm/forest estates by city, region, postal code, or street, with filters for price, size, rooms, construction year, seller type, and more. HTTP-only via the public Etuovi search API. No auth, no proxy, no cookies.

### What this actor does

- **Five property categories:** apartments & houses, plots & building sites, holiday homes & cottages, farms & forest estates, garages & other properties
- **Location search:** any city, region, neighborhood, postal code, or street address in Finland — combine multiple locations in one search
- **Rich filters:** building type, room count, price range, price per m², size range, plot area, construction year, new-building status, seller type (agency vs private), open-bidding status, publish-time window, heating system, overall condition, ownership type, plot ownership, unit storey layout, floor position, sauna, balcony, elevator, monthly maintenance charge, waterfront/shore access, has-video, open-house showing status (upcoming / premiere / today / tomorrow), commute time from a point (walk/cycle/drive/public transport), and free-text keyword search
- **8 sort orders:** newest/oldest, price low/high, size small/large, construction year old/new
- **Full listing data:** address, city, price, rooms, size, construction year, agent/agency contact, next open-house showings, and photo gallery
- **Empty fields are omitted**

### Output per listing

- `id`, `friendlyId` — Etuovi's internal and public listing identifiers
- `published` — whether the listing is currently live on Etuovi.com
- `propertyType`, `propertyTypeCode` — human-readable category and raw code
- `propertySubtype` — building type (e.g. "Detached house", "Cottage", "Forest estate")
- `address`, `areaAndCity`, `city`, `fullLocation`
- `latitude`, `longitude`
- `price` — asking price in EUR
- `size` — living area / plot area in m² (matches the `sizeSmallToLarge`/`sizeLargeToSmall` sort key)
- `totalArea` — total area in m², when Etuovi reports one (e.g. detached houses, where this also includes garages, basements, or outbuildings and can exceed `size`)
- `forestLandArea` — forest area in m² (farm/forest estates)
- `rooms` — Finnish room-structure notation (e.g. `4h, k, s` = 4 rooms, kitchen, sauna)
- `roomCountLabel`, `constructionYear`, `newBuilding`, `developmentPhase` — new-building construction status (`Pre-marketing` / `Under construction` / `Move-in ready`), when the listing is a new-build
- `floorLevel`, `floorCount` — the listing's floor, and the total floors in the building
- `unitFloorCount` — how many floors the unit itself spans (e.g. a duplex apartment inside a taller building spans 2 of its own floors), when Etuovi reports it
- `previousPrice` — the listing's prior asking price, when Etuovi reports a price change
- `hasOpenBidding`, `isCompanyAnnouncement`, `hasVideo`, `hasPanorama`
- `sellerName` — private seller's name, when the listing is not from an agency
- `officeName`, `officeWebsite`, `officeLogoUrl` — listing agency
- `agentName`, `agentImageUrl` — listing agent, when available
- `publishedAt`, `updatedAt`
- `nextShowings[]` — upcoming open-house dates/times
- `mainImageUrl`, `images[]`, `floorPlanImageUrl`
- `sourceUrl` — canonical `etuovi.com/kohde/...` listing page
- `recordType: "listing"`, `scrapedAt`

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `propertyType` | string | `RESIDENTIAL` | Property category — `RESIDENTIAL` / `PLOT` / `LEISURE` / `ESTATE` / `OTHER` |
| `locations` | array | – | City / region / postal code / street to search. Leave empty for all of Finland |
| `residentialPropertyTypes` | array | – | Building type filter (only applies when `propertyType=RESIDENTIAL`) |
| `roomCounts` | array | – | Restrict to specific room counts |
| `priceMin` / `priceMax` | int | – | Price range in EUR |
| `sizeMin` / `sizeMax` | int | – | Living-area range in m² |
| `yearMin` / `yearMax` | int | – | Construction-year range |
| `freeTextSearch` | string | – | Keyword search (e.g. `sauna`, `pool`, `fireplace`) |
| `newBuildingSearchCriteria` | string | `ALL_PROPERTIES` | `ALL_PROPERTIES` / `ONLY_NEW_BUILDINGS` / `NO_NEW_BUILDINGS` |
| `sellerType` | string | `ALL` | `ALL` / `OFFICE` (agencies only) / `USER` (private sellers only) |
| `bidType` | string | `ALL` | `ALL` / `OPEN_BID` / `NO_OPEN_BID` |
| `publishingTimeSearchCriteria` | string | `ANY_DAY` | Restrict to recently published listings |
| `heatingSystems` | array | – | Heating system filter (only applies when `propertyType=RESIDENTIAL`) — district heating, electric, geothermal, oil, gas, wood, heat pump, air-to-water heat pump, exhaust-air heat pump, solar, or not known |
| `overallConditions` | array | – | Seller-reported condition (`RESIDENTIAL` only) — good / satisfactory / tolerable / unclassified |
| `ownershipTypes` | array | – | Form of ownership (`RESIDENTIAL` only) — freehold, right-of-occupancy, partial ownership, other, not known |
| `plotHoldingTypes` | array | – | Plot ownership under the building (`RESIDENTIAL` only) — own / leased / optionally redeemable lease |
| `residentialFloorCountTypes` | array | – | Unit storey layout (`RESIDENTIAL` only) — single-storey, two-storey, multi-storey, one-and-a-half-storey, not known |
| `floorPositionInHighrise` | array | – | Unit's floor position in the building (`RESIDENTIAL` only) — bottom / middle / top / not known |
| `saunaType` | string | `ANY` | Sauna filter (`RESIDENTIAL` only) — `ANY` / `OWN_SAUNA` / `HOUSING_COMPANY_SAUNA` / `NO_SAUNA` |
| `hasBalcony` | boolean | `false` | Only listings with a balcony (`RESIDENTIAL` only) |
| `hasElevator` | boolean | `false` | Only listings in buildings with an elevator (`RESIDENTIAL` only) |
| `pricePerSqmMin` / `pricePerSqmMax` | int | – | Price-per-m² range in EUR (`RESIDENTIAL` only) |
| `maintenanceChargeMin` / `maintenanceChargeMax` | int | – | Monthly housing-company maintenance charge (vastike) range in EUR (`RESIDENTIAL` only) |
| `plotAreaMin` / `plotAreaMax` | int | – | Plot area range in m² (applies to `RESIDENTIAL`, `PLOT`, and `LEISURE` only) |
| `hasShore` | boolean | `false` | Only listings with direct shore/waterfront access (all property categories) |
| `hasVideo` | boolean | `false` | Only listings with a video tour (all property categories) |
| `hasUpcomingShowing` | boolean | `false` | Only listings with a future open-house showing scheduled (all property categories) |
| `hasPremiereShowing` | boolean | `false` | Only listings whose next showing is their first-ever ("premiere") showing (all property categories) |
| `hasShowingToday` | boolean | `false` | Only listings with an open-house showing today (all property categories) |
| `hasShowingTomorrow` | boolean | `false` | Only listings with an open-house showing tomorrow (all property categories) |
| `travelTimeLat` / `travelTimeLon` | number | – | Latitude/longitude of a point to measure commute time from (e.g. a workplace). Both must be set together to enable the filter. Applies to all property categories |
| `travelTimeMinutes` | int | `30` | Only listings reachable from the commute point within this many minutes (5–240) |
| `travelTimeTransportMethod` | string | `WALKING` | Commute mode — `WALKING` / `CYCLING` / `DRIVING` / `PUBLIC_TRANSPORT` |
| `travelTimeLocationName` | string | – | Optional cosmetic label for the commute point (doesn't affect matching) |
| `sortBy` | string | `newest` | Sort order (see enum below) |
| `maxItems` | int | `30` | Hard cap on emitted listings (1–5000) |

#### Example: apartments in Helsinki, 2–3 rooms, under 400k

```json
{
  "propertyType": "RESIDENTIAL",
  "locations": ["Helsinki"],
  "roomCounts": ["TWO_ROOMS", "THREE_ROOMS"],
  "priceMax": 400000,
  "sortBy": "priceLowToHigh",
  "maxItems": 50
}
```

#### Example: holiday cottages with a keyword, sorted by size

```json
{
  "propertyType": "LEISURE",
  "locations": ["Mikkeli", "Savonlinna"],
  "freeTextSearch": "oma ranta",
  "sortBy": "sizeLargeToSmall",
  "maxItems": 50
}
```

#### Example: private-seller detached houses built after 2010

```json
{
  "propertyType": "RESIDENTIAL",
  "residentialPropertyTypes": ["DETACHED_HOUSE"],
  "sellerType": "USER",
  "yearMin": 2010,
  "maxItems": 50
}
```

#### Example: forest estates nationwide

```json
{
  "propertyType": "ESTATE",
  "maxItems": 50
}
```

#### Example: district-heated, elevator apartments with a sauna and balcony

```json
{
  "propertyType": "RESIDENTIAL",
  "locations": ["Tampere"],
  "heatingSystems": ["DISTRICT_HEATING"],
  "saunaType": "OWN_SAUNA",
  "hasBalcony": true,
  "hasElevator": true,
  "maintenanceChargeMax": 400,
  "maxItems": 50
}
```

#### Example: waterfront cottages with a video tour, sorted by size

```json
{
  "propertyType": "LEISURE",
  "hasShore": true,
  "hasVideo": true,
  "sortBy": "sizeLargeToSmall",
  "maxItems": 50
}
```

#### Example: apartments within a 20-minute walk of Helsinki city centre

```json
{
  "propertyType": "RESIDENTIAL",
  "travelTimeLat": 60.1699,
  "travelTimeLon": 24.9384,
  "travelTimeMinutes": 20,
  "travelTimeTransportMethod": "WALKING",
  "travelTimeLocationName": "Helsinki city centre",
  "maxItems": 50
}
```

#### Example: apartments with an open-house showing today or tomorrow

```json
{
  "propertyType": "RESIDENTIAL",
  "locations": ["Espoo"],
  "hasShowingToday": true,
  "hasShowingTomorrow": true,
  "maxItems": 50
}
```

### Use cases

- **Real estate market analysis** — track asking prices, price-per-m², and inventory by city or region
- **PropTech products** — feed live Finnish listings into a search or comparison app
- **Relocation & investment research** — compare housing stock across Finnish cities
- **Lead generation** — find newly listed or private-seller properties in a target area
- **Forestry & land investors** — monitor farm and forest-estate listings nationwide

### FAQ

**What's the data source?**  The public search API behind [etuovi.com](https://www.etuovi.com), Finland's largest real-estate marketplace, operated by Alma Media. This actor is an independent third-party tool and is not affiliated with Alma Media or Etuovi.com.

**Does this cover rental listings?**  No — Etuovi.com lists properties for sale only. Alma Media's rental listings live on a separate site (vuokraovi.com), which is out of scope for this actor.

**Why do some listings lack an agent name or photos?**  Those fields are only populated by Etuovi for listings with "premium" placement. The actor never fabricates missing data — the field is simply omitted.

**What does the `rooms` field mean?**  It's Etuovi's Finnish room-structure shorthand, e.g. `4h, k, s` means 4 rooms + kitchen (`k`) + sauna (`s`). It's the most descriptive room field the source provides.

**How is `city` determined?**  Etuovi doesn't expose a standalone city field on search results — `city` is derived from the last word of the listing's area/city string (`addressLine2`). For the rare compound-name municipality, use the `fullLocation` field for the complete, unparsed string.

**Are prices in EUR?**  Yes, all prices are the listing's asking price in euros as shown on Etuovi.com.

**What's the difference between `size` and `totalArea`?**  `size` is the living area (the same field Etuovi sorts on for `sortBy: sizeSmallToLarge`/`sizeLargeToSmall`), so it always matches the requested sort order. `totalArea`, when Etuovi reports one, additionally counts garages, basements, or outbuildings — for detached houses it's often larger than `size`.

**How fresh is the data?**  Real-time — every run queries Etuovi's live search API directly.

**What's the difference between `floorCount` and `unitFloorCount`?**  `floorCount` is the total number of floors in the building. `unitFloorCount` is how many of those floors the individual unit itself occupies — e.g. a duplex apartment inside a 5-storey building has `floorCount: 5` and `unitFloorCount: 2`. Most listings only report `floorCount`; `unitFloorCount` appears when Etuovi tracks it separately (mainly apartments, terraced houses, and cottages).

**Why do filters like `heatingSystems` or `hasElevator` only work for `propertyType=RESIDENTIAL`?**  Etuovi's own search API rejects those fields with `400 Bad Request` for plots, holiday homes, farms/forest estates, and garages — they describe attributes of lived-in residential units (heating system, sauna, elevator access, monthly maintenance charge) that don't exist for a building plot or forest estate. `plotAreaMin`/`plotAreaMax` are the one exception that also work on `PLOT` and `LEISURE`. `hasShore` and `hasVideo` work on every property category.

**Can I see the heating system, condition, or sauna type in the output?**  No — those are search-time filter criteria only. Etuovi's search results endpoint doesn't echo them back per listing (only the full listing detail page does, which this actor doesn't fetch to keep the scraper fast and request-cheap). You can filter *by* `heatingSystems=["WOOD"]`, for example, but the matched records won't carry a `heatingSystem` output field.

**How does the commute-time filter work?**  Set `travelTimeLat`/`travelTimeLon` to the coordinates of a point (e.g. a workplace or city centre — get these from Google Maps by right-clicking the point), then set `travelTimeMinutes` and `travelTimeTransportMethod`. The actor only returns listings Etuovi's own routing engine estimates are reachable from that point within the given time by the given transport method. `travelTimeLocationName` is an optional label only used for your own reference — it doesn't affect matching. Both `travelTimeLat` and `travelTimeLon` must be set together, or the filter is ignored.

# Actor input Schema

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

Which category of listings to search.

## `locations` (type: `array`):

City, region, neighborhood, postal code, or street address to search (e.g. `Helsinki`, `Uusimaa`, `00100`). Multiple values are combined with OR. Leave empty to search all of Finland.

## `residentialPropertyTypes` (type: `array`):

Restrict to specific building types. Only applies when Property category is `Apartments & houses`. Leave empty for all building types.

## `roomCounts` (type: `array`):

Restrict to listings with these room counts. Leave empty for any room count.

## `priceMin` (type: `integer`):

Drop listings priced below this amount, in euros.

## `priceMax` (type: `integer`):

Drop listings priced above this amount, in euros.

## `sizeMin` (type: `integer`):

Drop listings with living area below this size, in square meters.

## `sizeMax` (type: `integer`):

Drop listings with living area above this size, in square meters.

## `yearMin` (type: `integer`):

Drop listings built before this year.

## `yearMax` (type: `integer`):

Drop listings built after this year.

## `freeTextSearch` (type: `string`):

Free-text keyword search across listing descriptions and features (e.g. `sauna`, `pool`, `fireplace`).

## `newBuildingSearchCriteria` (type: `string`):

Filter by new-construction status.

## `sellerType` (type: `string`):

Filter by who is selling.

## `bidType` (type: `string`):

Filter by whether the listing uses open bidding (tarjouskauppa).

## `publishingTimeSearchCriteria` (type: `string`):

Restrict to listings first published within a recent time window.

## `heatingSystems` (type: `array`):

Restrict to specific heating systems. Only applies when Property category is `Apartments & houses`. Leave empty for any heating system.

## `overallConditions` (type: `array`):

Restrict to listings with this seller-reported overall condition. Only applies when Property category is `Apartments & houses`. Leave empty for any condition.

## `ownershipTypes` (type: `array`):

Restrict to specific forms of ownership. Only applies when Property category is `Apartments & houses`. Leave empty for any ownership type.

## `plotHoldingTypes` (type: `array`):

Restrict by whether the plot the building stands on is owned or leased. Only applies when Property category is `Apartments & houses`. Leave empty for any plot ownership.

## `residentialFloorCountTypes` (type: `array`):

Restrict to units with this many internal storeys (e.g. single-storey apartment vs. two-storey maisonette). Only applies when Property category is `Apartments & houses`. Leave empty for any layout.

## `floorPositionInHighrise` (type: `array`):

Restrict to units on the bottom, middle, or top floor of the building. Only applies when Property category is `Apartments & houses`. Leave empty for any floor position.

## `saunaType` (type: `string`):

Filter by sauna availability. Only applies when Property category is `Apartments & houses`.

## `hasBalcony` (type: `boolean`):

Only include listings with a balcony. Only applies when Property category is `Apartments & houses`.

## `hasElevator` (type: `boolean`):

Only include listings in buildings with an elevator. Only applies when Property category is `Apartments & houses`.

## `pricePerSqmMin` (type: `integer`):

Drop listings priced below this EUR-per-square-meter rate. Only applies when Property category is `Apartments & houses`.

## `pricePerSqmMax` (type: `integer`):

Drop listings priced above this EUR-per-square-meter rate. Only applies when Property category is `Apartments & houses`.

## `maintenanceChargeMin` (type: `integer`):

Drop listings with a housing-company maintenance charge (vastike) below this monthly EUR amount. Only applies when Property category is `Apartments & houses`.

## `maintenanceChargeMax` (type: `integer`):

Drop listings with a housing-company maintenance charge (vastike) above this monthly EUR amount. Only applies when Property category is `Apartments & houses`.

## `plotAreaMin` (type: `integer`):

Drop listings with a plot area below this size, in square meters. Only applies when Property category is `Apartments & houses`, `Plots & building sites`, or `Holiday homes & cottages`.

## `plotAreaMax` (type: `integer`):

Drop listings with a plot area above this size, in square meters. Only applies when Property category is `Apartments & houses`, `Plots & building sites`, or `Holiday homes & cottages`.

## `travelTimeLat` (type: `number`):

Latitude of the point to measure commute time from (e.g. a workplace or city center). Must be paired with Commute-search longitude. Leave both empty to disable the commute-time filter. Applies to all property categories.

## `travelTimeLon` (type: `number`):

Longitude of the point to measure commute time from. Must be paired with Commute-search latitude. Leave both empty to disable the commute-time filter. Applies to all property categories.

## `travelTimeMinutes` (type: `integer`):

Only include listings reachable from the commute-search point within this many minutes, by the selected transport method. Only applies when Commute-search latitude/longitude are set.

## `travelTimeTransportMethod` (type: `string`):

How to measure the commute time from the commute-search point. Only applies when Commute-search latitude/longitude are set.

## `travelTimeLocationName` (type: `string`):

Optional display label for the commute-search point (e.g. `Helsinki city centre`). Cosmetic only — does not affect which listings match. Only applies when Commute-search latitude/longitude are set.

## `hasShore` (type: `boolean`):

Only include listings with direct shore/waterfront access. Applies to all property categories.

## `hasVideo` (type: `boolean`):

Only include listings that have a video tour. Applies to all property categories.

## `hasUpcomingShowing` (type: `boolean`):

Only include listings with at least one open-house showing scheduled in the future. Applies to all property categories. Combines with the other showing filters below (OR).

## `hasPremiereShowing` (type: `boolean`):

Only include listings whose next open-house showing is the listing's first-ever ("premiere") showing. Applies to all property categories. Combines with the other showing filters below (OR).

## `hasShowingToday` (type: `boolean`):

Only include listings with an open-house showing scheduled today. Applies to all property categories. Combines with the other showing filters below (OR).

## `hasShowingTomorrow` (type: `boolean`):

Only include listings with an open-house showing scheduled tomorrow. Applies to all property categories. Combines with the other showing filters below (OR).

## `sortBy` (type: `string`):

How to order the results.

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

Hard cap on the number of listings to scrape.

## Actor input object example

```json
{
  "propertyType": "RESIDENTIAL",
  "locations": [
    "Helsinki"
  ],
  "residentialPropertyTypes": [],
  "roomCounts": [],
  "newBuildingSearchCriteria": "ALL_PROPERTIES",
  "sellerType": "ALL",
  "bidType": "ALL",
  "publishingTimeSearchCriteria": "ANY_DAY",
  "heatingSystems": [],
  "overallConditions": [],
  "ownershipTypes": [],
  "plotHoldingTypes": [],
  "residentialFloorCountTypes": [],
  "floorPositionInHighrise": [],
  "saunaType": "ANY",
  "hasBalcony": false,
  "hasElevator": false,
  "travelTimeMinutes": 30,
  "travelTimeTransportMethod": "WALKING",
  "hasShore": false,
  "hasVideo": false,
  "hasUpcomingShowing": false,
  "hasPremiereShowing": false,
  "hasShowingToday": false,
  "hasShowingTomorrow": false,
  "sortBy": "newest",
  "maxItems": 30
}
```

# Actor output Schema

## `listings` (type: `string`):

Dataset containing all scraped Etuovi.com property listings.

# 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 = {
    "propertyType": "RESIDENTIAL",
    "locations": [
        "Helsinki"
    ],
    "residentialPropertyTypes": [],
    "roomCounts": [],
    "newBuildingSearchCriteria": "ALL_PROPERTIES",
    "sellerType": "ALL",
    "bidType": "ALL",
    "publishingTimeSearchCriteria": "ANY_DAY",
    "heatingSystems": [],
    "overallConditions": [],
    "ownershipTypes": [],
    "plotHoldingTypes": [],
    "residentialFloorCountTypes": [],
    "floorPositionInHighrise": [],
    "saunaType": "ANY",
    "hasBalcony": false,
    "hasElevator": false,
    "travelTimeMinutes": 30,
    "travelTimeTransportMethod": "WALKING",
    "hasShore": false,
    "hasVideo": false,
    "hasUpcomingShowing": false,
    "hasPremiereShowing": false,
    "hasShowingToday": false,
    "hasShowingTomorrow": false,
    "sortBy": "newest",
    "maxItems": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/etuovi-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 = {
    "propertyType": "RESIDENTIAL",
    "locations": ["Helsinki"],
    "residentialPropertyTypes": [],
    "roomCounts": [],
    "newBuildingSearchCriteria": "ALL_PROPERTIES",
    "sellerType": "ALL",
    "bidType": "ALL",
    "publishingTimeSearchCriteria": "ANY_DAY",
    "heatingSystems": [],
    "overallConditions": [],
    "ownershipTypes": [],
    "plotHoldingTypes": [],
    "residentialFloorCountTypes": [],
    "floorPositionInHighrise": [],
    "saunaType": "ANY",
    "hasBalcony": False,
    "hasElevator": False,
    "travelTimeMinutes": 30,
    "travelTimeTransportMethod": "WALKING",
    "hasShore": False,
    "hasVideo": False,
    "hasUpcomingShowing": False,
    "hasPremiereShowing": False,
    "hasShowingToday": False,
    "hasShowingTomorrow": False,
    "sortBy": "newest",
    "maxItems": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/etuovi-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 '{
  "propertyType": "RESIDENTIAL",
  "locations": [
    "Helsinki"
  ],
  "residentialPropertyTypes": [],
  "roomCounts": [],
  "newBuildingSearchCriteria": "ALL_PROPERTIES",
  "sellerType": "ALL",
  "bidType": "ALL",
  "publishingTimeSearchCriteria": "ANY_DAY",
  "heatingSystems": [],
  "overallConditions": [],
  "ownershipTypes": [],
  "plotHoldingTypes": [],
  "residentialFloorCountTypes": [],
  "floorPositionInHighrise": [],
  "saunaType": "ANY",
  "hasBalcony": false,
  "hasElevator": false,
  "travelTimeMinutes": 30,
  "travelTimeTransportMethod": "WALKING",
  "hasShore": false,
  "hasVideo": false,
  "hasUpcomingShowing": false,
  "hasPremiereShowing": false,
  "hasShowingToday": false,
  "hasShowingTomorrow": false,
  "sortBy": "newest",
  "maxItems": 30
}' |
apify call crawlerbros/etuovi-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawlerbros/etuovi-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/V4gvaQJas8t3lZGzR/builds/u6irSwIGNQ8jviQpe/openapi.json
