# Spitogatos Scraper: Greece Property Listings (`reventadata/spitogatos-scraper`) Actor

Scrape Spitogatos.gr property listings in Greece: homes, apartments and land for sale, homes for rent, by area. Price, area, bedrooms, floor, coordinates, agency, photos and publish dates. Filter by price, size or reduced price. Unofficial.

- **URL**: https://apify.com/reventadata/spitogatos-scraper.md
- **Developed by:** [reventadata](https://apify.com/reventadata) (community)
- **Categories:** Real estate, Automation
- **Features:** 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 results

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/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

> **Unofficial.** This Actor is not affiliated with, authorised by, endorsed by, or in any
> way officially connected to Spitogatos. "Spitogatos" is a trademark of its respective owner
> and is used here only to describe what this tool reads. It reads the same public pages a
> browser does.

Spitogatos Scraper reads property listings from [Spitogatos.gr](https://www.spitogatos.gr),
a Greek real-estate portal, for sale or for rent: price, area, bedrooms, bathrooms, floor,
location with coordinates, the agency that published the listing, photos and when the listing
was published and last modified.

### What data can you extract from Spitogatos?

The listings Spitogatos returns for your search (before any price or area limits you set), with
the fields the site publishes in its search results. The Actor reads the state the site embeds in its own search pages, so it needs
no browser.

### Why scrape Spitogatos?

- **Sale and rent.** Homes, apartments and land for sale; homes for rent. Any area Spitogatos
  has a page for (`athens-center`, `thessaloniki-center`, `cyclades`, `chalkidiki`, ...).
- **Reduced-price listings only**, on sale searches, with the old price and the percentage.
- **Numeric limits.** Minimum and maximum price and area are applied to the rows after they are
  fetched (the site's own price filter was not found as a URL parameter).
- **Many result pages.** The run walks up to 200 pages by default (raise `maxPages` for more; Spitogatos reported 1,223 pages
  for homes for sale in Athens center on 2026-11-07), or stops earlier at your row cap or the last page.
- **No duplicates.** A listing that moves between pages while the run walks is returned once.

### How to scrape Spitogatos

1. Pick `listingType`, `category` and `area`.
2. Optionally set price and area limits, or reduced price only.
3. Run it. Results land in the dataset.

#### Input

| Field | Type | Meaning |
|---|---|---|
| `listingType` | string | `sale` | `rent`. Rent is available for `homes` only. |
| `category` | string | `homes` | `apartments` | `land`. |
| `area` | string | Spitogatos area slug from a search URL, for example `athens-center`. An unknown slug stops the run with an error. |
| `reducedPriceOnly` | boolean | Only listings with a lowered price. Sale only. |
| `minPrice`, `maxPrice` | integer | Optional, EUR (monthly rent on rent searches). Rows outside, or without a price, are dropped. |
| `minAreaM2`, `maxAreaM2` | integer | Optional. Rows outside, or without an area, are dropped. |
| `maxItems` | integer | Cap on rows. Default 1000. |
| `maxPages` | integer | Cap on pages, 30 listings each. Default 200. |

```json
{
    "listingType": "rent",
    "category": "homes",
    "area": "thessaloniki-center",
    "minPrice": 300,
    "maxPrice": 900,
    "maxItems": 100
}
```

#### Output

One row, from a real local run on 2026-11-07. All 36 output fields are shown; `description` is shortened here and `imageIds` lists 3 of 19 ids. A field the site gives no value for is `null` (here `pricePreReduction` and `priceChangePercentage`, because the price was not reduced):

```json
{
    "id": "20880028",
    "url": "https://www.spitogatos.gr/en/property/1120880028",
    "listingType": "sale",
    "category": "house",
    "subtype": 1,
    "price": 580000,
    "currency": "EUR",
    "priceReduced": false,
    "pricePreReduction": null,
    "priceChangePercentage": null,
    "areaM2": 115,
    "bedrooms": 2,
    "bathrooms": 2,
    "floorCode": 3,
    "floor": "G",
    "location": "Kolonaki (Kolonaki - Lykavittos)",
    "latitude": 37.97966,
    "longitude": 23.744823,
    "locationIsExact": true,
    "description": "An ultra-luxury 115 sq.m. raised ground-floor apartment in a quiet spot of Kolonaki, ...",
    "isNewDevelopment": false,
    "hasVideo": false,
    "hasVirtualTour": false,
    "imageUrl": "https://m3.spitogatos.gr/369358208_300x220.jpg?v=20130730",
    "imageCount": 19,
    "imageIds": [369358208, 369358209, 369358210],
    "adType": "vip",
    "agencyId": 3155,
    "agencyName": "Katoikia",
    "agencyProfileUrl": "https://www.spitogatos.gr/en/find-agents/Katoikia/3155",
    "agencyLogoUrl": "https://m2.spitogatos.gr/300441385_100x50.jpg",
    "agencyMembership": "expert",
    "firstPublishedAt": "2026-09-18 19:47:56",
    "uploadedAt": "2026-09-18 19:47:56",
    "modifiedAt": "2026-11-07 20:55:43",
    "searchUrl": "https://www.spitogatos.gr/en/for_sale-homes/athens-center"
}
```

### Notes and limits

- **On rent searches `price` is the monthly rent.**
- **`bedrooms` is the bedroom count** (it matches the Bedrooms badge on the site's cards); it is 0 where the card shows none.
- **`floorCode` is the site's own code;** `floor` is the label the card shows (-1, LG, G, UG, 1 to 8). `floor` is null for a code not yet seen.
- **`description` is the start of the text,** cut by the site at about 300 characters. Times are site-local with no timezone.
- **Agency names and profile links are returned; phone numbers are not.** The site does not put them in the results list, and the Actor does not open listing pages.
- **A search that matches nothing ends with a status message and no rows.** A wrong area slug, or a run where Spitogatos' pages could not be read, ends as failed with the reason.
- Only the categories above were tested. Reads the same public pages a browser does. See the disclaimer at the top.

### How much does it cost to scrape Spitogatos?

Pay-per-event: you pay per result written to the dataset, with no subscription. The current
price is on the Actor's Pricing tab.

### FAQ

**How do I find an area slug?** Search on spitogatos.gr and copy the part of the URL after the
category, for example `thessaloniki-center` from `/en/for_sale-homes/thessaloniki-center`.

**Why do I get fewer rows than the site's result count?** The site's count drifts while a run
walks; ids that repeat across pages are returned once, and your limits drop rows.

# Actor input Schema

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

Listings for sale (for_sale) or for rent (to_rent). Rent is available for category Homes only.

## `category` (type: `string`):

Homes (all residential), Apartments, or Land. Other Spitogatos categories were not tested and are not offered.

## `area` (type: `string`):

Spitogatos area slug as it appears in a search URL on spitogatos.gr after the category, for example "athens-center", "athens-north", "thessaloniki-center", "cyclades", "chalkidiki" or "zante". An unknown slug stops the run with an error.

## `reducedPriceOnly` (type: `boolean`):

Only listings whose price was lowered (the site's reduced-price filter). Sale searches only.

## `minPrice` (type: `integer`):

Optional. Rows below this price, or with no price, are dropped after fetching (the site's own price filter was not found as a URL parameter, so pages are still fetched in full). On a rent search this is the monthly rent.

## `maxPrice` (type: `integer`):

Optional. Rows above this price, or with no price, are dropped after fetching. On a rent search this is the monthly rent.

## `minAreaM2` (type: `integer`):

Optional. Rows smaller than this, or with no area, are dropped after fetching.

## `maxAreaM2` (type: `integer`):

Optional. Rows larger than this, or with no area, are dropped after fetching.

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

Hard cap on rows pushed.

## `maxPages` (type: `integer`):

Cap on result pages fetched (30 listings each). Each page is one paid unblocking request on the Actor's side, so the default stops at 200 pages even when filters reject most rows. The run also stops at the last page the site reports.

## Actor input object example

```json
{
  "listingType": "sale",
  "category": "homes",
  "area": "athens-center",
  "reducedPriceOnly": false,
  "maxItems": 10,
  "maxPages": 1
}
```

# Actor output Schema

## `listings` (type: `string`):

Property listings: price, area, bedrooms, floor, location, agency and a link to the ad.

# 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 = {
    "area": "athens-center",
    "maxItems": 10,
    "maxPages": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("reventadata/spitogatos-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 = {
    "area": "athens-center",
    "maxItems": 10,
    "maxPages": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("reventadata/spitogatos-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 '{
  "area": "athens-center",
  "maxItems": 10,
  "maxPages": 1
}' |
apify call reventadata/spitogatos-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,reventadata/spitogatos-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/85otv5ncKX7WebzTn/builds/a32gafjGL6YWGbM9h/openapi.json
