Is There an Immobiliare.it API? How to Get Listing Data

Search for immobiliare.it API and you get a wall of scraper listings, all opening with the same sentence: "Immobiliare.it does not offer a public API." It is repeated so often that it has become the settled answer.
It is also wrong. Immobiliare.it publishes a full API documentation site, with OAuth, sandbox environments, error tables, changelogs and a dozen endpoints. It has been sitting at insights.immobiliare.it/webdocs the whole time, and none of the pages ranking for the query link to it.
The catch is subtler than "there is no API," and more interesting. Italy's largest property portal built an API that deliberately answers a different question than the one you came with.
The short answer
Immobiliare.it has an official API, called Immobiliare.it Insights. It is real, documented, versioned and sold. What it returns is valuations, market statistics, comparables and risk scores.
What it does not return, anywhere in its documentation, is the listings. There is no endpoint that hands you the properties on sale in Milan today with their prices, photos, descriptions and agency contacts. That is a product decision, not an oversight, and no amount of budget changes it.
So if you are building a search portal, a lead tool, a price tracker or a comparison site, the official API will not unblock you. If you are building a valuation model or a market dashboard, it may be exactly what you want and you should stop reading vendor pages and go talk to their sales team.
For everything in the first category, this post covers the three routes that remain, and gives you working code for the one we run.
Immobiliare.it does have an API. It just isn't the one you want
Insights is not a thin afterthought. Reading the docs, you find six separate services, each with its own base URL, its own sandbox and its own changelog:
| Service | What it does |
|---|---|
| AVM | Automated valuation of a single property, for Italy and Greece |
| Appraisal | Create and update formal appraisals, with ESG risk and forecast |
| Comps finder | Find properties comparable to one you are analysing |
| Property Risk | Hazard, vulnerability and risk scores for a location |
| Market Explorer | Prices, stock, demand, transactions and forecasts for an area |
| Report Pro | Generates a full property report, downloadable as PDF |
The engineering is careful in the way that only paid APIs usually are. Every service has a production host and a matching sandbox. The getting-started guide asks you to write tolerant clients, because "additional, non-breaking properties may appear in future releases." Responses share one envelope: a _metadata object carrying the status and a request_id, and an items array with the results.
Authentication is OAuth 2.0. You POST to /oauth/token with a client ID and secret as HTTP Basic credentials plus a username and password in the body, and you get back a bearer token that lasts four hours. The docs are unusually blunt about how to use it:
You do not need to authenticate before every API request: excessive authentication traffic can be flagged by our protection systems and may lead to a temporary ban.
That is a company that has watched people hammer a token endpoint in a loop and decided to say something about it. Cache the token.
The endpoint called "Ads" does not return ads
Here is the moment the whole picture clicks. Market Explorer has an endpoint at POST /api/ads, described in the docs as "Real estate listings stock infos." If you were skimming, you would assume you had found it.
Look at what it returns. The documented response keys are qtraw (number of listings), oldness (time on market), persistence (time to sell), qt_inout (absorption index), status_annunci (stock renewal), plus price aggregates: price_avg, price_sqm_avg, price_sqm_variability, price_sqm_elasticity, and price percentiles from the 10th to the 90th, broken out by maintenance condition and by typology. Several of them arrive wrapped in a ranking object telling you where this zone sits among its peers.
Every one of those is a statistic about the ads. Not one of them is an ad. You can learn that a comune's asking price per square metre is drifting up while its absorption slows, and where it ranks against its neighbours, and still not name a single one of the properties behind those numbers.
That is the design. The request body proves it: you address the API by ty_zone and id_zone (a geography level and a zone id), a time window of 1, 3, 6 or 12 months, a year, a month and a contract of 1 for sale or 2 for rent. There is no listing id in the request, because there is no listing in the response. The unit of analysis is the area, never the property.
The Comps API gets closer to the metal, and then stops. It returns individual comparable properties, each with a uuid you can expand into a detail record or render as a PDF. But the docs gate the interesting half explicitly:
Offerta and Stima are generally available, while the Compravendita types, that is the actual closed transactions, have to be enabled by the Sales team, and Compravendita approssimata requires a further specific request on top of that.
Sold-price data is entitlement-gated, twice. And comparables are scoped to whatever property you are analysing, retrieved by market zone, OMI zone, municipality or bounding box. It is a valuation input, not a market feed. You cannot ask it for "everything for sale in Turin under €300,000" and get a usable answer.
Where the official API genuinely wins
It would be dishonest to file Insights under "useless because it isn't listings." There is one endpoint no scraper on earth can replicate, and it deserves credit.
POST /api/search-data returns demand. Not supply, demand: the share of national searches and views a zone attracts (contribution, contribution_views), the conversion_rate, the average number of leads a listing in that area receives (leads_avg), the average spending propensity of the people searching there (price_sqm_search_avg), and the surface areas and typologies they are actually looking for.
That data exists in exactly one place: Immobiliare.it's own server logs. You cannot scrape a search that someone else performed. If your model needs to know whether a neighbourhood is heating up before the asking prices move, this is the only door, and it is a genuinely good reason to pay them.
The same goes for sales-price and sales-volume, which cover closed transactions rather than asking prices, and for the AVM, which values a property from coordinates and attributes. Note that latitude and longitude are mandatory there: as the docs put it, an address alone is not enough to run a valuation.
How you actually get in
Every base URL in the documentation is a live host under realitycs.it, and every one of them will refuse you, because the credentials are issued, not registered for. The documentation has no signup link and no self-serve key flow. The auth flow needs four separate values (client ID, secret, username, password), which is what a contract looks like when it has been translated into a request body.
This matches the general terms, which split users into Utenti Semplici and Utenti Professionali and say that professional users get access only after contacting the company, with enablement tied to a Contratto di Servizio. Insights is a B2B product sold to banks, funds, appraisers and agencies. If that is you, the docs are worth reading before the sales call, because knowing the vocabulary is a real advantage.
What the Condizioni Generali actually say
The second thing no ranking page does is read the terms. Immobiliare.it's Condizioni Generali, last updated 12 March 2026, are short, in Italian, and considerably broader than the usual anti-bot boilerplate.
The permitted-use section does not bother listing robots and spiders. It goes straight past them:
È vietato svolgere, direttamente o indirettamente, qualsiasi forma di sfruttamento commerciale dei Servizi attraverso l'accesso, l'uso, il trasferimento di informazioni contenute nel Sito e App.
Roughly: any form of commercial exploitation of the Services, direct or indirect, through the access, use or transfer of information contained in the site and app, is prohibited. Note what is missing. No mention of how you obtained the information, no carve-out for manual collection, no technical test at all. The restriction attaches to the commercial use of the data, not to the method.
The intellectual property section then lists what the company owns, and the list includes the word database alongside texts, photographs, graphics and software. In the EU that word carries weight beyond copyright: the sui generis database right protects substantial extraction from a database that took substantial investment to build, whether or not any individual record is original.
There is one more thing in that document, and it is the reason anyone wants this data in the first place. The EU Digital Services Act obliges platforms to publish their audience size, so at the bottom of the Condizioni Generali, Immobiliare.it discloses an average of roughly 10,860,000 monthly unique visitors to the site and 4,290,000 monthly active users of the app, measured over the six months from 1 September 2025 to 28 February 2026. The same page that forbids commercial exploitation of the data tells you exactly how much attention sits behind it.
Two more clauses worth knowing. Compliance is checked by machine, in their words "anche tramite verifiche automatizzate." And any dispute lands exclusively in the Tribunale di Milano, which is a meaningful detail if your company is not in Italy.
What robots.txt adds
Their robots.txt is refreshingly small. One User-agent: * group, no per-crawler rules, and not a single AI-crawler directive, which in 2026 makes it a minority. What it does block is precise:
Disallow: /ricerca-mappa/
Disallow: /search-map
Disallow: /search-list
Disallow: /ricerca.php
Disallow: /ricerca_agenzie.php
Disallow: /dettaglio.php
Disallow: *idmacroarea=
Disallow: *slau=
Those are the search surfaces. Map search, list search, agency search, and the parameterised query strings behind them. The individual listing pages under /annunci/ are not disallowed, because Immobiliare.it wants those indexed. Search results are for humans; the crawl budget goes to the properties.
Read together, the terms and the robots file describe a portal that is happy to be found and unhappy to be harvested. None of this is legal advice, and the terms are worth reading in full with your own counsel before you build on them. We have written up how we think about the same question for our own service in Is RealtyAPI legal?, and the general landscape in Website scraping legal?.
Your four real options in 2026
| Option | What you get | Cost | The catch |
|---|---|---|---|
| Immobiliare.it Insights | Valuations, comparables, market and demand statistics, risk scores | Negotiated contract, no public price | No listings, ever. Credentials issued by sales; sold-price comps need extra entitlement |
| Build your own scraper | Whatever you can parse today | Proxies, headless browsers, and an engineer who owns it | Search paths are disallowed in robots.txt, and layouts change. The maintenance never ends |
| Apify actors | Listing rows in JSON, per run | Roughly $1 to $5 per 1,000 results depending on the actor | Community-maintained, so quality and uptime vary per actor. Built for batch jobs, not live queries |
| A hosted listing API | Search, details and agency endpoints behind one key | See pricing; the free tier includes Immobiliare.it | You depend on someone else keeping the parsers alive. That is the trade you are making on purpose |
On Apify the spread is wide and worth checking before you commit. Reading the store metadata this week, azzouzana/immobiliare-it-listing-page-scraper-by-search-url charges $0.001 per result, loykos/immobiliare-listings charges $0.004, and studio-amba/immobiliare-scraper charges $0.005 per result plus a cent to start the run. Same portal, a fivefold difference in price.
The build-your-own column deserves one honest note. It is not the scrape that costs you, it is the second year of it. This walkthrough of repairing a broken Immobiliare.it Scrapy spider is a good look at the actual job:
We compared the two approaches in general in Web scraping vs API, and the short version has not changed: scraping is cheaper to start and more expensive to keep.
What RealtyAPI's Immobiliare.it endpoints cover
Our Immobiliare.it API exposes eight endpoints. They are grouped the way you would actually use them: find a place, search it, open a listing, then look up whoever is selling it.
| Endpoint | What it does |
|---|---|
GET /autocomplete | Resolves free text to comune, province, region or zone ids |
GET /search/bylocation | Searches listings by location or by an explicit id |
GET /search/byurl | Takes an immobiliare.it results URL and applies its filters |
GET /details/byid | Full detail for one listing by its numeric id |
GET /details/byurl | Same detail, resolved from a listing URL |
GET /agent/search | Agencies operating in a municipality |
GET /agent/details | Full profile for one agency |
GET /agent/listings | Active listings published by an agency |
The /search/byurl endpoint is the one people underuse. Build the search you want in the browser, on immobiliare.it, with every filter set exactly how you like it, then paste that URL in. No parameter mapping, no guessing at their query string. It is the fastest way to prototype a query and the fastest way to confirm your parameterised version returns the same thing.
The filters that make it feel like Immobiliare.it
A generic property API gives you beds, baths and price. That is not how Italians search, and a search that ignores the local vocabulary returns technically-correct results nobody wants.
propertyCategorysplits the market before anything else:residential,rooms,buildings,garage,offices,land,industrial,shops. Whole buildings and garages are separate categories in Italy, not property types tucked inside residential.propertyTypethen narrows the residential set:apartment,villa,townhouse,detached,loft,penthouse,farmhouse. Comma-separate for several.roomsRangeis locali, the Italian room count, and it is the number every listing headline leads with.surfaceRangeis in square metres andpriceRangein euros, both using the samemin:/max:syntax.conditionmaps to the four states a listing declares:new,excellent,good,to_renovate. On a market with this much old housing stock, it is closer to a price driver than a filter.featurescoversbalcony,terrace,garden,elevator,garage,pool,cellar,furnished. In a country of walk-up palazzi,elevatoris not a nice-to-have.excludeAuctionskeeps judicial auction listings out. More on this one below, because the default will surprise you.
Quick start: Italian listings in three requests
Every endpoint lives at https://immobiliare.realtyapi.io and authenticates with an x-realtyapi-key header. Grab a key from the docs and follow along.
1. Resolve the place
curl -s "https://immobiliare.realtyapi.io/autocomplete?query=Milano&limit=5" \
-H "x-realtyapi-key: $REALTYAPI_KEY"
Free text in, ids out. You can skip this and pass location=Milano straight to the search, which is fine for a demo. For anything scheduled, resolve once and store the id, so a rename or an ambiguous string never silently changes which market you are pulling.
2. Search
curl -s "https://immobiliare.realtyapi.io/search/bylocation\
?location=Milano\
&searchType=For_Sale\
&propertyCategory=residential\
&propertyType=apartment\
&priceRange=min:200000,max:500000\
&surfaceRange=min:80\
&roomsRange=min:3\
&excludeAuctions=true\
&sortOrder=Newest\
&page=1" \
-H "x-realtyapi-key: $REALTYAPI_KEY"
Every response uses the same envelope, whatever the endpoint and whatever the outcome. Here is a real one, from calling /autocomplete with no key at all:
{
"message": "401: missing API key in the header",
"source": "immobiliare.it",
"total": 0,
"nextPage": false,
"resultCount": 0,
"searchResults": [],
"detail": {},
"count": 0
}
Note that the shape does not change on failure. searchResults is still an array, detail is still an object, nextPage is still a boolean. Your parser never has to branch on the status code to know what it is holding, which removes an entire category of three-in-the-morning error. Check message, then walk searchResults, then page while nextPage is true.
3. Pull the full detail
curl -s "https://immobiliare.realtyapi.io/details/byid?id=116128813" \
-H "x-realtyapi-key: $REALTYAPI_KEY"
The id comes from searchResults[].id in step 2. If you already have a listing URL from a colleague or a spreadsheet, /details/byurl takes it directly and saves you the parsing.
A production-ish Python loop
import os, time, requests
BASE = "https://immobiliare.realtyapi.io"
HEADERS = {"x-realtyapi-key": os.environ["REALTYAPI_KEY"]}
def search_all(location, max_pages=25, **filters):
params = {"location": location, "searchType": "For_Sale",
"excludeAuctions": "true", **filters}
page = 1
while page <= max_pages:
params["page"] = page
r = requests.get(f"{BASE}/search/bylocation", headers=HEADERS,
params=params, timeout=30)
if r.status_code == 429:
time.sleep(5)
continue
r.raise_for_status()
body = r.json()
results = body.get("searchResults") or []
if not results:
break
for listing in results:
yield listing
if not body.get("nextPage"):
break
page += 1
seen = 0
for listing in search_all("Milano", propertyCategory="residential",
priceRange="min:200000,max:500000"):
seen += 1
print(listing["id"])
print(f"{seen} listings")
Three things in there are not decoration. The 429 branch retries instead of dying, the max_pages ceiling stops a bad filter from walking Lombardy at three in the morning, and the loop trusts nextPage rather than assuming a full page means more pages. That last one matters more than it looks, and the next section explains why.
Five things that will bite you
1. Auctions are included by default. excludeAuctions defaults to false, so aste come back mixed in with ordinary sales. Auction listings carry a base d'asta, the starting price set for a court-ordered sale, which is not an ordinary market asking price. Leave them in and your median price per square metre for a comune quietly drops, your "bargains" ranking fills with properties nobody can buy normally, and your model learns something untrue about the market. Set it to true unless you specifically want them.
2. The page size is 20, and resultCount cannot raise it. Upstream serves 20 listings per page, so resultCount only ever trims that down. A thousand listings is fifty requests, not one big one. Budget your calls by pages, and page with nextPage rather than dividing total by your page size.
3. propertyType only applies to residential. It narrows the residential set. Ask for propertyCategory=offices and also pass propertyType=apartment and you have written a filter that does nothing, which is worse than one that errors. Pick the category first, then narrow.
4. There is no bedroom filter, because Italian listings do not lead with bedrooms. roomsRange is locali, the total habitable room count. If you are porting a schema from a US or UK product, do not map bedrooms onto roomsRange and hope. They are different numbers, and a "3 locali" flat is not a three-bedroom flat.
5. bathrooms is a minimum, and it tops out. Upstream buckets it into 1 to 4, where 4 means four or more. Asking for exactly two bathrooms is not a query this market supports, so if your product promises it, filter client-side after the fetch.
What you still can't get
Being straight about the ceiling is more useful than a feature list.
Sold prices. Italy's closed-transaction data lives with the Agenzia delle Entrate and its OMI zone tables, and inside Insights behind the entitlement gate described above. A listing API covers what is on the market, not what changed hands.
Search demand. The search-data indicators are Immobiliare.it's own traffic. Nobody can reconstruct that from the outside, and anyone claiming to is guessing.
Guaranteed completeness. Any listing feed is a view of a portal at a moment. Cross-check against a second source before you tell an investor a comune has exactly N properties for sale, and see Best real estate listing APIs for how the sources compare.
Anything the portal does not publish. Listing completeness is set by whoever posted the ad. If a field is blank upstream, it arrives blank, and no API can invent it for you.
Key takeaways
- The official Immobiliare.it API exists, and it is not a listings API. Insights ships AVM, comparables, risk and market statistics under real documentation. Every page that says "no API exists" has not read it, and every page that says "there's your API" has not checked what it returns.
- The endpoint named "Ads" returns counts, not ads.
qtraw,oldness,persistenceand price percentiles describe the market. If your product needs to show a property to a user, no combination of Insights endpoints gets you there. - Read the Condizioni Generali before you build. The prohibition covers commercial exploitation of the information regardless of how it was obtained, the IP clause names the database explicitly, and disputes go to Milan. Broader than the robots-and-spiders wording you may be used to.
- Italian filters are not translated English ones. Locali is not bedrooms, categories sit above types, and auctions are in your results until you exclude them. Getting these wrong produces plausible numbers that are quietly wrong.
- Pick the door that matches your question. Valuing a property or modelling a zone, go to Insights. Listing properties to users, you need a listing feed.
If it is the second one, our Immobiliare.it endpoints are on every plan including the free tier, so you can run the three requests above before deciding anything. Same key works across the rest of the portals we cover, which is the point: see Idealista for Spain or StreetEasy for New York, and check pricing when you outgrow the free tier.
