# Finn.no Real Estate Scraper (`datascrapers/finn-no-scraper`) Actor

Scrape Norwegian real-estate listings from Finn.no with search URL or filter-based discovery, optional full details and broker contact info.

- **URL**: https://apify.com/datascrapers/finn-no-scraper.md
- **Developed by:** [Data Scrapers](https://apify.com/datascrapers) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 listings

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

**Finn.no Real Estate Scraper** creates a structured dataset of Norwegian home listings collected from Finn.no. Each dataset item can include the listing id, title, location, asking and total price, usable area, rooms, property type, ownership, energy label, broker organisation, and publication time. Query the source with a Finn search URL or with filters for area, price, size, and housing type. Control the result limit with `maxItems`, and optionally request full listing details or broker contact. Retrieve records through the Apify Dataset API or export them as JSON, CSV, Excel, XML, or another supported format.

[![Finn.no Real Estate Scraper — search to structured listings](https://raw.githubusercontent.com/faizanalii/apify-actor-assets/main/finn-no-scraper/finn-no-scraper-value-demo.gif)](https://apify.com/datascrapers/finn-no-scraper)

### Dataset at a glance

| Property | Value |
|---|---|
| Source | finn.no |
| Record unit | One home listing |
| Input methods | `startUrls`, or filters such as `locations`, price, and `propertyTypes` |
| Main identifiers | `id`, `url` |
| Delivery | Apify Dataset and API |
| Export formats | JSON, CSV, Excel, XML |
| Update model | Fresh records per Actor run |
| Pricing | $1.00 per 1,000 listings. Detail and broker events are $2.00 per 1,000. Platform usage is billed separately. |

### Coverage and available records

The Actor collects homes for sale from Finn.no. A `startUrls` entry is a Finn homes search URL. When no start URL is set, the Actor builds a search from the filter fields. `maxItems` stops the run after that many saved listings. `0` is not used; the schema default is 50.

`scrapeDetails` loads the listing page and charges `detailed-listing` when that page is saved. `includeContactInfo` charges `broker-info` when a contact block is saved. Search-card rows have `source` other than `detail` and do not include the detail-only fields. Sold, rental, and commercial Finn sections outside the homes search are not collected by this input.

### Data dictionary

| Field | Type | Nullable | Description | Example |
|---|---|---:|---|---|
| id | string | no | Finn listing code. Deduplication key. | 470675677 |
| url | string | yes | Public listing page | https://www.finn.no/realestate/homes/ad.html?finnkode=470675677 |
| title | string | yes | Listing title | Enebolig med 3 soverom |
| location | string | yes | Address text | Skøelvdalen 231, 9310 Sørreisa |
| priceSuggestion | number | yes | Asking price, NOK | 1250000 |
| priceTotal | number | yes | Total price, NOK | 1282340 |
| priceSharedCost | number | yes | Shared monthly cost, NOK | 0 |
| areaUsable | number | yes | Usable area, square meters | 172 |
| bedrooms | number | yes | Bedroom count | 3 |
| rooms | number | yes | Room count | 4 |
| propertyType | string | yes | Housing type | Enebolig |
| ownershipType | string | yes | Ownership | Selveier |
| constructionYear | number | yes | Year built | 1958 |
| energyLabel | string | yes | Energy label | E |
| organisationName | string | yes | Broker organisation | EiendomsMegler 1 Finnsnes |
| publishedAt | string | yes | Publication time, ISO-8601 | 2026-07-24T17:42:00+00:00 |
| imageUrl | string | yes | Primary image | https://images.finncdn.no/dynamic/default/2026/7/vertical-2/24/7/470/675/677_8685aebe-5ba0-4089-aa60-1321d855748a.jpg |
| latitude | number | yes | Latitude | 69.11598 |
| longitude | number | yes | Longitude | 18.01850 |
| source | string | yes | `detail` when the listing page was fetched | detail |

### Example dataset record

```json
{
  "id": "470675677",
  "url": "https://www.finn.no/realestate/homes/ad.html?finnkode=470675677",
  "title": "Enebolig med 3 soverom | Balkong, terrasse og garasje | Ligger landlig til i Skøelvdalen",
  "location": "Skøelvdalen 231, 9310 Sørreisa",
  "priceSuggestion": 1250000,
  "priceTotal": 1282340,
  "priceSharedCost": 0,
  "areaUsable": 172,
  "bedrooms": 3,
  "rooms": 4,
  "propertyType": "Enebolig",
  "ownershipType": "Selveier",
  "constructionYear": 1958,
  "energyLabel": "E",
  "organisationName": "EiendomsMegler 1 Finnsnes",
  "publishedAt": "2026-07-24T17:42:00+00:00",
  "imageUrl": "https://images.finncdn.no/dynamic/default/2026/7/vertical-2/24/7/470/675/677_8685aebe-5ba0-4089-aa60-1321d855748a.jpg",
  "latitude": 69.11598185054471,
  "longitude": 18.018504483094624,
  "source": "detail"
}
```

This row came from a Finn homes search for location code `0.20061` with `scrapeDetails` enabled.

### Query and input reference

| Input | Type | Required | Default | Accepted values | Description |
|---|---|---:|---|---|---|
| startUrls | array | no | empty | Finn homes search URLs | Direct search pages. Used ahead of the filter fields. |
| searchQuery | string | no | empty | Free text | Keyword on the homes search. |
| publishedToday | boolean | no | false | true, false | Limit to listings published today. |
| locations | array | no | empty | Finn area ids | Counties or areas. |
| saleStatus | array | no | empty | Schema enum | Sale status filter. |
| propertyCondition | string | no | empty | Schema enum | Condition filter. |
| priceFrom | integer | no | empty | NOK | Minimum asking price. |
| priceTo | integer | no | empty | NOK | Maximum asking price. |
| totalPriceFrom | integer | no | empty | NOK | Minimum total price. |
| totalPriceTo | integer | no | empty | NOK | Maximum total price. |
| sharedCostFrom | integer | no | empty | NOK | Minimum shared monthly cost. |
| sharedCostTo | integer | no | empty | NOK | Maximum shared monthly cost. |
| areaFrom | integer | no | empty | Square meters | Minimum usable area. |
| areaTo | integer | no | empty | Square meters | Maximum usable area. |
| minBedrooms | integer | no | empty | Integer | Minimum bedrooms. |
| constructionYearFrom | integer | no | empty | Year | Oldest year built. |
| constructionYearTo | integer | no | empty | Year | Newest year built. |
| plotAreaFrom | integer | no | empty | Square meters | Minimum plot size. |
| plotAreaTo | integer | no | empty | Square meters | Maximum plot size. |
| propertyTypes | array | no | empty | Schema enum | Housing types. |
| ownershipTypes | array | no | empty | Schema enum | Ownership types. |
| sellerTypes | array | no | empty | Schema enum | Private or broker. |
| facilities | array | no | empty | Schema enum | Facility filters. |
| energyLabels | array | no | empty | Schema enum | Energy labels. |
| floors | array | no | empty | Schema enum | Floor filters. |
| videoTypes | array | no | empty | Schema enum | Digital viewing filters. |
| scrapeDetails | boolean | no | false | true, false | Fetch each listing page. Charges `detailed-listing`. |
| includeContactInfo | boolean | no | false | true, false | Save broker contact when present. Charges `broker-info`. |
| maxItems | integer | no | 50 | 0 or a positive integer | Maximum listings saved. |
| proxyConfiguration | object | no | Apify residential | Apify proxy input | Proxy used for Finn requests. |

Minimal request:

```json
{
  "startUrls": [{ "url": "https://www.finn.no/realestate/homes/search.html?location=0.20061" }],
  "maxItems": 5
}
```

### Retrieve the data through the API

Start the Actor with JSON input, wait for the run, then read the default dataset. Other languages are on the Actor API tab.

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("datascrapers/finn-no-scraper").call(run_input={
    "startUrls": [{"url": "https://www.finn.no/realestate/homes/search.html?location=0.20061"}],
    "maxItems": 5,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["id"], item.get("priceSuggestion"))
```

### Data quality and record handling

Use `id` as the deduplication key. A search-card row and a later detail row for the same Finn code share that id. Prices are numeric NOK amounts, not formatted strings. `publishedAt` is an ISO-8601 timestamp. A listing page that fails is skipped and is not saved. Contact blocks can include an organisation name. Person names from those blocks are not part of the example above.

### Pricing and cost examples

| Event | Free | Bronze | Silver | Gold |
|---|---:|---:|---:|---:|
| dataset-item | $1.00 | $1.00 | $1.00 | $1.00 |
| detailed-listing | $2.00 | $2.00 | $2.00 | $2.00 |
| broker-info | $2.00 | $2.00 | $2.00 | $2.00 |

Prices are per 1,000 events. Platinum and Diamond use the Gold price. Platform usage is billed separately. A run that saves 1,000 search cards costs $1.00 before platform usage. The same run with details and broker contact, when both succeed, also charges 1,000 `detailed-listing` events and 1,000 `broker-info` events.

### Limitations and responsible data use

Finn can change search markup, require a proxy, or omit fields on some listings. Results are a snapshot of one run, not a historical archive. Use the data under Finn.no's terms and applicable privacy rules. Do not treat missing contact fields as proof that a listing has no broker.

### Dataset questions

#### Can I search without a Finn URL?

Yes. Leave `startUrls` empty and set filters such as `locations`, `priceFrom`, `priceTo`, and `propertyTypes`.

#### When is a row a detail record?

`source` is `detail` after `scrapeDetails` saves the listing page. Search-card rows do not carry that source value.

#### Which field should I store as the key?

Store `id`. It is the Finn code in the listing URL.

### Related datasets from Data Scrapers

- [Hemnet.se Scraper](https://apify.com/datascrapers/hemnet-se-scraper) for Swedish listings.
- [Booli Sweden Scraper](https://apify.com/datascrapers/booli-se) for another Swedish homes source.
- [Boliga Denmark Scraper](https://apify.com/datascrapers/boliga-dk) for Danish listings.
- [Daft.ie Property Scraper](https://apify.com/datascrapers/daft-ie-scraper) for Irish listings.
- [DAHLER Real Estate Scraper](https://apify.com/datascrapers/dahler-scraper) for German listings.

### Data Scrapers support

Questions about this dataset: stardustspotlight@gmail.com

# Actor input Schema

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

Preferred input. Finn.no real-estate search page URLs (search.html with any filters already applied), e.g. https://www.finn.no/realestate/homes/search.html?location=0.20061\&property_type=3. When provided, these take priority over structured filters below.

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

Free-text search in Finn Eiendom (q). Used when building a search from filters (or ignored when startUrls already encode the query).

## `publishedToday` (type: `boolean`):

Only listings published today (published=1 / Nye i dag).

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

Norwegian counties or Finn location codes. Names (Oslo, Nordland, Innlandet, Finnmark, …) are mapped to Finn codes; you can also paste codes such as 0.20061.

## `saleStatus` (type: `array`):

Salgsstatus: for sale, sold last 3 days, or coming for sale.

## `propertyCondition` (type: `string`):

Tilstand: used housing or new construction.

## `priceFrom` (type: `integer`):

Minimum asking price in NOK (price_from).

## `priceTo` (type: `integer`):

Maximum asking price in NOK (price_to).

## `totalPriceFrom` (type: `integer`):

Minimum total price in NOK (price_collective_from).

## `totalPriceTo` (type: `integer`):

Maximum total price in NOK (price_collective_to).

## `sharedCostFrom` (type: `integer`):

Minimum common expenses per month in NOK (rent_from / fellesutgifter).

## `sharedCostTo` (type: `integer`):

Maximum common expenses per month in NOK (rent_to).

## `areaFrom` (type: `integer`):

Minimum living area in square meters (area_from).

## `areaTo` (type: `integer`):

Maximum living area in square meters (area_to).

## `minBedrooms` (type: `integer`):

Minimum number of bedrooms (1–5 maps to Finn min_bedrooms).

## `constructionYearFrom` (type: `integer`):

Earliest construction year (construction_year_from).

## `constructionYearTo` (type: `integer`):

Latest construction year (construction_year_to).

## `plotAreaFrom` (type: `integer`):

Minimum plot / tomt size (plot_area_from).

## `plotAreaTo` (type: `integer`):

Maximum plot / tomt size (plot_area_to).

## `propertyTypes` (type: `array`):

Boligtype filters (apartment, detached, townhouse, semi-detached, farm, etc.).

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

Eierform: stock, share, bond, freeholder, other.

## `sellerTypes` (type: `array`):

Privat/Megler filter.

## `facilities` (type: `array`):

Fasiliteter such as balcony, elevator, garage, view, EV charging, etc.

## `energyLabels` (type: `array`):

Energikarakter A–G.

## `floors` (type: `array`):

Etasje filter values: NOTFIRST, 1–6, or BIG (over 6th floor).

## `videoTypes` (type: `array`):

Digitale visninger: video and/or 360°.

## `scrapeDetails` (type: `boolean`):

When enabled, opens each listing and extracts full details (description, all images, facilities, viewings, cadastre, etc.). Slower but much richer output.

## `includeContactInfo` (type: `boolean`):

When enabled, extracts agent/broker or private seller contact information (phone, email). Performs a detail page fetch per listing.

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

Maximum number of listings to scrape (0 = unlimited).

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

Apify proxy settings. Residential proxies are recommended for Finn.no.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.finn.no/realestate/homes/search.html?location=0.20061"
    }
  ],
  "searchQuery": "",
  "publishedToday": false,
  "propertyCondition": "",
  "scrapeDetails": false,
  "includeContactInfo": false,
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset containing scraped Finn.no real-estate listings

## `runStats` (type: `string`):

Key-value store record with recordsScraped and run timestamps

# 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.finn.no/realestate/homes/search.html?location=0.20061"
        }
    ],
    "searchQuery": "",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("datascrapers/finn-no-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.finn.no/realestate/homes/search.html?location=0.20061" }],
    "searchQuery": "",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("datascrapers/finn-no-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 '{
  "startUrls": [
    {
      "url": "https://www.finn.no/realestate/homes/search.html?location=0.20061"
    }
  ],
  "searchQuery": "",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call datascrapers/finn-no-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datascrapers/finn-no-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/5MskgGJXXhSERgQQZ/builds/IpfTgWYZJZeN3ayOh/openapi.json
