Scrappa's GET /api/wikicasa/search returns Wikicasa property for sale or rent in one Italian city.
What you get
data.count is the number of matches, data.items holds up to 25 listings. Each item has id, url, title, description, price, area_sqm, rooms, bathrooms, address, zone, city, coordinates, condition, energy_class, flags, auction, published_at, the first image, the agency and the agent.
How to use it
- Call
GET /api/wikicasa/autocompleteand takecity_idandslugof a place withsearchabletrue. - Pass them as
city_idandcity_slug, withtransactionsale or rent. - Add filters. Use
GET /api/wikicasa/property-typesforproperty_type.
Filters
Every filter is checked again on each item. Items that break a filter are removed and counted in meta.filtered_out. data.count is the total Wikicasa reports for the search. A price that Wikicasa hides is returned as null with price_reserved true, and such an item does not pass a price filter.
Pagination
page is 1-based, 25 listings per page, up to page 2000. meta.page always equals the page you asked for. meta.has_more tells you whether a next page exists.
Not supported
There is no bedrooms filter. Wikicasa filters rooms and bathrooms. Zone, province and region search are not available and answer 422.
Run this endpoint
Endpoint
Parameters
Start with the required fields, then add optional filters only when your use case needs them.
Runnable path
3 required parameters needed before sending a request.
12 optional filters available.
string
Required
sale or rent. The Italian words vendita and affitto also work.
sale
integer
Required
Numeric city id from the autocomplete endpoint, for example 15146 for Milano.
15146
string
Required
City slug from the autocomplete endpoint, for example milano.
milano
integer
Optional
Result page, 1 to 2000. A page holds up to 25 listings. Default: 1.
1
integer
Optional
Minimum price in EUR (monthly rent for rent). Checked on every item.
10
integer
Optional
Maximum price in EUR. Must not be below price_min. Checked on every item.
400000
integer
Optional
Minimum area in m2. Checked on every item.
10
integer
Optional
Maximum area in m2. Checked on every item.
10
integer
Optional
Minimum number of rooms (locali). Checked on every item.
10
integer
Optional
Maximum number of rooms. Checked on every item.
10
integer
Optional
Minimum number of bathrooms. Checked on every item.
10
integer
Optional
Maximum number of bathrooms. Checked on every item.
10
string
Optional
Type id or key with searchable true from the property-types endpoint, for example appartamenti or 5.
example
string
Optional
new, refurbished (refurbished or new) or to_refurbish. Checked on every item.
example
string
Optional
most_recent (default), price_asc, price_desc or area_desc.
price_asc
Request Examples
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://scrappa.co/api/wikicasa/search?transaction=sale&city_id=15146&city_slug=milano&price_max=400000&sort=price_asc",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: YOUR_API_KEY_HERE"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
<?php
use Illuminate\Support\Facades\Http;
$response = Http::timeout(30)
->withHeaders(['x-api-key' => 'YOUR_API_KEY_HERE'])
->get('https://scrappa.co/api/wikicasa/search?transaction=sale&city_id=15146&city_slug=milano&price_max=400000&sort=price_asc');
if ($response->successful()) {
echo $response->body();
} else {
echo "Error: " . $response->status();
}
const options = {
method: 'GET',
headers: {
'x-api-key': 'YOUR_API_KEY_HERE'
}
};
fetch('https://scrappa.co/api/wikicasa/search?transaction=sale&city_id=15146&city_slug=milano&price_max=400000&sort=price_asc', options)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.text();
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
const axios = require('axios');
const options = {
method: 'GET',
url: 'https://scrappa.co/api/wikicasa/search?transaction=sale&city_id=15146&city_slug=milano&price_max=400000&sort=price_asc',
headers: {
x-api-key: 'YOUR_API_KEY_HERE',
}
};
try {
const response = await axios(options);
console.log(response.data);
} catch (error) {
console.error('Error:', error.message);
}
require 'net/http'
require 'uri'
uri = URI.parse("https://scrappa.co/api/wikicasa/search?transaction=sale&city_id=15146&city_slug=milano&price_max=400000&sort=price_asc")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == 'https'
request = Net::HTTP::Get.new(uri.request_uri)
request['x-api-key'] = 'YOUR_API_KEY_HERE'
begin
response = http.request(request)
puts response.body
rescue => e
puts "Error: #{e.message}"
end
import http.client
import json
conn = http.client.HTTPSConnection("scrappa.co")
headers = {
'x-api-key': 'YOUR_API_KEY_HERE',
}
try:
conn.request("GET", "/api/wikicasa/search?transaction=sale&city_id=15146&city_slug=milano&price_max=400000&sort=price_asc", headers=headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
except Exception as e:
print(f"Error: {e}")
finally:
conn.close()
import requests
headers = {
'x-api-key': 'YOUR_API_KEY_HERE',
}
try:
response = requests.get('https://scrappa.co/api/wikicasa/search?transaction=sale&city_id=15146&city_slug=milano&price_max=400000&sort=price_asc', headers=headers)
response.raise_for_status()
print(response.text)
except requests.exceptions.RequestException as e:
print(f"Error: {e}")
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
public class ApiExample {
public static void main(String[] args) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://scrappa.co/api/wikicasa/search?transaction=sale&city_id=15146&city_slug=milano&price_max=400000&sort=price_asc")
.addHeader("x-api-key", "YOUR_API_KEY_HERE")
.build();
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful()) {
System.out.println(response.body().string());
} else {
System.out.println("Error: " + response.code());
}
} catch (IOException e) {
System.out.println("Error: " + e.getMessage());
}
}
}
package main
import (
"fmt"
"net/http"
"io/ioutil"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://scrappa.co/api/wikicasa/search?transaction=sale&city_id=15146&city_slug=milano&price_max=400000&sort=price_asc", nil)
if err != nil {
fmt.Println("Error creating request:", err)
return
}
req.Header.Set("x-api-key", "YOUR_API_KEY_HERE")
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error making request:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error reading response:", err)
return
}
fmt.Println(string(body))
}
#!/bin/bash
curl -X GET \
-H "x-api-key: YOUR_API_KEY_HERE" \
"https://scrappa.co/api/wikicasa/search?transaction=sale&city_id=15146&city_slug=milano&price_max=400000&sort=price_asc"
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key", "YOUR_API_KEY_HERE");
try
{
var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, "https://scrappa.co/api/wikicasa/search?transaction=sale&city_id=15146&city_slug=milano&price_max=400000&sort=price_asc"));
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}
import axios from 'axios';
async function run(): Promise<void> {
try {
const response = await axios({
method: 'GET',
url: 'https://scrappa.co/api/wikicasa/search?transaction=sale&city_id=15146&city_slug=milano&price_max=400000&sort=price_asc',
headers: {
'x-api-key': 'YOUR_API_KEY_HERE',
},
});
console.log(response.data);
} catch (error) {
console.error('Error:', error);
}
}
void run();
use reqwest::Client;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new();
let response = client
.get("https://scrappa.co/api/wikicasa/search?transaction=sale&city_id=15146&city_slug=milano&price_max=400000&sort=price_asc")
.header("x-api-key", "YOUR_API_KEY_HERE")
.send()
.await?;
println!("{}", response.text().await?);
Ok(())
}
Response Schema
Example response fields are illustrative; inspect the JSON before integrating.
Example response fields
Scan these fields before integrating.
success
data
meta
{
"success": true,
"data": {
"count": 2537,
"items": [
{
"id": 31209219,
"url": "https://www.wikicasa.it/annuncio/31209219",
"title": "Bilocale in Viale Monte Nero, Milano",
"description": "Montenero vendiamo in esclusiva ottimo bilocale piu servizi, ingresso soggiorno con cucinotto, camera da letto matrimoniale, bagno, cantina.",
"transaction": "sale",
"price": 460000,
"price_sale": 460000,
"price_rent": null,
"original_price": null,
"price_reserved": false,
"currency": "EUR",
"area_sqm": 55,
"rooms": 2,
"bathrooms": 1,
"address": "Viale Monte Nero",
"zone": "Porta Romana, Sabotino, Muratori, Cadore, Montenero, Cinque Giornate",
"city": "Milano",
"city_id": 15146,
"latitude": 45.4569,
"longitude": 9.2051,
"typology_id": 1,
"macro_typology_id": 1,
"condition": "refurbished",
"energy_class": "D",
"flags": {
"garden": false,
"luxury": false,
"recent": true,
"opportunity": false,
"furnished": true,
"bare_ownership": false,
"short_rent": false
},
"auction": {
"is_auction": false,
"days_left": null,
"discount_percent": null
},
"published_at": "2026-10-26",
"image": "https://images.wk-cdn.it/3790b1dec9e72e38f05336c59c9e3b34c36e2f0eb056e4682d5263cdf5e762a6//original",
"floor_plan_count": 0,
"virtual_tour_url": null,
"project_units": 0,
"agency": {
"id": 59246,
"name": "REIA Association of Italian Real Estate Agents",
"city": "Milano",
"latitude": 45.4563735,
"longitude": 9.1530444,
"premium": false,
"image_id": 1266737544
},
"agent": null
}
]
},
"meta": {
"endpoint_family": "search",
"billable": true,
"page": 1,
"per_page": 25,
"has_more": true,
"filtered_out": 0
}
}
Errors
Handle these documented responses before retrying or showing customer-facing failures.
Validation Error
A query parameter is missing, unknown or unusable. Unknown parameters and unknown values are rejected, never ignored. Non-billable.
{
"errors": {
"sort": [
"The selected sort is invalid."
]
},
"message": "The selected sort is invalid."
}Upstream Unavailable
Wikicasa could not be reached, refused the request or answered with data this API could not read (`UPSTREAM_UNAVAILABLE`). Retryable and never billed. Clients are never rate limited.
{
"meta": {
"billable": false,
"retryable": true,
"endpoint_family": "search"
},
"error": {
"code": "UPSTREAM_UNAVAILABLE",
"message": "Wikicasa could not be reached. Please retry shortly."
},
"success": false
}Generate Code with AI
Copy a ready-made prompt with all the endpoint details, parameters, and example responses. Paste it into ChatGPT, Claude, or any AI assistant to instantly generate working code.
Try It Live
Test this endpoint in our interactive playground with real data.