# Casa.it Scraper (Phase-0 probe) (`sian.agency/casa-property-scraper`) Actor

Scrape casa.it listings across Italy: asking price, price per square metre, size, rooms, energy class, condominium fees, year built, agency phone, GPS, judicial auction dates and walking distances to transport and schools.

- **URL**: https://apify.com/sian.agency/casa-property-scraper.md
- **Developed by:** [SIÁN OÜ](https://apify.com/sian.agency) (community)
- **Categories:** Real estate, Lead generation, Business
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.32 / 1,000 property searches

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/actors/running/actors-in-store.md#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

## Casa.it Scraper - Italy Property Listings & Auctions 🇮🇹

[![SIÁN Agency Store](https://img.shields.io/badge/Store-SI%C3%81N%20Agency-1AE392)](https://apify.com/sian.agency?fpr=sian) [![Immobiliare.it Scraper](https://img.shields.io/badge/Store-Immobiliare.it%20Scraper-009246)](https://apify.com/sian.agency/immobiliare-property-scraper?fpr=sian) [![Immobiliare.it Agency Scraper](https://img.shields.io/badge/Store-Immobiliare.it%20Agency%20Scraper-1AE392)](https://apify.com/sian.agency/immobiliare-agent-scraper?fpr=sian) [![Smart Idealista Scraper](https://img.shields.io/badge/Store-Smart%20Idealista%20Scraper-E60023)](https://apify.com/sian.agency/smart-idealista-scraper?fpr=sian)

#### ⚖️ Judicial auctions are a filter here, not a flag you sift for - 2,809 court-ordered sales in Rome and 1,040 in Milan, with the auction date and the reserve price on the row

##### Built for property investors, estate agencies, PropTech analysts and market researchers who need Italian listing data with the numbers already attached.

### 🔎 What is the Casa.it Italy Property Scraper — and when should you use it?

The **Casa.it Italy Property Scraper** turns public Casa.it property listings and judicial auctions from anywhere in Italy into clean, structured rows you can filter, export and feed straight into a spreadsheet, database or AI agent. No account, no portal API key, no browser automation to maintain.

**Use it when you need:** Italian sale and rental listings as rows: asking price in euros with the price per square metre computed, size, rooms, bathrooms, floor, GPS, the full photo set and the floor plan. Every row also names the agency behind the listing, with its phone number and postal address. Switch on full details and each row gains the condominium fees, the year the building went up, its heating and condition, and the energy certificate's numbers rather than just its letter. Detail rows also carry the walking distance in metres to every nearby bus stop, metro station, school and pharmacy, and on a court-ordered sale the auction date and the reserve price. Each row reports how many listings its whole query matched, so you know the size of a market before you page through it..

**Use something else when:** the property is not on Casa.it. Use [Immobiliare.it Scraper](https://apify.com/sian.agency/immobiliare-property-scraper?fpr=sian) for Italy's largest portal, a different operator with overlapping but not identical inventory — run both for a complete Italian picture. Use [Immobiliare.it Agent Scraper](https://apify.com/sian.agency/immobiliare-agent-scraper?fpr=sian) for Italian estate agencies and the individual agents inside them, with contact details. Use [Idealista Scraper](https://apify.com/sian.agency/smart-idealista-scraper?fpr=sian) for Idealista across Italy, Spain and Portugal. This actor covers the public listing surface of casa.it — homes and apartments for sale and rent, rooms in shared flats, holiday lets, offices, shops, warehouses, land, garages and whole buildings, plus every estate agency's own portfolio page. Sold prices and price history are out of scope, because casa.it publishes only what is currently on the market; build a history by scheduling the actor and keeping the runs. Cadastral references and full energy certificates live on surfaces casa.it does not serve. The property's own postcode is not published either — casa.it gives the agency's postcode, which the rows carry under an agency field rather than pretending it belongs to the property.

### 🤖 Use with AI agents

Already connected to the [Apify MCP server](https://mcp.apify.com)? Just ask for this Actor by name: sian.agency/casa-property-scraper

**Your agent can pay for its own runs.** This Actor is eligible for [agentic payments](https://docs.apify.com/platform/actors/publishing/monetize), so an agent can discover it, run it and settle the bill over [x402](https://www.x402.org/) (USDC on Base) or [Skyfire](https://www.skyfire.xyz/) — without an Apify account or API token of its own. Billing is the same either way: per successful row, never for errors.

Otherwise copy this prompt into Claude, ChatGPT, Cursor or any MCP-enabled assistant:

```text
I want Italian property listings, asking prices and judicial auctions from Casa.it using the Apify Actor `sian.agency/casa-property-scraper`.

Use it when I need: Italian sale and rental listings as rows: asking price in euros with the price per square metre computed, size, rooms, bathrooms, floor, GPS, the full photo set and the floor plan. Every row also names the agency behind the listing, with its phone number and postal address. Switch on full details and each row gains the condominium fees, the year the building went up, its heating and condition, and the energy certificate's numbers rather than just its letter. Detail rows also carry the walking distance in metres to every nearby bus stop, metro station, school and pharmacy, and on a court-ordered sale the auction date and the reserve price. Each row reports how many listings its whole query matched, so you know the size of a market before you page through it..

Don't use it when: the property is not on Casa.it — use immobiliare-property-scraper or immobiliare-agent-scraper or smart-idealista-scraper instead.

How to call it: give `location` an Italian place the way casa.it writes it — `Milano`, `Roma`, `Roma provincia`, a district or a neighbourhood — and add more of them in `locations`. Set `transactionType` to `vendita` for sale or `affitto` for rent, and `propertyType` to narrow the market (`residenziale` sweeps every home type; `stanze` and `vacanza` are rent-only). `listingFilter` is the one worth knowing about: `da-asta-immobiliare` returns court-ordered sales only, `con-da-privati` removes every agency listing so you reach owners directly, and the rest cover new builds, gardens, lifts, pools and heating. Narrow further with `priceMin`/`priceMax`, `sizeMinSqm`/`sizeMaxSqm`, `roomsMin`, `bathroomsMin` and `energyClass`, and use `sortBy` to decide which slice you get, because casa.it stops paginating at 80 pages of 20 — about 1,600 rows per query, so split a large city into districts to go deeper. Set `maxResults` to your row budget, turn `enrichWithDetails` on when you want the condominium fees, year built, energy numbers, auction dates and amenity distances, or paste a casa.it search URL straight into `location` and everything in it is used as-is. Switch `operation` to `detail` for specific listing URLs or ids, and to `agency` to pull one estate agency's entire book..

Start with this input:
{
  "operation": "search",
  "location": "Milano",
  "transactionType": "vendita",
  "propertyType": "residenziale",
  "listingFilter": "da-asta-immobiliare",
  "maxResults": 100
}

Ask me which Italian places to cover, whether they want listings for sale or to rent, and whether the condominium fees, energy numbers, auction dates and amenity distances are worth the extra per-listing charge for the full detail page, then run the Actor and summarise the results as a table.
```

**Things you can ask your agent for:**

- *Pull every apartment for sale in Milan under €400,000 with a lift and rank the districts by price per square metre.*
- *Find court-ordered property auctions in Rome and Naples, with the auction date and reserve price on each one.*
- *Give me every private-seller listing in Turin from this week, with the owner's asking price and the photos, ready to paste into a sheet.*

Machine-readable API, MCP config and OpenAPI definition for this Actor are published at [apify.com/sian.agency/casa-property-scraper.md](https://apify.com/sian.agency/casa-property-scraper.md).

### 📋 Overview

**Pull casa.it listings as clean JSON or CSV, anywhere in Italy, for sale (*vendita*) or for rent (*affitto*).** Name a city, a province, a district or a neighbourhood, or paste a casa.it search URL and the whole query is read off it. Three operations share one Actor: search a market, expand single listings, or take an estate agency's entire book.

**Why investors and agents choose us:**

- ⚖️ **Judicial auctions as a first-class filter**: court-ordered sales are one dropdown choice, and the rows carry the auction date and the reserve price rather than a bare true/false flag
- 💎 **The detail layer other casa.it tools skip**: condominium fees per month, year built, heating, air conditioning, building condition, furnishing, lift, and the energy certificate's numeric values alongside its letter
- 📊 **Every row knows its denominator**: the total number of matches for its own query and the page it came from, so you can tell a complete sweep from a sample
- 👤 **Private sellers in one click**: 196 of Milan's 13,936 homes for sale are posted by the owner, and that is the whole addressable list for anyone whose business is reaching owners
- 💰 **Pay per row, from $1.50 per 1,000 listings**: nothing is charged for a listing that did not come back
- 🖼️ **Image URLs that open**: photos you can load straight from the row, a photo count that matches them, and the floor plan's own URL
- 🆓 **Free to try**: up to 25 listings per run on a free Apify plan, no credit card

### ✨ Features

- 🔍 **Property Search**: name an Italian place, pick the market and the filters, and take every matching listing at 20 per page
- 📄 **Listing Detail**: paste casa.it listing URLs or bare numeric ids and get the full attribute table for each one
- 🏢 **Agency Listings**: paste a casa.it agency page and export that agency's entire portfolio. The agency measured while building this carried 5,246 listings
- 💎 **One-switch enrichment**: turn on **Fetch the full detail page** and every search or agency row is followed to its own listing page
- 🎯 **14 saved filters**: judicial auctions, private sellers, new builds, needs renovation, garden, terrace, balcony, lift, pool, garage, heating type and bare ownership
- 🏘️ **18 property types**: apartments, villas, detached and semi-detached houses, penthouses, terraced houses, farmhouses, lofts, rooms in shared flats, holiday lets, offices, shops, warehouses, land, garages and whole buildings
- 📐 **Price per m² computed** on every row that has both a price and a floor area, so comparisons need no cleanup
- 🇮🇹 **Italian numbers parsed properly**: casa.it renders `1.090.000` for €1,090,000, and every price leaves as a plain number
- 🚏 **Walking distances in metres** to the nearest bus stop, metro, school, pharmacy and supermarket, with the name of each one
- 📞 **Agency contact on every row**: name, phone, website, casa.it profile page and postal address
- 🗺️ **Multi-place runs**: search several cities, provinces or districts in a single run with the same filters
- 📤 **Clean exports**: JSON, CSV, Excel, or the full Apify REST API

### 🎬 Quick Start

Pick an operation, name a place, set your filters, and press Start. Rows stream into the Apify dataset as they arrive, and a run report lands in the key-value store with the numbers and the costs.

```bash
curl -X POST "https://api.apify.com/v2/acts/sian.agency~casa-property-scraper/runs?token=[YOUR_TOKEN]" \
-H 'Content-Type: application/json' \
-d '{"operation":"search","location":"Milano","transactionType":"vendita","propertyType":"residenziale","maxResults":100}'
```

### 🚀 Getting Started (3 Simple Steps)

#### Step 1: Choose what to scrape

**Property Search** for a market sweep, **Listing Detail** for specific listings you already have ids for, or **Agency Listings** for one agency's whole book.

#### Step 2: Name the target

A place like "Roma", "Milano" or "Reggio Calabria" for search, or a pasted casa.it URL. For the other two operations, drop listing or agency URLs into their own field.

#### Step 3: Filter and run

Sale or rent, property type, special filter, price and size range, minimum rooms and bathrooms, energy class, sort order and Max listings. Then press **Start**.

**That's it. In a couple of minutes you'll have:**

- A clean Italian property dataset in JSON, CSV or Excel
- Price, price per m², size, rooms, GPS, agency and phone on every row
- A run report with the row counts, the failures and what the run cost

### 📥 Input Configuration

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `operation` | string | No | `search`, `detail` or `agency`. Default `search`. |
| `location` | string | No | Italian place name or a casa.it search URL. Default "Milano". |
| `locations` | array | No | Extra places to search in the same run, same filters. |
| `transactionType` | string | No | `vendita` (sale) or `affitto` (rent). Default `vendita`. |
| `propertyType` | string | No | `residenziale`, `appartamenti`, `ville`, `stanze`, `uffici`, `terreni` and 12 more. |
| `listingFilter` | string | No | `none`, `da-asta-immobiliare` (auctions), `con-da-privati` (private sellers), `in-nuove-costruzioni` and 11 more. |
| `priceMin` / `priceMax` | integer | No | Price range in euros. `0` means no limit. |
| `sizeMinSqm` / `sizeMaxSqm` | integer | No | Floor area range in m². `0` means no limit. |
| `roomsMin` | integer | No | Minimum *locali*: habitable rooms including the living room. |
| `bathroomsMin` | integer | No | Minimum bathrooms. |
| `energyClass` | string | No | `any`, or one of `A4` … `G`. |
| `sortBy` | string | No | `relevance`, `price_asc`, `price_desc`, `surface_desc`, `date_desc`. |
| `maxResults` | integer | No | Listings per place. Default 100. Free plans are capped at 25 per run. |
| `enrichWithDetails` | boolean | No | Follow every search or agency row to its own listing page. Default `false`. |
| `listingUrls` | array | No | Listing pages or bare ids, for the `detail` operation. |
| `agencyUrls` | array | No | Agency pages or bare ids, for the `agency` operation. |

**Example - judicial auctions in Rome, with the auction dates:**

```json
{
  "operation": "search",
  "location": "Roma",
  "transactionType": "vendita",
  "propertyType": "residenziale",
  "listingFilter": "da-asta-immobiliare",
  "enrichWithDetails": true,
  "maxResults": 200
}
```

**Example - private sellers across three Italian cities, cheapest first:**

```json
{
  "operation": "search",
  "location": "Milano",
  "locations": ["Roma", "Torino"],
  "transactionType": "vendita",
  "propertyType": "appartamenti",
  "listingFilter": "con-da-privati",
  "priceMax": 450000,
  "roomsMin": 3,
  "sortBy": "price_asc",
  "maxResults": 300
}
```

**Example - the full record for specific listings:**

```json
{
  "operation": "detail",
  "listingUrls": ["https://www.casa.it/immobili/53928047/", "53715366"]
}
```

**Example - one agency's whole portfolio:**

```json
{
  "operation": "agency",
  "agencyUrls": ["https://www.casa.it/agenzie/deus-ex-casa-1096354/"],
  "maxResults": 500
}
```

### 📤 Output

Every row is flat JSON with **108 fields**, exportable as JSON, CSV or Excel. The most useful ones:

| Field | Type | Description |
|-------|------|-------------|
| `listingId` / `listingUrl` | number / string | Casa.it listing id and its page |
| `price` / `pricePerSqm` | number | Asking price in euros, and price per m² computed for you |
| `sizeSqm` / `rooms` / `bathrooms` / `floorLabel` | number / string | Floor area, *locali*, bathrooms, floor |
| `condoFeesMonthly` | number | *(detail)* Condominium fees per month |
| `yearBuilt` / `buildingCondition` / `heating` | number / string | *(detail)* Build year, condition, heating type |
| `energyClass` / `energyEpNonRenewable` / `energyDecree` | string | Certificate letter, its EP figures and the decree behind it |
| `isAuction` / `auctionDate` / `auctionReservePrice` | boolean / string / number | Judicial auction flag, date and reserve |
| `sellerType` / `agencyName` / `agencyPhone` | string | Owner or agency, the agency's name and its phone |
| `city` / `district` / `province` / `region` | string | Location rollup for grouping |
| `latitude` / `longitude` / `streetViewUrl` | number / string | GPS and a Street View link |
| `photos` / `photoCount` / `floorplanUrls` | array / number | Working image URLs, an honest count, floor plans |
| `pois` / `nearestPublicTransportMeters` | array / number | *(detail)* Named amenities and walking distance in metres |
| `monthlyMortgageEstimate` / `mortgageFixedRate` | number | Casa.it's own repayment estimate and the rate behind it |
| `searchTotalResults` / `searchPage` | number | How many listings matched the query, and which page this row came from |

**Example - a Rome judicial auction, detail row (trimmed):**

```json
{
  "listingId": 53715366,
  "listingUrl": "https://www.casa.it/immobili/53715366/",
  "propertyTypeLabel": "Appartamento",
  "price": 106800,
  "pricePerSqm": 1037,
  "sizeSqm": 103,
  "rooms": 4,
  "bathrooms": 1,
  "floorLabel": "1° piano",
  "hasElevator": false,
  "yearBuilt": 1967,
  "heating": "autonomo",
  "buildingCondition": "abitabile",
  "furnishing": "completamente arredato",
  "energyClass": "G",
  "energyDecree": "DL 192 del 19/08/05",
  "isAuction": true,
  "auctionDate": "18 novembre 2026",
  "auctionReservePrice": 106800,
  "city": "Roma",
  "district": "Casal Monastero-Sant'Alessandro, Settecamini",
  "province": "RM",
  "region": "Lazio",
  "latitude": 41.939425,
  "longitude": 12.625695,
  "zoneCode": "B-2422",
  "agencyName": "Aste Preaste Investimenti srl",
  "agencyPhone": "0281273201",
  "sellerType": "agency",
  "photoCount": 29,
  "floorplanCount": 1,
  "nearestPublicTransportMeters": 80,
  "nearestSchoolMeters": 250,
  "nearestServiceMeters": 220,
  "mortgageFixedRate": 2.85,
  "mortgageYears": 30,
  "lastModified": "8 Settembre 2026",
  "searchTotalResults": 20134,
  "detailFetched": true
}
```

### 🚧 What this cannot do

Worth knowing before you plan a run:

- **About 1,600 rows from any single query.** Casa.it stops paginating at 80 pages of 20, whatever the match total says. Split the area into districts or provinces to go deeper. Every row still carries the real match total, so you always know what fraction you got.
- **No postcode for the property.** Casa.it publishes the *agency's* postcode, which ships here as `agencyPostcode` under an agency name. Nothing else is claimed.
- **No sold prices and no price history.** Casa.it lists live asking prices. To build a history, schedule the Actor and keep the runs. The listing id plus `zoneCode` make a stable join key.
- **No cadastral references and no full energy certificate documents.** Casa.it does not publish them.
- **Rooms in shared flats (`stanze`) and holiday lets (`vacanza`) are rent-only markets.** Pick `affitto` first, or the run returns nothing and says so in the log.

### 💼 Use Cases & Examples

#### 1. Investor hunting distressed stock

**Buyers sourcing court-ordered sales across several Italian provinces.**
**Input:** Property Search, judicial auctions filter, Fetch the full detail page on, one run per province, weekly.
**Output:** auction listings with the auction date, the reserve price and price per m².
**Use:** rank the calendar by discount to the zone median before the hearing date.

#### 2. Estate agency building a farming list

**Agents who want the owner's own listing, not a competitor's.**
**Input:** Property Search, private sellers filter, one run per district, newest first.
**Output:** every owner-posted listing in the catchment area with its contact route.
**Use:** door-knocking and prospecting lists that are the whole market, not a sample.

#### 3. PropTech analyst tracking price per square metre

**Analysts maintaining a comparables set by zone.**
**Input:** Property Search per zone with Fetch the full detail page on, monthly.
**Output:** price, size, floor, condition, year built and energy class on every row.
**Use:** a €/m² index joined run to run on `zoneCode` and `cityCode`.

#### 4. Relocation and co-living operator

**Operators placing tenants near transport.**
**Input:** Property Search set to rent with Rooms in shared flats, detail page on.
**Output:** monthly rents plus the walking distance to the nearest metro or bus stop.
**Use:** shortlist rooms by commute rather than by postcode guesswork.

#### 5. Competitive intelligence on Italian agencies

**Portals and franchises sizing who dominates a city.**
**Input:** Property Search to harvest agency pages, then Agency Listings on each one.
**Output:** each agency's full book, its `listingTier` placement and the query's match total.
**Use:** market share by district, and which agencies pay for platinum placement.

#### 6. Mortgage broker or bank marketing team

**Lenders targeting new-build buyers.**
**Input:** Property Search with the new builds filter, by city.
**Output:** casa.it's own monthly repayment estimate, plus the fixed and variable rates and the term it was computed at.
**Use:** reprice every listing against your own product and lead with the difference.

### 🔗 Integration Examples

#### JavaScript/Node.js

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });

const run = await client.actor('sian.agency/casa-property-scraper').call({
  operation: 'search',
  location: 'Roma',
  transactionType: 'vendita',
  listingFilter: 'da-asta-immobiliare',
  maxResults: 100,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]);
```

#### Python

```python
from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')

run = client.actor('sian.agency/casa-property-scraper').call(
    run_input={
        'operation': 'search',
        'location': 'Roma',
        'transactionType': 'vendita',
        'listingFilter': 'da-asta-immobiliare',
        'maxResults': 100,
    }
)

for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item)
```

#### cURL

```bash
curl -X POST 'https://api.apify.com/v2/acts/sian.agency~casa-property-scraper/runs?token=YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"operation":"detail","listingUrls":["https://www.casa.it/immobili/53928047/"]}'
```

#### Automation Workflows (N8N / Zapier / Make)

1. **Trigger**: a schedule (weekly auction sweep) or an inbound webhook
2. **HTTP Request**: call the Actor API with your saved input
3. **Process**: read the JSON rows, filter on `isAuction`, `sellerType` or `pricePerSqm`
4. **Action**: write to a sheet or CRM, alert the team, or push into your valuation model

### 📊 Performance & Pricing

#### FREE Tier (Try It Now)

- **25 listings** per run, with every field and every filter
- No credit card required
- Enough to check the fields against your model before you commit

#### PAID Tier (Production Ready)

- **Unlimited** listings per run, up to what casa.it will paginate
- Pay per row: a listing that did not come back is never charged
- Search, agency and detail rows are priced separately, so you only pay for the depth you asked for

💰 **Search from $1.50 per 1,000 listings.** Agency portfolio rows from $1.80 per 1,000, and full detail rows from $3.50 per 1,000. Turning on Fetch the full detail page bills one detail row on top of each search or agency row, which is why it is off by default.

🔗 [View current pricing](https://apify.com/sian.agency/casa-property-scraper?fpr=sian)

### ❓ Frequently Asked Questions

**Q: How many listings can one search return?**
A: Casa.it serves 20 per page and stops at 80 pages, so roughly 1,600 rows per query however high you set Max listings. Every row carries `searchTotalResults`, the real size of the result set, so you always know what fraction you got. To go deeper, run each district or province as its own place.

**Q: What is the difference between Property Search and Listing Detail?**
A: A search row is what casa.it puts on the results page: price, size, rooms, bathrooms, floor, GPS, photos, the agency and its phone. A detail row adds what only the listing page carries. That means condominium fees, year built, heating, building condition, the energy certificate's numbers, floor plans, the auction date and reserve, and walking distances to transport, schools and shops.

**Q: Are judicial auction listings really included?**
A: Yes, and you pick them from a dropdown. Court-ordered sales are a large slice of Italian inventory: 2,809 in Rome and 1,040 in Milan when this was measured. Every row carries the flag, and detail rows carry the auction date plus the reserve price where the listing states one.

**Q: Do I need an API key, a login or a browser?**
A: No. There is nothing to configure and nothing to buy. Name a place, press Start, and read the dataset.

**Q: Why is the energy class empty on some rows?**
A: Casa.it puts the letter on roughly one search row in five, and the rest state it on the listing page. Turn on Fetch the full detail page, or run Listing Detail on the ids, and you also get the certificate's numeric values and the decree it was issued under.

**Q: Italian prices use dots for thousands. Do they parse correctly?**
A: They do. Casa.it renders `1.090.000` for €1,090,000, and every price leaves as a plain number you can sort and total without cleaning. Price per m² is computed on every row that has both a price and a floor area.

**Q: Can I get an agency's whole portfolio?**
A: Yes, that is the Agency Listings operation. Paste the agency's casa.it page or just the numeric id from the end of it. Agency pages paginate deep, and the agency measured while building this held 5,246 listings.

**Q: What output formats are available?**
A: JSON, CSV and Excel, straight from the Apify dataset, or the REST API if you want to pull it into your own stack.

**Q: How fresh is the data?**
A: Every run reads casa.it live, so the rows are whatever the site is serving at that moment. Detail rows also carry `lastModified`, the date casa.it says the listing was last touched.

**Q: Is this legal?**
A: We read only pages casa.it serves publicly. See the legal note below.

### 🐛 Troubleshooting

**No results came back**

- Check the Italian spelling of the place. Casa.it knows "Milano" and "Roma", not Milan and Rome. A pasted casa.it search URL always works.
- Loosen the filters. A tight price band combined with a minimum size can genuinely match nothing.
- Rooms in shared flats and holiday lets exist only on the rent side. Set Sale or rent to `affitto` first.

**Fewer rows than Max listings**

- Free Apify plans are capped at 25 rows per run.
- Casa.it stops at 80 pages, so a single query tops out near 1,600 rows. Compare your row count against `searchTotalResults` and split the area into districts.

**The detail fields are empty**

- Condominium fees, year built, heating and the amenity distances live on the listing page. Turn on Fetch the full detail page, or run the Listing Detail operation on the ids.

**A run stopped early or a listing failed**

- Casa.it can be briefly unavailable. Retry in a few minutes, and check the run report in the key-value store: it lists every failed item and what to do about it.
- A listing removed between the results page and its own page is reported, not billed.

### ⚖️ Is it legal to scrape data?

Our actors are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what the user has chosen to share publicly. We therefore believe that our actors, when used for ethical purposes by Apify users, are safe.

However, you should be aware that your results could contain personal data. Personal data is protected by the **GDPR** in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

You can also read Apify's blog post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

*Casa.it is a trademark of Immobiliare.it S.p.A. This actor is not affiliated with, endorsed by or sponsored by Casa.it.*

### 🤝 Support

**Join our active support community**

- For issues or questions, open an issue from the actor page
- Check the [SIÁN Agency Store](https://apify.com/sian.agency?fpr=sian) for more automation tools
- 📧 <apify@sian-agency.online>

***

**Built by [SIÁN Agency](https://www.sian-agency.online)** | **[More Tools](https://apify.com/sian.agency?fpr=sian)**

# Actor input Schema

## `operation` (type: `string`):

Pick one per run. Property Search takes an Italian place name (or a casa.it search URL) plus filters and returns every matching listing. Listing Detail takes casa.it listing URLs or IDs and returns the full attribute table for each: condominium fees, year built, heating, the energy certificate's numbers, judicial auction date and reserve, floor plans, and walking distances to transport, schools and shops. Agency Listings takes casa.it agency pages and returns that agency's whole portfolio.

## `location` (type: `string`):

An Italian place - a city (Roma, Milano, Napoli, Torino, Firenze), a province (Roma provincia), a district or a neighbourhood. Accents and spaces are handled, so 'Reggio Calabria' and 'Forlì' both work. A casa.it search URL works too and everything in it - market, property type, filters, sort - is read off the URL and used as-is. The run log prints the exact casa.it page each search resolved to, so you can always check what was searched.

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

Extra places to search in the same run, each with the same filters. Three places return roughly three times the rows. This is also how you get past casa.it's 80-page ceiling on a single query: split a big city into its districts, or a region into its provinces.

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

Which market to search. Rooms in shared flats and holiday lets exist only on the rent side - pick 'To rent' before choosing those property types.

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

Which slice of casa.it's inventory to search. 'All homes' is the broadest residential search and is the right default. Rooms in shared flats and holiday lets are rent-only markets; picking either with 'For sale' returns nothing and the run log says so rather than failing silently.

## `listingFilter` (type: `string`):

One of casa.it's own saved filters. Judicial auctions is the one worth knowing about: it returns court-ordered sales only - 2,809 of them in Rome and 1,040 in Milan when this was measured - and those rows carry an auction date and a reserve price that ordinary listings do not. Private sellers only removes every agency listing, which is what you want when the point is to reach the owner. Each of these was verified by checking the rows that came back, not by trusting the site to echo the filter.

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

Lowest asking price to include, in euros. 0 means no minimum. On the rent side this is a monthly rent, not a purchase price.

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

Highest asking price to include, in euros. 0 means no maximum.

## `sizeMinSqm` (type: `integer`):

Smallest floor area to include, in square metres. 0 means no minimum.

## `sizeMaxSqm` (type: `integer`):

Largest floor area to include, in square metres. 0 means no maximum.

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

Fewest rooms to include. Italian listings count 'locali' - habitable rooms including the living room, excluding kitchen and bathrooms - so a two-bedroom flat is normally 3 locali. 0 means no minimum.

## `bathroomsMin` (type: `integer`):

Fewest bathrooms to include. 0 means no minimum.

## `energyClass` (type: `string`):

Filter by the property's energy performance certificate class. Italian listings are legally required to state one, so this is well populated on the detail page - though only about a fifth of search rows carry the letter, which is one reason to run Listing Detail on the results.

## `sortBy` (type: `string`):

Casa.it caps any single query at 80 pages, so on a query with more matches than that the sort decides which slice you get. 'Cheapest first' and 'Most expensive first' are the two that make a truncated run useful rather than arbitrary.

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

How many listings to return per place. Casa.it serves 20 per search page and stops at 80 pages, so a single query tops out near 1,600 rows however high you set this - split the area into districts to go deeper. Free-plan runs are capped at 25 rows regardless.

## `enrichWithDetails` (type: `boolean`):

Off by default. When on, each search or agency result is followed to its own listing page, which adds condominium fees, year built, heating and air conditioning, building condition, the energy certificate's numeric values, floor plans, judicial auction date and reserve price, and the walking distance to every nearby bus stop, metro station, school, pharmacy and supermarket. It costs one extra page load per listing and bills the Listing Detail event on top of the search event, so turn it on…

## `listingUrls` (type: `array`):

Used by the Listing Detail operation: casa.it listing pages, e.g. https://www.casa.it/immobili/53928047/. The numeric id is the listing, so a bare 53928047 works too. Ids come out of a Property Search run in the Listing ID column.

## `agencyUrls` (type: `array`):

Used by the Agency Listings operation: casa.it agency pages, e.g. https://www.casa.it/agenzie/deus-ex-casa-1096354/. The trailing number is the agency id, so a bare 1096354 works too. Agency pages come out of a Property Search run in the Agency page column, which makes 'find every agency in Milan, then pull each one's whole portfolio' a two-run job.

## Actor input object example

```json
{
  "operation": "search",
  "location": "Milano",
  "locations": [
    "Roma",
    "Torino"
  ],
  "transactionType": "vendita",
  "propertyType": "residenziale",
  "listingFilter": "none",
  "priceMin": 0,
  "priceMax": 0,
  "sizeMinSqm": 0,
  "sizeMaxSqm": 0,
  "roomsMin": 0,
  "bathroomsMin": 0,
  "energyClass": "any",
  "sortBy": "relevance",
  "maxResults": 100,
  "enrichWithDetails": false,
  "listingUrls": [
    "https://www.casa.it/immobili/53928047/"
  ],
  "agencyUrls": [
    "https://www.casa.it/agenzie/deus-ex-casa-1096354/"
  ]
}
```

# Actor output Schema

## `casaItListings` (type: `string`):

Every listing this run returned.

## `scrapingSummary` (type: `string`):

HTML summary showing successful and failed results with key metrics

# 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 = {
    "operation": "search",
    "location": "Milano",
    "locations": [
        "Roma",
        "Torino"
    ],
    "transactionType": "vendita",
    "propertyType": "residenziale",
    "listingFilter": "none",
    "priceMin": 0,
    "priceMax": 0,
    "sizeMinSqm": 0,
    "sizeMaxSqm": 0,
    "roomsMin": 0,
    "bathroomsMin": 0,
    "energyClass": "any",
    "sortBy": "relevance",
    "maxResults": 100,
    "enrichWithDetails": false,
    "listingUrls": [
        "https://www.casa.it/immobili/53928047/"
    ],
    "agencyUrls": [
        "https://www.casa.it/agenzie/deus-ex-casa-1096354/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("sian.agency/casa-property-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 = {
    "operation": "search",
    "location": "Milano",
    "locations": [
        "Roma",
        "Torino",
    ],
    "transactionType": "vendita",
    "propertyType": "residenziale",
    "listingFilter": "none",
    "priceMin": 0,
    "priceMax": 0,
    "sizeMinSqm": 0,
    "sizeMaxSqm": 0,
    "roomsMin": 0,
    "bathroomsMin": 0,
    "energyClass": "any",
    "sortBy": "relevance",
    "maxResults": 100,
    "enrichWithDetails": False,
    "listingUrls": ["https://www.casa.it/immobili/53928047/"],
    "agencyUrls": ["https://www.casa.it/agenzie/deus-ex-casa-1096354/"],
}

# Run the Actor and wait for it to finish
run = client.actor("sian.agency/casa-property-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 '{
  "operation": "search",
  "location": "Milano",
  "locations": [
    "Roma",
    "Torino"
  ],
  "transactionType": "vendita",
  "propertyType": "residenziale",
  "listingFilter": "none",
  "priceMin": 0,
  "priceMax": 0,
  "sizeMinSqm": 0,
  "sizeMaxSqm": 0,
  "roomsMin": 0,
  "bathroomsMin": 0,
  "energyClass": "any",
  "sortBy": "relevance",
  "maxResults": 100,
  "enrichWithDetails": false,
  "listingUrls": [
    "https://www.casa.it/immobili/53928047/"
  ],
  "agencyUrls": [
    "https://www.casa.it/agenzie/deus-ex-casa-1096354/"
  ]
}' |
apify call sian.agency/casa-property-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sian.agency/casa-property-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/hh7S1nGNPGbnk8e4V/builds/2pca3Ga1gZgdRHKeU/openapi.json
