Asunnot Oikotie.fi Real Estate Scraper
Pricing
from $1.00 / 1,000 dataset items
Asunnot Oikotie.fi Real Estate Scraper
Scrape Finnish property listings from asunnot.oikotie.fi by location, filters, or search/listing URLs. Optionally enrich each result with full listing details.
Pricing
from $1.00 / 1,000 dataset items
Rating
0.0
(0)
Developer
Data Scrapers
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Asunnot Oikotie.fi Real Estate Scraper creates a structured dataset of Finnish property listings collected from asunnot.oikotie.fi. Each dataset item is one listing card and can include the listing URL, address, city, district, price in euros, living area, rooms, building type, construction year, and image. Query by location, listing type, or a search or listing URL, optionally enrich each card from the listing page, limit results with maxItems, and retrieve records through the Apify Dataset API or export them as JSON, CSV, Excel, XML, or another supported format.
Dataset at a glance
| Property | Value |
|---|---|
| Source | asunnot.oikotie.fi |
| Record unit | One listing card, optionally enriched from the listing page |
| Input methods | startUrls, or searchQueries plus filters |
| Main identifiers | cardId and id |
| Delivery | Apify Dataset and API |
| Export formats | JSON, CSV, Excel, XML, and other Apify dataset exports |
| Update model | Fresh records per Actor run |
| Pricing | $0.001 per listing card. $0.002 extra per listing when detail enrichment succeeds. |
Coverage and available records
Start URLs take priority. A start URL may be a search results URL, such as https://asunnot.oikotie.fi/myytavat-asunnot?cardType=100&locations[]=helsinki, or a single listing URL. Query filters already on a search URL are kept. searchQueries is used when startUrls is empty. An empty location list with no start URL searches nationwide using the filters.
Supported listing types: homes for sale, homes for rent, holiday homes for sale or rent, plots, commercial for sale or rent, farms and forest estates, garages, and new developments.
Supported filters on searches that do not already set the same keys: building type, room count, minimum and maximum price in euros, living area in square meters, construction year, and sort order.
maxItems defaults to 100. 0 means no item cap. The saved sample used Helsinki, homes for sale, and maxItems 5, with detail extraction off.
Card records include address, district, city, postal code, price, price per square meter, living area, rooms, room layout, floor, building floor count, maintenance fee, construction year, coordinates, image, publication time, vendor ad id, and visit counts. officeName and officeId were null on the saved cards.
extractDetails fetches the listing page and sets detailsScraped to true. That path can add energy class, heating, sauna and kitchen text, contact name, phone, and email, office contact fields, an image list, viewings, and extra price fields. Those fields are absent on card-only records. Detail enrichment charges the separate listing-details event after a successful detail fetch.
Not currently collected:
- A guaranteed office name on every card. The saved Helsinki cards left
officeNamenull - Historical sold-price series
- Media files.
imageUrlis a link
Data dictionary
Types and examples are from a saved Helsinki for-sale card with detailsScraped false. The description in that file is longer than the text shown in the example below.
| Field | Type | Nullable | Description | Example |
|---|---|---|---|---|
id | integer | No | Numeric listing id. Same value as cardId on this card. | 24609013 |
cardId | string | No | Listing id as a string. Best join key when you mix card and detail records. | 24609013 |
url | string | No | Public listing URL. | https://asunnot.oikotie.fi/myytavat-asunnot/helsinki/24609013 |
cardType | integer | No | Listing category code. | 100 |
cardTypeLabel | string or null | Yes | Category label. | For sale (homes) |
buildingType | integer or null | Yes | Building type code. | 1 |
buildingTypeLabel | string or null | Yes | Building type label. | Apartment building |
status | integer or null | Yes | Source status code. | 1 |
description | string or null | Yes | Card description text. | Finnish listing text |
rooms | number or null | Yes | Room count. | 2 |
roomConfiguration | string or null | Yes | Layout label. | 2h + kk |
price | number or null | Yes | Price in euros. | 215000.0 |
priceText | string or null | Yes | Formatted euro price. | 215 000 € |
pricePerSqm | number or null | Yes | Euros per square meter. | 5000 |
size | number or null | Yes | Living area in square meters. | 43 |
sizeText | string or null | Yes | Formatted area. | 43 m² |
sizeLot | number or null | Yes | Lot size. Null on some cards. | 1118.9 |
buildYear | integer or null | Yes | Construction year. | 1961 |
floor | integer or null | Yes | Floor number. | 4 |
buildingFloorCount | integer or null | Yes | Floors in the building. | 8 |
maintenanceFee | number or null | Yes | Maintenance fee in euros. | 245.1 |
newDevelopment | boolean or null | Yes | New-development flag. | false |
nextViewing | object or null | Yes | Next viewing. Null when none is listed. | See below |
visits | integer or null | Yes | Visit count from the card. | 0 |
visitsWeekly | integer or null | Yes | Weekly visit count. | 0 |
address | string or null | Yes | Street, postal code, and city. | Suvilahdenkatu 1, 00500, Helsinki |
streetAddress | string or null | Yes | Street address. | Suvilahdenkatu 1 |
district | string or null | Yes | District. | Sörnäinen |
city | string or null | Yes | City. | Helsinki |
zipCode | string or null | Yes | Postal code. | 00500 |
country | string or null | Yes | Country label from the source. | Suomi |
latitude | number or null | Yes | Latitude. | 60.1871 |
longitude | number or null | Yes | Longitude. | 24.9669 |
published | string or null | Yes | Published timestamp, YYYY-MM-DD HH:MM:SS. | 2026-07-25 11:15:17 |
publishedSort | string or null | Yes | Sort timestamp from the source. | 2026-07-25 11:15:18 |
vendorAdId | string or null | Yes | Vendor advertisement id. | UUID string |
officeName | string or null | Yes | Office name. Null on the saved card. | null |
officeId | string or null | Yes | Office id. Null on the saved card. | null |
imageUrl | string or null | Yes | Card image URL. | https://cdn.asunnot.oikotie.fi/... |
detailsScraped | boolean | No | True only after a successful listing-page enrichment. | false |
sourceQuery | string or null | Yes | Location or URL query that produced the card. | Helsinki |
nextViewing, when present:
| Field | Type | Description | Example |
|---|---|---|---|
date | string | Viewing date | 2026-07-26 |
start | string | Start time | 13:00 |
end | string | End time | 13:30 |
live | boolean | Live-viewing flag | false |
first | boolean | First-viewing flag | true |
Detail-only fields, present when detailsScraped is true, and otherwise omitted:
descriptionSupplementary, priceSell, shareOfLiabilities, rentPerMonth, sizeTotal, energyClass, heating, sauna, saunaInfo, kitchenInfo, bathroomInfo, availability, servicesInfo, otherFeesInfo, estateTax, realEstateId, created, lastModified, expires, officeEmail, officePhone, officeUrl, officeStreetAddress, officeCity, officeZipCode, contactName, contactPhone, contactEmail, images, viewings, and sellStatus.
No detail-enriched sample was saved in this folder, so those fields are named from the parser and are not given example values here.
Example dataset record
This card is a Helsinki for-sale apartment from searchQueries: ["Helsinki"] with extractDetails false. The stored description is longer. The text below is the opening of that same description.
{"id": 24609013,"cardId": "24609013","url": "https://asunnot.oikotie.fi/myytavat-asunnot/helsinki/24609013","cardType": 100,"cardTypeLabel": "For sale (homes)","buildingType": 1,"buildingTypeLabel": "Apartment building","status": 1,"description": "Raikasta merituulta, urbaania asumista parhaimmillaan Vilhonvuoren rauhaisilla ja viihtyisillä kaduilla.","rooms": 2,"roomConfiguration": "2h + kk","price": 215000.0,"priceText": "215 000 €","pricePerSqm": 5000,"size": 43,"sizeText": "43 m²","sizeLot": 1118.9,"buildYear": 1961,"floor": 4,"buildingFloorCount": 8,"maintenanceFee": 245.1,"newDevelopment": false,"nextViewing": {"date": "2026-07-26","start": "13:00","end": "13:30","live": false,"first": true},"visits": 0,"visitsWeekly": 0,"address": "Suvilahdenkatu 1, 00500, Helsinki","streetAddress": "Suvilahdenkatu 1","district": "Sörnäinen","city": "Helsinki","zipCode": "00500","country": "Suomi","latitude": 60.1871,"longitude": 24.9669,"published": "2026-07-25 11:15:17","publishedSort": "2026-07-25 11:15:18","vendorAdId": "75485a34-132f-43b2-a38e-c37b1e1e7f9c","officeName": null,"officeId": null,"imageUrl": "https://cdn.asunnot.oikotie.fi/C763kBNcZy05qAuNvn9lfE21dH4=/full-fit-in/708x444/filters:background_color(white):format(jpeg):quality(60)/ot-real-estate-mediabank-prod/281/886/source/231688182","detailsScraped": false,"sourceQuery": "Helsinki"}
Query and input reference
| Input | Type | Required | Default | Accepted values | Description |
|---|---|---|---|---|---|
startUrls | URL array | No | None | Search or listing URLs | Priority source. Prefill is a Helsinki for-sale search. |
searchQueries | string array | No | None | City, district, or postal code | Ignored when startUrls is set. Prefill: Helsinki. |
listingType | string | No | FOR_SALE | FOR_SALE, FOR_RENT, HOLIDAY_FOR_SALE, HOLIDAY_FOR_RENT, PLOTS, COMMERCIAL_FOR_SALE, COMMERCIAL_FOR_RENT, FARMS, GARAGES, NEW_DEVELOPMENT | Listing category. |
buildingTypes | string array | No | Empty | APARTMENT, ROW_HOUSE, DETACHED_HOUSE, HOLIDAY_HOME, SEMI_DETACHED_SEPARATE, SEMI_DETACHED, OTHER, WALK_UP, WOODEN_APARTMENT | Empty means all types. |
roomCounts | string array | No | Empty | 1, 2, 3, 4, 5 | 5 means five or more rooms. |
priceMin | integer | No | None | Euros, minimum 0 | Minimum sale price or rent. |
priceMax | integer | No | None | Euros, minimum 0 | Maximum price. |
sizeMin | integer | No | None | Square meters, minimum 0 | Minimum living area. |
sizeMax | integer | No | None | Square meters, minimum 0 | Maximum living area. |
yearMin | integer | No | None | Year, minimum 1800 | Minimum construction year. |
yearMax | integer | No | None | Year, minimum 1800 | Maximum construction year. |
sortBy | string | No | publishedDesc | publishedDesc, publishedAsc, priceAsc, priceDesc, sizeAsc, sizeDesc | Search sort. |
extractDetails | boolean | No | false | true or false | Fetch each listing page and charge listing-details. |
detailConcurrency | integer | No | 5 | 1–50 | Parallel detail requests. |
maxItems | integer | No | 100 | 0 or a positive integer | Maximum listings. 0 means no cap. Prefill 20. |
proxyConfiguration | object | No | Apify residential proxy | Apify proxy editor | Proxy for search and detail requests. |
Filters are ignored for keys already present on a start URL.
Minimal request:
{"searchQueries": ["Helsinki"],"listingType": "FOR_SALE","maxItems": 5,"extractDetails": false}
Detail request:
{"startUrls": [{ "url": "https://asunnot.oikotie.fi/myytavat-asunnot?cardType=100&locations[]=helsinki" }],"maxItems": 5,"extractDetails": true,"detailConcurrency": 3}
Retrieve the data through the API
- Start
datascrapers/asunnot-oikotie-fiwith the JSON input. - Wait until the run finishes, or call the synchronous dataset endpoint.
- Read items from the run's default dataset.
- Paginate with dataset
offsetandlimit, or export from the Apify console.
from apify_client import ApifyClientclient = ApifyClient("<YOUR_API_TOKEN>")run = client.actor("datascrapers/asunnot-oikotie-fi").call(run_input={"searchQueries": ["Helsinki"],"listingType": "FOR_SALE","maxItems": 5,"extractDetails": False,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["cardId"], item["city"], item["price"])
Other languages are listed on the Actor's API tab. This is the Apify Actor API, not an Oikotie API.
Data quality and record handling
- Card records always include
detailsScraped. It is false until a listing page is merged in. - Deduplicate on
cardId.idis the same listing number when it is numeric. vendorAdIdis a second identifier from the source. It was present on the saved Helsinki cards.- Price is euros.
pricePerSqmis euros per square meter.sizeis square meters.maintenanceFeeis euros. publishedis a source timestamp string, not a timezone-aware ISO value.- Overlapping locations can return the same
cardId. Compare that field before merging runs. - A failed detail request leaves the card record and does not set
detailsScrapedto true. - The
listing-detailscharge runs only after a successful enrichment. A card-only run chargesdataset-itemonly. - Contact email and phone exist only on enriched records and only when the listing page includes them.
Pricing and cost examples
The price file in the Actor folder sets $1 per 1,000 listings and $2 per 1,000 listing details. Registered event prices, the same on every plan:
| Event | When it is charged | Price |
|---|---|---|
dataset-item | Each listing pushed to the dataset | $0.001 |
listing-details | Each successful detail enrichment | $0.002 |
Platform usage, including compute and residential proxy, is billed separately by Apify. Estimates below assume every selected listing is pushed, and, in the enriched column, every one of those listings is enriched.
| Listings | Cards only | Cards plus details |
|---|---|---|
| 1,000 | $1.00 | $3.00 |
| 10,000 | $10.00 | $30.00 |
Limitations and responsible data use
- Results follow the public search you request. An empty location list is a nationwide search and can be large.
- Filters do not override query keys already present on a start URL.
- Office and contact fields are often missing on card-only records.
- Detail fields depend on the listing page. A missing energy class or email stays absent.
- Viewings and prices change on the source. This dataset is not a historical archive.
- Contact details are personal data when they identify a person. Use them in line with the privacy rules that apply to your project.
- You are responsible for complying with the site's terms and applicable law.
Dataset questions
What does one dataset item represent?
One Oikotie Asunnot listing. With extractDetails enabled and a successful fetch, the same record also contains listing-page fields and detailsScraped true.
Which field should I use as a unique identifier?
Use cardId. id repeats that number as an integer on saved cards.
Are fields nullable or conditional?
Yes. Lot size, office name, and the next viewing are null on some cards. Energy class, heating, and contact fields are only added when detailsScraped is true.
Can I retrieve the records as CSV or JSON?
Yes. Export the default dataset as JSON, CSV, Excel, XML, or another Apify format.
How do I paginate large datasets?
Set maxItems on the run. Read items with dataset limit and offset. 0 removes the Actor's item cap.
Does the Actor return historical data?
No. published is the listing's published time, not a history of price changes.
What counts as a billable result?
Each pushed listing charges dataset-item at $0.001. Each successful detail enrichment also charges listing-details at $0.002.
Related datasets from Data Scrapers
- Apartments Scraper collects apartment listings with price, size, and location fields.
- Aqar.fm Scraper collects Saudi listing cards you can compare on price, area, and city.
- Aengevelt Scraper collects property records from a commercial brokerage site.
- 99acres Scraper is a listings dataset with price and area fields.
- 99.co Scraper collects portal listings for the same kind of market comparison.
Data Scrapers support
Need an additional field, record type, or export workflow? Contact Data Scrapers at stardustspotlight@gmail.com. Include a sample source URL, required fields, expected record volume, and preferred delivery format.
