# Imovirtual Scraper — Portugal Real Estate Data (`logiover/imovirtual-pt-scraper-portugal-real-estate`) Actor

Scrape real estate listings from Imovirtual.com — Portugal's major property portal (OLX Group). No browser, no API key. Filter by location, buy/rent, property type, price (EUR), area, rooms and owner type. Returns price, m², price/m², full Portuguese address, agency and image gallery per listing.

- **URL**: https://apify.com/logiover/imovirtual-pt-scraper-portugal-real-estate.md
- **Developed by:** [Logiover](https://apify.com/logiover) (community)
- **Categories:** Real estate, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.50 / 1,000 results

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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## Imovirtual Scraper — Scrape Portugal Real Estate Listings & Prices

Scrape property listings from **Imovirtual.com**, one of Portugal's largest real estate portals (OLX Group), with hundreds of thousands of active listings. This Imovirtual scraper extracts apartments, houses (moradias), plots/land, commercial property, warehouses, garages, rooms and new developments — by location, transaction type (buy or rent), price in EUR, area, rooms (T-typology), market and owner type. It returns price, price/m², full Portuguese address breakdown (distrito, concelho, freguesia), agency details and image galleries via direct `__NEXT_DATA__` JSON parsing — **fast, no browser, no API key required.** Export Portuguese real estate data to JSON, CSV or Excel.

### ✨ What this Actor does / Key features

- 🏠 **9 property categories** — apartments, houses/moradias, plots/land, commercial, warehouses, garages, rooms, studios (T0) and new developments, for sale or rent.
- 📍 **Nationwide location targeting** — scrape all of Portugal, any district (distrito), council (concelho) or parish (freguesia) via location slugs.
- 💰 **Powerful filters** — price range (EUR), area range (m²), room range (T-typology), market (primary/secondary), owner type and distance radius.
- 🔀 **Flexible sorting** — by latest, price, price/m² or area, ascending or descending.
- 🗺️ **Full Portuguese address** — district, council, parish, neighborhood and street for every listing (GPS and postal code available on detail pages).
- 🏢 **Agency data embedded** — agency name, ID, slug, logo and type, plus exclusivity, featured and promoted flags.
- 🖼️ **Image galleries** — main image URL, preview image URLs and total image count.
- ⚡ **Direct HTTP + JSON extraction** — parses Imovirtual's `__NEXT_DATA__` payload; no browser, no DOM walking, no GraphQL token.
- 🛡️ **Proxy support** — Apify Proxy integration; residential + country=PT strongly recommended to avoid blocks.

Because Imovirtual belongs to the same OLX Group platform family as Otodom (Poland) and shares the same Next.js SSR data structure, this Actor reads the site's own embedded listing JSON directly — the fastest and most reliable way to get structured Portuguese property data without an official API.

### 🔍 Input

| Field | Type | Description |
|-------|------|-------------|
| `locationSlugs` | array | Imovirtual URL location paths. Each slug becomes its own task (e.g. `lisboa`, `porto`, `lisboa/cascais`, `todo-o-pais`). **Required.** |
| `transaction` | string | `sale` (comprar) or `rent` (arrendar). |
| `propertyType` | string | `apartment`, `house`, `plot`, `commercial`, `warehouse`, `garage`, `room`, `development` or `studio`. |
| `priceMin` | integer | Minimum price in EUR. 0 = no minimum. |
| `priceMax` | integer | Maximum price in EUR. 0 = no maximum. |
| `areaMin` | integer | Minimum surface area in m². 0 = no minimum. |
| `areaMax` | integer | Maximum surface area in m². 0 = no maximum. |
| `roomsMin` | integer | Minimum room count / T-typology (T0–T10). 0 = no minimum. |
| `roomsMax` | integer | Maximum room count / T-typology (T0–T10). 0 = no maximum. |
| `market` | string | `ALL`, `PRIMARY` (new build) or `SECONDARY` (resale). |
| `ownerType` | string | `ALL`, `PRIVATE` or `AGENCY`. |
| `sort` | string | Result ordering: latest, price_asc/desc, price_per_m_asc/desc, area_asc/desc. |
| `distanceRadius` | integer | Expand search to nearby areas: 0, 5, 10, 15, 25, 50 or 75 km. |
| `limit` | integer | Listings per page: 24, 36, 48 or 72. |
| `maxListings` | integer | Total cap across all location tasks. 0 = unlimited. |
| `maxPagesPerTask` | integer | Pagination depth per location. |
| `requestDelay` | integer | Delay between page requests in milliseconds (keep ≥ 600 ms). |
| `maxRetries` | integer | Retries per request on HTTP errors (rotates proxy IP). |
| `proxyConfiguration` | object | Apify Proxy settings. Residential with country=PT strongly recommended. |

### 🚀 Example input

```json
{
  "locationSlugs": ["lisboa", "porto"],
  "transaction": "sale",
  "propertyType": "apartment",
  "priceMin": 200000,
  "priceMax": 600000,
  "areaMin": 50,
  "areaMax": 120,
  "roomsMin": 2,
  "roomsMax": 3,
  "market": "SECONDARY",
  "ownerType": "ALL",
  "sort": "latest",
  "distanceRadius": 0,
  "limit": 72,
  "maxListings": 500,
  "maxPagesPerTask": 10,
  "requestDelay": 800,
  "maxRetries": 3,
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "PT" }
}
````

> **Finding a location slug:** browse imovirtual.com, apply a location filter, and copy the path between `/resultados/{txn}/{type}/` and `?` from the URL. Use `todo-o-pais` for all of Portugal, a district slug like `lisboa`, `porto`, `faro`, `braga` or `setubal`, a council like `lisboa/cascais`, or a parish like `lisboa/cascais/cascais-e-estoril`. These slugs follow the Portuguese administrative hierarchy (distrito → concelho → freguesia).

### 📦 Output

Each property listing is saved as a structured item in the dataset. Export to JSON, CSV, Excel or XML, or pull via the Apify API.

| Field | Description |
|-------|-------------|
| `adId` | Imovirtual's stable listing ID |
| `detailUrl` | Full listing detail URL |
| `slug` | Listing URL slug |
| `title` | Listing title |
| `shortDescription` | Short description / snippet |
| `transactionType` | sale or rent |
| `propertyType` | Property type (apartment, house, etc.) |
| `estate` | Raw estate enum (FLAT, HOUSE, TERRAIN, COMMERCIAL\_PROPERTY, HALL, GARAGE, ROOM, INVESTMENT) |
| `advertType` | Advert type (AGENCY, PRIVATE, etc.) |
| `isPrivate` | Whether the listing is from a private owner |
| `market` | PRIMARY (new build) or SECONDARY (resale) |
| `price` | Listing price |
| `priceCurrency` | Currency code (EUR) |
| `pricePerSqm` | Price per square meter (EUR/m²) |
| `monthlyRent` | Recurring monthly rent (for rentals) |
| `areaSqm` | Surface area in m² |
| `terrainAreaSqm` | Terrain / plot area in m² |
| `rooms` | Number of bedrooms (T-typology) |
| `floor` | Floor (enum, e.g. GROUND, SECOND) |
| `totalFloors` | Total floors in the building |
| `province` | District (distrito) |
| `county` | Council (concelho / município) |
| `city` | Parish (freguesia) / city label |
| `district` | Neighborhood (bairro) |
| `street` | Street |
| `postalCode` | Postal code (detail pages only) |
| `fullAddress` | Composed full address |
| `latitude` | GPS latitude (detail pages only) |
| `longitude` | GPS longitude (detail pages only) |
| `mainImageUrl` | Main listing image URL |
| `imageUrls` | Array of preview image URLs |
| `imageCount` | Number of preview images |
| `totalPossibleImages` | Total images on the full listing |
| `contactName` | Listing contact / seller name |
| `agencyId` | Agency ID |
| `agencyName` | Agency name |
| `agencySlug` | Agency slug |
| `agencyLogoUrl` | Agency logo URL |
| `agencyType` | Agency type |
| `isExclusive` | Exclusive listing flag |
| `isFeatured` | Featured listing flag |
| `isPromoted` | Promoted listing flag |
| `hasOpenDay` | Whether the listing has an open day |
| `developmentName` | Development / investment name (for primary market) |
| `investmentState` | Development / investment state |
| `source` | Listing source / partner feed |
| `dateCreated` | Date the listing was created |
| `dateCreatedFirst` | Date the listing was first created |
| `pushedUpAt` | Date the listing was last bumped |
| `labels` | Feature/amenity tags (AIR\_CONDITIONING, BALCONY, PARKING\_SPOT, ...) |
| `searchTransaction` | Transaction type used for this search |
| `searchPropertyType` | Property type used for this search |
| `searchLocation` | Location slug used for this search |
| `searchUrl` | Full search URL used |
| `scrapedAt` | Scrape timestamp (ISO 8601) |

### 💡 Use cases

- **Market research** — build EUR/m² heatmaps by district, council and parish across Portugal.
- **Investment screening** — calculate rental yield (monthly rent vs. sale price) per area, from Lisboa and Porto to the Algarve.
- **Lead generation** — use `ownerType: PRIVATE` to find direct-owner listings, or cluster agency listings by `agencyId`.
- **Price tracking** — re-run on a schedule and diff against prior datasets using `dateCreated` and `pushedUpAt`.
- **Primary-market monitoring** — use `propertyType: development` or `market: PRIMARY` to track new developer offers.
- **Cross-city comparison** — pass multiple `locationSlugs` in one run to benchmark prices across Portuguese cities.

### ❓ Frequently Asked Questions

**Is it legal to scrape Imovirtual.com?**
The Actor only collects publicly available property listing data. You are responsible for using the data in compliance with Imovirtual's terms and applicable laws such as the GDPR.

**Does Imovirtual.com have a public API?**
Imovirtual does not offer an open public data API for listings, so this Actor reads the site's own embedded `__NEXT_DATA__` JSON instead — giving you structured Portuguese real estate data without any API key.

**Do I need an API key or a login?**
No. There is no Imovirtual account, login or API key required — only an Apify account.

**Do I need a proxy?**
Imovirtual deploys mild bot protection. Datacenter proxies often get blocked, so residential Apify Proxy with country=PT is strongly recommended; the Actor runs cleanly with it at a ≥600 ms request delay.

**How do I target a specific city, council or parish?**
Imovirtual uses URL location slugs following Portugal's distrito → concelho → freguesia hierarchy. Browse imovirtual.com, apply a location filter, and copy the path from the URL. Examples: `lisboa`, `porto`, `lisboa/cascais`, `lisboa/cascais/cascais-e-estoril`.

**How much data can I get?**
You can scrape thousands of listings per run. Imovirtual paginates deep filter sets, so narrow with price and area filters to reach the full inventory across multiple locations.

**Does it return rental prices separately?**
Yes. For rental listings, the recurring monthly rent is returned in the `monthlyRent` field, alongside the headline `price`.

**What output formats are supported?**
Results are stored in a structured Apify dataset and can be exported as JSON, CSV, Excel or XML, or accessed via the Apify API.

#### Is this an Imovirtual API alternative?

Yes. Imovirtual has no open public listings API, so this Actor works as an unofficial Imovirtual API alternative — it reads the site's embedded `__NEXT_DATA__` JSON and returns structured Portuguese real estate data with no API key.

#### Can I scrape Imovirtual without an API or login?

Yes. No Imovirtual account, login or API key is needed — only an Apify account. The Actor pulls publicly available property listings over direct HTTP, so you can scrape Imovirtual without an API.

#### How do I export Imovirtual data to CSV or JSON?

Run the Actor, then export the resulting dataset as CSV, JSON, Excel or XML from the Apify console or via the Apify API. This makes it easy to export Imovirtual property data to CSV or JSON for spreadsheets and BI tools.

#### How do I scrape apartments for sale in Lisbon from Imovirtual?

Set `locationSlugs` to `lisboa`, `transaction` to `sale` and `propertyType` to `apartment`. The scraper returns Lisbon apartments with price, price/m², area, T-typology, address and agency details. Swap the slug to `porto`, `faro` or `braga` for other regions.

#### What is the T-typology (T0, T1, T2, T3) in Portuguese listings?

In Portugal, apartments and houses are classified by "T" number: T0 is a studio, T1 has one bedroom, T2 two bedrooms, and so on. This Actor parses the T-typology into the numeric `rooms` field, and you can filter with `roomsMin`/`roomsMax`.

### ⏰ Scheduling & integration

Schedule this Actor on Apify to track the Portuguese property market daily or weekly. Export results to JSON, CSV or Excel, sync to Google Sheets, or push to your database, BI tools and webhooks through the Apify API.

***

### 📝 Changelog

#### 2026-07-06 — Initial release

- Scrapes Imovirtual.com (Portugal, OLX Group) real estate listings via direct HTTP + `__NEXT_DATA__` JSON extraction — no browser, no API key.
- Filters by location slug (distrito/concelho/freguesia), transaction (buy/rent), property type, price (EUR), area, rooms (T-typology), market, owner type, distance radius and sort order.
- Returns price, price/m², full Portuguese address breakdown, agency data, image galleries and promotion flags per listing.
- Verified end-to-end on live data within the 5-minute quality window on the default input.

# Actor input Schema

## `locationSlugs` (type: `array`):

URL location paths from Imovirtual (Portuguese admin hierarchy: distrito / concelho / freguesia). Each slug becomes its own scraping task. Use `todo-o-pais` for nationwide, a district slug like `lisboa` or `porto`, a council like `lisboa/cascais`, or a parish like `lisboa/cascais/cascais-e-estoril`. Find one by browsing imovirtual.com, applying the location filter, and copying the path between `/resultados/{txn}/{type}/` and `?` from the URL. Common slugs are listed in the README.

## `transaction` (type: `string`):

Buy (`comprar`) or rent (`arrendar`).

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

Imovirtual URL category slug. Note: `room` (quarto) and `development` (empreendimento) are rent/new-build only.

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

Minimum price in euros. 0 = no minimum.

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

Maximum price in euros. 0 = no maximum.

## `areaMin` (type: `integer`):

Minimum surface area. 0 = no minimum.

## `areaMax` (type: `integer`):

Maximum surface area. 0 = no maximum.

## `roomsMin` (type: `integer`):

Minimum bedroom count (T0–T10). 0 = no minimum. Imovirtual counts rooms as the Portuguese T-number (T2 = 2 bedrooms).

## `roomsMax` (type: `integer`):

Maximum bedroom count (T0–T10). 0 = no maximum.

## `market` (type: `string`):

Primary market = developer / new build. Secondary market = resale. ALL = both.

## `ownerType` (type: `string`):

Filter by who's listing the property.

## `sort` (type: `string`):

Result ordering. Maps to `by` + `direction` query params.

## `distanceRadius` (type: `integer`):

Expand search to nearby areas. Imovirtual supports 0, 5, 10, 15, 25, 50, 75 km.

## `limit` (type: `integer`):

Page size. Imovirtual supports 24, 36, 48, 72.

## `maxListings` (type: `integer`):

Total cap across all location tasks (0 = unlimited).

## `maxPagesPerTask` (type: `integer`):

Pagination depth per location. Imovirtual caps results around page 500 (× 72). Narrow with price/area for deeper inventory.

## `requestDelay` (type: `integer`):

Delay between sequential page requests. Imovirtual is mildly bot-protected — keep ≥ 600ms.

## `maxRetries` (type: `integer`):

Retries per request on HTTP errors (rotates proxy IP).

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

Apify Proxy is recommended. Imovirtual deploys mild bot defense — RESIDENTIAL with country=PT is strongly recommended; datacenter often gets blocked.

## Actor input object example

```json
{
  "locationSlugs": [
    "lisboa"
  ],
  "transaction": "sale",
  "propertyType": "apartment",
  "priceMin": 0,
  "priceMax": 0,
  "areaMin": 0,
  "areaMax": 0,
  "roomsMin": 0,
  "roomsMax": 0,
  "market": "ALL",
  "ownerType": "ALL",
  "sort": "latest",
  "distanceRadius": 0,
  "limit": 72,
  "maxListings": 200,
  "maxPagesPerTask": 5,
  "requestDelay": 800,
  "maxRetries": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "PT"
  }
}
```

# Actor output Schema

## `adId` (type: `string`):

Imovirtual listing ID

## `detailUrl` (type: `string`):

Full URL to the listing page

## `slug` (type: `string`):

URL slug

## `title` (type: `string`):

Listing title

## `shortDescription` (type: `string`):

Card-level description snippet

## `transactionType` (type: `string`):

sale / rent

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

apartment / house / plot / commercial / ...

## `estate` (type: `string`):

Raw estate enum from site (FLAT / HOUSE / TERRAIN / COMMERCIAL\_PROPERTY / HALL / GARAGE / ROOM / INVESTMENT)

## `advertType` (type: `string`):

AGENCY / PRIVATE / DEVELOPER (raw)

## `isPrivate` (type: `string`):

True if posted by private owner

## `market` (type: `string`):

PRIMARY (new) / SECONDARY (resale)

## `price` (type: `string`):

Total price

## `priceCurrency` (type: `string`):

Currency (EUR)

## `pricePerSqm` (type: `string`):

Price per square meter

## `monthlyRent` (type: `string`):

Recurring monthly rent (rentals)

## `areaSqm` (type: `string`):

Usable surface area

## `terrainAreaSqm` (type: `string`):

Plot/terrain area (houses, land)

## `rooms` (type: `string`):

Bedroom count (T-typology)

## `floor` (type: `string`):

Floor number/label (GROUND, FIRST, ...)

## `totalFloors` (type: `string`):

Total floors in the building

## `province` (type: `string`):

Distrito (district)

## `county` (type: `string`):

Concelho / município (council)

## `city` (type: `string`):

Freguesia / city label

## `district` (type: `string`):

Bairro / neighborhood

## `street` (type: `string`):

Street name

## `postalCode` (type: `string`):

Postal code (only on detail pages; null in search results)

## `fullAddress` (type: `string`):

Composed address string

## `latitude` (type: `string`):

GPS latitude (only on detail pages; null in search results)

## `longitude` (type: `string`):

GPS longitude (only on detail pages; null in search results)

## `mainImageUrl` (type: `string`):

Cover photo (large)

## `imageUrls` (type: `string`):

All preview image URLs on the card

## `imageCount` (type: `string`):

Preview images on the card

## `totalPossibleImages` (type: `string`):

Total images on the full listing

## `contactName` (type: `string`):

Listing contact name (agent or private seller)

## `contactLogoUrl` (type: `string`):

Contact avatar / photo URL

## `agencyId` (type: `string`):

Agency ID

## `agencyName` (type: `string`):

Agency display name

## `agencySlug` (type: `string`):

Agency URL slug

## `agencyLogoUrl` (type: `string`):

Agency logo image URL

## `agencyType` (type: `string`):

Agency / private category from API

## `isExclusive` (type: `string`):

Exclusive offer flag

## `isFeatured` (type: `string`):

Featured / highlighted listing

## `isPromoted` (type: `string`):

Promoted listing

## `hasOpenDay` (type: `string`):

Has scheduled open day

## `developmentName` (type: `string`):

New-build development name (primary market)

## `investmentState` (type: `string`):

Construction state

## `source` (type: `string`):

Listing source/partner feed

## `dateCreated` (type: `string`):

Most recent post date

## `dateCreatedFirst` (type: `string`):

First-ever post date

## `pushedUpAt` (type: `string`):

Most recent bump

## `labels` (type: `string`):

Feature/amenity tags (AIR\_CONDITIONING, BALCONY, ...)

## `searchTransaction` (type: `string`):

Transaction used in search

## `searchPropertyType` (type: `string`):

Property type used in search

## `searchLocation` (type: `string`):

Location slug used in search

## `searchUrl` (type: `string`):

Full search URL used

## `scrapedAt` (type: `string`):

ISO timestamp

# 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 = {
    "locationSlugs": [
        "lisboa"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "PT"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("logiover/imovirtual-pt-scraper-portugal-real-estate").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 = {
    "locationSlugs": ["lisboa"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "PT",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("logiover/imovirtual-pt-scraper-portugal-real-estate").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "locationSlugs": [
    "lisboa"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "PT"
  }
}' |
apify call logiover/imovirtual-pt-scraper-portugal-real-estate --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=logiover/imovirtual-pt-scraper-portugal-real-estate",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Imovirtual Scraper — Portugal Real Estate Data",
        "description": "Scrape real estate listings from Imovirtual.com — Portugal's major property portal (OLX Group). No browser, no API key. Filter by location, buy/rent, property type, price (EUR), area, rooms and owner type. Returns price, m², price/m², full Portuguese address, agency and image gallery per listing.",
        "version": "1.0",
        "x-build-id": "cOhdQdZPLiWIcub4H"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/logiover~imovirtual-pt-scraper-portugal-real-estate/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-logiover-imovirtual-pt-scraper-portugal-real-estate",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/logiover~imovirtual-pt-scraper-portugal-real-estate/runs": {
            "post": {
                "operationId": "runs-sync-logiover-imovirtual-pt-scraper-portugal-real-estate",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/logiover~imovirtual-pt-scraper-portugal-real-estate/run-sync": {
            "post": {
                "operationId": "run-sync-logiover-imovirtual-pt-scraper-portugal-real-estate",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "locationSlugs"
                ],
                "properties": {
                    "locationSlugs": {
                        "title": "Location Slugs",
                        "type": "array",
                        "description": "URL location paths from Imovirtual (Portuguese admin hierarchy: distrito / concelho / freguesia). Each slug becomes its own scraping task. Use `todo-o-pais` for nationwide, a district slug like `lisboa` or `porto`, a council like `lisboa/cascais`, or a parish like `lisboa/cascais/cascais-e-estoril`. Find one by browsing imovirtual.com, applying the location filter, and copying the path between `/resultados/{txn}/{type}/` and `?` from the URL. Common slugs are listed in the README.",
                        "default": [
                            "lisboa"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "transaction": {
                        "title": "Transaction Type",
                        "enum": [
                            "sale",
                            "rent"
                        ],
                        "type": "string",
                        "description": "Buy (`comprar`) or rent (`arrendar`).",
                        "default": "sale"
                    },
                    "propertyType": {
                        "title": "Property Type",
                        "enum": [
                            "apartment",
                            "house",
                            "plot",
                            "commercial",
                            "warehouse",
                            "garage",
                            "room",
                            "development",
                            "studio"
                        ],
                        "type": "string",
                        "description": "Imovirtual URL category slug. Note: `room` (quarto) and `development` (empreendimento) are rent/new-build only.",
                        "default": "apartment"
                    },
                    "priceMin": {
                        "title": "Min Price (EUR)",
                        "minimum": 0,
                        "maximum": 1000000000,
                        "type": "integer",
                        "description": "Minimum price in euros. 0 = no minimum.",
                        "default": 0
                    },
                    "priceMax": {
                        "title": "Max Price (EUR)",
                        "minimum": 0,
                        "maximum": 1000000000,
                        "type": "integer",
                        "description": "Maximum price in euros. 0 = no maximum.",
                        "default": 0
                    },
                    "areaMin": {
                        "title": "Min Area (m²)",
                        "minimum": 0,
                        "maximum": 1000000,
                        "type": "integer",
                        "description": "Minimum surface area. 0 = no minimum.",
                        "default": 0
                    },
                    "areaMax": {
                        "title": "Max Area (m²)",
                        "minimum": 0,
                        "maximum": 1000000,
                        "type": "integer",
                        "description": "Maximum surface area. 0 = no maximum.",
                        "default": 0
                    },
                    "roomsMin": {
                        "title": "Min Rooms (T-typology)",
                        "minimum": 0,
                        "maximum": 10,
                        "type": "integer",
                        "description": "Minimum bedroom count (T0–T10). 0 = no minimum. Imovirtual counts rooms as the Portuguese T-number (T2 = 2 bedrooms).",
                        "default": 0
                    },
                    "roomsMax": {
                        "title": "Max Rooms (T-typology)",
                        "minimum": 0,
                        "maximum": 10,
                        "type": "integer",
                        "description": "Maximum bedroom count (T0–T10). 0 = no maximum.",
                        "default": 0
                    },
                    "market": {
                        "title": "Market",
                        "enum": [
                            "ALL",
                            "PRIMARY",
                            "SECONDARY"
                        ],
                        "type": "string",
                        "description": "Primary market = developer / new build. Secondary market = resale. ALL = both.",
                        "default": "ALL"
                    },
                    "ownerType": {
                        "title": "Owner Type",
                        "enum": [
                            "ALL",
                            "PRIVATE",
                            "AGENCY"
                        ],
                        "type": "string",
                        "description": "Filter by who's listing the property.",
                        "default": "ALL"
                    },
                    "sort": {
                        "title": "Sort Order",
                        "enum": [
                            "latest",
                            "price_asc",
                            "price_desc",
                            "price_per_m_asc",
                            "price_per_m_desc",
                            "area_asc",
                            "area_desc"
                        ],
                        "type": "string",
                        "description": "Result ordering. Maps to `by` + `direction` query params.",
                        "default": "latest"
                    },
                    "distanceRadius": {
                        "title": "Distance Radius (km)",
                        "minimum": 0,
                        "maximum": 75,
                        "type": "integer",
                        "description": "Expand search to nearby areas. Imovirtual supports 0, 5, 10, 15, 25, 50, 75 km.",
                        "default": 0
                    },
                    "limit": {
                        "title": "Listings per Page",
                        "minimum": 24,
                        "maximum": 72,
                        "type": "integer",
                        "description": "Page size. Imovirtual supports 24, 36, 48, 72.",
                        "default": 72
                    },
                    "maxListings": {
                        "title": "Max Listings",
                        "minimum": 0,
                        "maximum": 1000000,
                        "type": "integer",
                        "description": "Total cap across all location tasks (0 = unlimited).",
                        "default": 200
                    },
                    "maxPagesPerTask": {
                        "title": "Max Pages per Task",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Pagination depth per location. Imovirtual caps results around page 500 (× 72). Narrow with price/area for deeper inventory.",
                        "default": 5
                    },
                    "requestDelay": {
                        "title": "Request Delay (ms)",
                        "minimum": 0,
                        "maximum": 30000,
                        "type": "integer",
                        "description": "Delay between sequential page requests. Imovirtual is mildly bot-protected — keep ≥ 600ms.",
                        "default": 800
                    },
                    "maxRetries": {
                        "title": "Max Retries",
                        "minimum": 0,
                        "maximum": 10,
                        "type": "integer",
                        "description": "Retries per request on HTTP errors (rotates proxy IP).",
                        "default": 3
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Apify Proxy is recommended. Imovirtual deploys mild bot defense — RESIDENTIAL with country=PT is strongly recommended; datacenter often gets blocked."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
