# Objektvision Scraper — Swedish Commercial Property (`studio-amba/objektvision-scraper`) Actor

Scrape Objektvision.se for Swedish commercial property: offices, retail, warehouses, industrial space and land. Rent/price, price unit (kr/m²/år), surface, location and segment.

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

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

## Objektvision Scraper — Swedish Commercial Property

Scrape [Objektvision.se](https://objektvision.se), Sweden's largest commercial
property marketplace, into clean structured data. Offices, retail, warehouses,
industrial space, coworking and land, with rent or asking price, surface,
location and segment. The whole of Sweden, or a single city or county.

Objektvision lists roughly 19,000 rental objects nationwide plus commercial
properties and companies for sale. This actor reads the public listings and,
by default, each object's detail page for the full record.

### What you get

One row per object, with:

- Rent or asking price in SEK, plus the exact Swedish price unit
  (`kr/m²/år`, `kr/mån`, `kr`) captured as text and never converted
- Surface in square metres (and the raw string, which can be a range)
- Segment (Kontor, Butik, Lager & logistik, Industri & verkstad, Kontorshotell & coworking)
- Street address, area and city
- Access date (Tillträde)
- Full description text, the object image and the source URL

### Who it is for

- Tenant reps and commercial brokers tracking available space in a city or region
- Investors and analysts building a view of the Swedish commercial market
- Proptech and market-intelligence teams that need a Sweden feed alongside the rest of Europe
- Anyone comparing office, retail or warehouse supply across Swedish cities

### How to scrape Objektvision data

1. Set **Location** to a Swedish city or county, e.g. `stockholm`, `göteborg`,
   `malmö`, `uppsala`, or a county like `skåne län`. Leave it empty to scrape
   all of Sweden. Native Swedish spelling (å, ä, ö) works.
2. Choose a **Listing type**: `rent` (lediga lokaler), `sale` (commercial
   properties for sale) or `companies` (företag till salu).
3. Optionally set a **Segment** to keep only offices, retail, warehouses, etc.
4. Set **Max results** to cap the run.
5. Run the actor. Results stream into the dataset and can be exported as JSON,
   CSV or Excel.

#### Example inputs

Offices to rent in Stockholm:

```json
{
  "searchQuery": "stockholm",
  "listingType": "rent",
  "segment": "kontor",
  "maxResults": 100
}
```

Warehouses to rent across all of Sweden:

```json
{
  "searchQuery": "",
  "listingType": "rent",
  "segment": "lager",
  "maxResults": 500
}
```

Commercial property for sale in Göteborg:

```json
{
  "searchQuery": "göteborg",
  "listingType": "sale",
  "maxResults": 50
}
```

### Input reference

| Field | Type | Description |
|---|---|---|
| `searchQuery` | string | Swedish city or county. Empty = all of Sweden. |
| `listingType` | select | `rent`, `sale` or `companies`. Default `rent`. |
| `segment` | select | Keep only one segment (kontor, butik, lager, industri, coworking, mark, ovrigt). Empty = all. Applied to each object's own category label. |
| `maxResults` | integer | Stop after this many objects. Default 100. |
| `fetchDetails` | boolean | On by default. Opens each object's detail page for rent/price, price unit, access date and full description. Turn off for a faster, thinner listing-only scan with no price (cards do not show price). This changes how COMPLETE each record is, not just how many you get. |
| `proxyConfiguration` | object | RESIDENTIAL + country SE, required (see below). |

### Output fields

| Field | Type | Example |
|---|---|---|
| `objectId` | string | `"198008684"` |
| `heading` | string | `"Ledig lokal, Norrlandsgatan 12, City, Stockholm"` |
| `segment` | string | `"Kontor"` |
| `listingType` | string | `"rent"` |
| `price` | number | null | `6800` (null when the object quotes "Kontakta annonsören") |
| `currency` | string | `"SEK"` |
| `priceUnit` | string | null | `"kr/m²/år"` |
| `priceRaw` | string | null | `"6 800 kr/m²/år"` |
| `surface` | number | null | `225` |
| `surfaceRaw` | string | null | `"225 m²"` |
| `streetAddress` | string | null | `"Norrlandsgatan 12"` |
| `location` | string | null | `"City, Stockholm"` |
| `city` | string | null | `"Stockholm"` |
| `accessDate` | string | null | `"2026-11-01"` |
| `descriptionText` | string | null | Full object description |
| `agentId` | string | null | `"26033"` |
| `imageUrl` | string | null | First object image |
| `url` | string | `"https://objektvision.se/Beskriv/198008684"` |
| `source` | string | `"objektvision.se"` |
| `scrapedAt` | string | ISO 8601 timestamp |
| `searchQuery` | string | null | Location input echo |

#### Example output

```json
{
  "objectId": "268036543",
  "heading": "3500 kvm i ett plan med genomgående 4,5 meter i takhöjd",
  "segment": "Kontor",
  "listingType": "rent",
  "price": 6800,
  "currency": "SEK",
  "priceUnit": "kr/m²/år",
  "priceRaw": "6 800 kr/m²/år",
  "surface": 3475,
  "surfaceRaw": "3 475 m²",
  "streetAddress": "Fleminggatan 14",
  "location": "Kungsholmen, Stockholm",
  "city": "Stockholm",
  "accessDate": "Ca 6-9 mån efter signing",
  "url": "https://objektvision.se/Beskriv/268036543",
  "source": "objektvision.se",
  "scrapedAt": "2026-08-18T10:00:00.000Z"
}
```

### A note on price

Swedish commercial property very often quotes rent and asking price as
"Kontakta annonsören" (contact the advertiser). When that is the case, `price`
and `priceUnit` are `null` and `currency` stays `SEK`. This is the source's own
practice, not a gap in the scraper. Surface, segment, location and address are
present on nearly every object. Rent, when published, is usually quoted per
square metre per year (`kr/m²/år`).

### Proxy

RESIDENTIAL + country SE is required. Objektvision is behind a Cloudflare
Turnstile clearance gate; a Swedish residential IP is what passes it, and the
clearance is IP-scoped. The actor handles the gate for you. Keep the proxy on
Swedish residential.

### Cost

Pricing is pay per result. Detail fetching spends one request per object, plus
one browser warm-up per run to pass the clearance gate. As a rough guide, at the
listed per-result price 1,000 objects with detail fetching on cost about $5 in
result fees plus proxy and compute. Turning `fetchDetails` off lowers the per-run
cost and returns about 40 objects per request, but without price.

A run's usage cost only settles after it reports SUCCEEDED. A dataset read taken
while a run is still in progress shows a cost far below the final figure, so size
your spend from a completed run, not a partial one.

### Limitations

- Price is null whenever the object quotes "Kontakta annonsören" (common).
- Segment filtering is applied to each object's own category label, so a narrow
  segment fetches listing pages and keeps the matching objects.
- Land (Mark) objects are reachable through the segment filter but do not have a
  dedicated SEO listing path.
- The site is Swedish-language; field values are returned as published.

# Actor input Schema

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

Swedish city or county to search, e.g. 'stockholm', 'göteborg', 'malmö', 'uppsala', or a county like 'skåne län'. Leave empty to scrape all of Sweden. Native Swedish spelling works (å, ä, ö).

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

Which market to read: spaces to rent (lediga lokaler), commercial properties for sale, or companies for sale.

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

Keep only objects whose category matches this segment. Applied to the object's own category label, so it narrows the result without changing the market. Leave empty for all segments.

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

Stop after this many objects. Objektvision has ~19,000 rental objects nationwide, so a cap keeps runs bounded. One request per object is spent when detail fetching is on.

## `fetchDetails` (type: `boolean`):

On (default): open each object's detail page to get rent/price, price unit (kr/m²/år), access date and the full description. Off: a faster, thinner listing-only scan with no price (cards do not show price). This flag changes how COMPLETE each record is, not just how many you get.

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

RESIDENTIAL + country SE is required. Objektvision is behind a Cloudflare Turnstile clearance gate (see docs/site-recon/objektvision.md); a Swedish residential IP is the only pool that passes it, and the clearance cookie is IP-scoped so every follow-up request must stay on Swedish residential. Do not switch this off.

## Actor input object example

```json
{
  "searchQuery": "stockholm",
  "listingType": "rent",
  "segment": "",
  "maxResults": 20,
  "fetchDetails": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "SE"
  }
}
```

# 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": "stockholm",
    "listingType": "rent",
    "segment": "",
    "maxResults": 20,
    "fetchDetails": true,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "SE"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/objektvision-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": "stockholm",
    "listingType": "rent",
    "segment": "",
    "maxResults": 20,
    "fetchDetails": True,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "SE",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/objektvision-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": "stockholm",
  "listingType": "rent",
  "segment": "",
  "maxResults": 20,
  "fetchDetails": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "SE"
  }
}' |
apify call studio-amba/objektvision-scraper --silent --output-dataset

```

## MCP server setup

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