# Finn.no Næringseiendom Scraper - Norway Commercial Property (`studio-amba/finn-naering-scraper`) Actor

Scrape commercial real estate listings from Finn.no, Norway's dominant marketplace: offices, retail, warehouses and commercial plots (næringstomter) for rent or sale. Prices, rent per m2 per year, areas, addresses and agents.

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

## Pricing

from $1.20 / 1,000 result scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Finn.no Næringseiendom Scraper

Scrape commercial real estate listings from [Finn.no](https://www.finn.no), Norway's dominant marketplace with roughly 80% market share. This actor covers the three commercial property sections: lokaler til leie (premises for rent, ~4,500 active listings), næringseiendom til salgs (commercial property for sale, ~1,300 listings) and næringstomter (commercial plots, ~200 listings).

Each result is one flat JSON object per listing: headline, address, floor or plot area, segment labels (Kontor, Butikk/Handel, Lager/Logistikk, ...), asking price or rent per m2 per year where published, the advertising agency or private landlord, photo and listing URL.

### Why use it

- **Market research**: track asking prices and advertised rents per city, county or segment across Norway.
- **Lead generation**: every listing names the advertiser, either a commercial agency (DNB Næringsmegling, Akershus Eiendom, ...) or a private landlord.
- **Site selection**: filter offices, retail or warehouse space by location and compare available areas.
- **Investment screening**: sale listings include the asking price (Prisantydning) and the total price including costs (Totalpris).
- **Monitoring**: run it on a schedule and diff against yesterday's dataset to catch new listings the day they appear.

### How to scrape Finn.no data

1. Set **Location** to a Norwegian city, municipality or county: `Oslo`, `Bergen`, `Trondheim`, `Rogaland`, `Vestland`. Known places use Finn's own location filter, so you get exactly the listings in that area. Other place names run as a free-text search. Leave it empty to scrape all of Norway.
2. Pick a **Listing Type**: for rent (til leie), for sale (til salgs), commercial plots (næringstomt), or all three.
3. Pick a **Property Segment**: office (kontor), retail (butikk/handel), warehouse (lager/logistikk), industry, workshop, hotel, restaurant and more. Finn has no segment filter on plots.
4. Set **Max Results** and run. Results land in the dataset as one flat JSON object per listing.

Example: office space for rent in Oslo:

```json
{
    "searchQuery": "Oslo",
    "listingType": "rent",
    "segment": "office",
    "maxResults": 200
}
```

Example: commercial plots around Bergen:

```json
{
    "searchQuery": "Bergen",
    "listingType": "plots",
    "maxResults": 50
}
```

Example: warehouse and logistics space for sale, whole country:

```json
{
    "listingType": "sale",
    "segment": "warehouse",
    "maxResults": 500
}
```

An empty input `{}` works as well. It returns rental premises from all of Norway up to the default cap of 100.

### Input options

| Field | Type | Description |
|-------|------|-------------|
| `searchQuery` | string | City, municipality or county (e.g. `Oslo`, `Bergen`, `Trondheim`). A raw Finn location code (e.g. `0.20061`) also works. Empty = all of Norway. |
| `listingType` | string | `rent` (default), `sale`, `plots`, or `all` for all three sections. |
| `segment` | string | `all` (default), `office`, `retail`, `warehouse`, `industrial`, `combination`, `workshop`, `garage-parking`, `hotel`, `restaurant`, `shopping-centre`, `teaching-event`, `farm`, `apartment-building`, `other`. Applies to rent and sale. |
| `maxResults` | integer | Maximum listings to return (default 100, hard cap 2,500 per query). |
| `proxyConfiguration` | object | Proxy settings. The default automatic Apify proxy works; no residential proxy needed. |

### Output fields

| Field | Type | Example |
|-------|------|---------|
| `id` | string | `"473754929"` (finnkode) |
| `title` | string | `"Flott kontoretasje midt i Kvadraturen"` |
| `listingType` | string | `"rent"`, `"sale"` or `"plot"` |
| `segment` | string | null | `"Kontor"` |
| `segments` | array | `["Kontor", "Kombinasjonslokaler"]` |
| `price` | number | null | `2810` (rent, per m2 per year) or `6400000` (sale, total) |
| `currency` | string | `"NOK"` |
| `priceUnit` | string | null | `"NOK/m²/year"` (rent) or `"NOK total"` (sale/plot) |
| `priceText` | string | null | `"2 810 kr"` exactly as shown |
| `totalPrice` | number | null | `6401090` (Totalpris, sale/plot) |
| `surfaceM2` | number | null | `416` (null when the card shows a range) |
| `surfaceFromM2` | number | null | `10` |
| `surfaceToM2` | number | null | `500` |
| `surfaceText` | string | null | `"10 - 500 m²"` |
| `ownershipForm` | string | null | `"Selveier"` (sale listings) |
| `address` | string | null | `"Prinsens gate 22, Oslo"` |
| `city` | string | null | `"Oslo"` |
| `location` | string | null | Same as address |
| `sellerName` | string | null | `"Akershus Eiendom AS"` or `"Privat"` |
| `sellerType` | string | null | `"professional"` or `"private"` |
| `imageUrl` | string | null | Photo on images.finncdn.no |
| `promoted` | boolean | `true` for paid placements |
| `url` | string | Full listing URL on Finn.no |
| `source` | string | `"finn.no"` |
| `scrapedAt` | string | ISO 8601 timestamp |

### Example output

```json
{
    "id": "473754929",
    "title": "Flott kontoretasje midt i Kvadraturen med god takhøyde og store vinduer",
    "listingType": "rent",
    "segment": "Kontor",
    "segments": ["Kontor"],
    "price": null,
    "currency": "NOK",
    "priceUnit": null,
    "priceText": null,
    "totalPrice": null,
    "surfaceM2": 416,
    "surfaceFromM2": 416,
    "surfaceToM2": 416,
    "surfaceText": "416 m²",
    "ownershipForm": null,
    "address": "Prinsens gate 22, Oslo",
    "city": "Oslo",
    "location": "Prinsens gate 22, Oslo",
    "sellerName": "Akershus Eiendom AS",
    "sellerType": "professional",
    "imageUrl": "https://images.finncdn.no/dynamic/480w/2026/8/vertical-7/18/9/473/754/929_e2a26745.jpg",
    "promoted": false,
    "url": "https://www.finn.no/realestate/businessrent/ad.html?finnkode=473754929",
    "source": "finn.no",
    "scrapedAt": "2026-08-18T11:33:01.791Z"
}
```

### Prices: what to expect

Commercial real estate is a price-on-application market and the actor never invents numbers:

- **Rent listings** rarely publish a price (roughly 1 in 20). When they do, it is the standard Norwegian commercial quote: kroner per m2 per year (`priceUnit: "NOK/m²/year"`).
- **Sale listings** publish an asking price on about 90% of listings, plus a separate Totalpris including costs.
- **Plots** are priced like sale listings.

When no price is shown, `price`, `priceUnit` and `priceText` are null. Area, segment, address and advertiser are populated on effectively every listing.

### Cost estimate

The actor charges per result plus a small run start fee. At $0.002 per result, $1 buys roughly 500 listings. A full scrape of the rental section (~4,500 listings) costs about $9 in result fees plus a few cents of compute. Runs are fast: 60 results take a few seconds, a full section a few minutes.

Note: a run's usage cost only settles after the run reports SUCCEEDED. Reading the dataset mid-run shows a cost that is far too low and misleads any spend estimate based on a partial run.

### Limitations

- Finn caps any single query at 50 result pages (about 2,500 listings). To cover more, split the work across locations or segments in separate runs.
- The segment filter does not apply to plots (Finn has no such filter on næringstomter).
- Rent prices are only available where the advertiser publishes them (see the price section above).
- One listing can appear in the output as promoted (`promoted: true`) when the advertiser paid for placement; promoted cards are deduplicated against organic results by finnkode.
- The actor scrapes listing cards, not detail pages. Fields shown only on the detail page (full description, energy label, viewing times, contact details beyond the advertiser name) are not included.

# Actor input Schema

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

City, municipality or county to search (e.g. 'Oslo', 'Bergen', 'Trondheim', 'Rogaland'). Known places use Finn's own location filter; anything else runs as a free-text search. A raw Finn location code (e.g. '0.20061') also works. Leave empty to search all of Norway.

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

Finn splits commercial property into three sections: lokaler til leie (rent), næringseiendom til salgs (sale) and næringstomter (commercial plots). 'All' scrapes all three.

## `segment` (type: `string`):

Type of premises (Type lokale). Applies to rent and sale; Finn has no segment filter on plots. 'All segments' returns everything.

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

Maximum number of listings to return. Finn caps any single query at 50 pages (about 2,500 results) — narrow by location or segment to cover more of the portal.

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

Proxy settings. Recon found no anti-bot on Finn's commercial search pages (see docs/site-recon/finn-naering.md), so the free automatic proxy pool is the default.

## Actor input object example

```json
{
  "searchQuery": "Oslo",
  "listingType": "rent",
  "segment": "all",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

# 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 = {
    "searchQuery": "Oslo",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/finn-naering-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 = {
    "searchQuery": "Oslo",
    "maxResults": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/finn-naering-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 '{
  "searchQuery": "Oslo",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call studio-amba/finn-naering-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,studio-amba/finn-naering-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/bVvn4dh3IXsCVdaZo/builds/NcGksIh7HroEZ7RRx/openapi.json
