Search commercial premises
https://platform.casafari.com/v1/claro/searchSend Authorization: Bearer $CASAFARI_API_KEY: a platform API key or OAuth access token, metered in platform tokens; see platform sign-in and Claro AI. On the platform this is POST https://platform.casafari.com/v1/claro/search; POST /v1/search is Claro's own path, which the platform adds /claro to. The platform forwards the call to Claro unchanged: Claro's Claro-Version header and its error bodies ({"error":{"code","message"}}, with rate_limited and quota_reached on a 429) pass through.
Over MCP: search_premises (equivalent). MCP and REST compared.
Description
Find shops, restaurant premises, offices, warehouses and other commercial premises for rent or sale anywhere in Spain or Germany (one country per search; Spain unless Germany is asked). Describe the site in plain words in any language (brief), send criteria as data, or both (criteria override the brief). Returns exact counts (matching, all criteria stated, some not stated), the criteria as understood, and the best results: each with its data, what was met and what its text does not state, the sentence that matched, its coordinates (exact, or snapped to the centre of a ~500 m cell and marked approximate when the agency hides the address; none when it has no pin), a fit verdict read from its text (fit: good, partial or poor, a reason, the quote it rests on; data_conflict when its text names another district, city or property type than its own data, with the text's words and a note to check the agency's ad: the data decides the verdict, an exact pin over any place the text names), location figures when your account has location access (footfall, residents, nearby places, and in location the footfall split by weekday/weekend, time of day and where the activity comes from live, plus residents by age, households by income and spending power, each null when not stated or unknown, never 0 for unknown; location_sources gives each figure's unit, source and vintage, and when it was computed), and the agency (agency.name) with its own listing page as agency.listing_url, null when the agency has no page of its own (always the agency's own page, never a property portal's). Our fit verdict is one input: every raw figure is there for your own scoring. Up to 200 results a page (50 with a publishable key). next_cursor gets the next page: send it as cursor (alone, with limit if you like); the order is fixed when the search runs and stays the same for its 24 hours, so pages never repeat or skip a premises. page gives offset, limit and the total ranked. The read-through (check) runs only for pages of up to 50. stated_only: true pages through only the matches that state every criterion (those with a point not stated or not met are left out; counts still gives both totals, page.total the set being paged); send it with the first search, or with search_id to page a stored search's stated matches without searching again, and its next_cursor keeps it. search_id with offset (and no brief, criteria or change) returns that search's page from that place. pins_only: true with search_id (or a cursor) returns just each match's pin, pins (id, lat, lon, precision, plus type, district, rent and sale price, size and the day it was first listed, listed_since, each null when not stated), up to 2000 a page, for a map. Keep search_id to refine. Keywords only, no model: send just criteria.keywords and/or exclude_keywords (plus any data criteria) with no brief and check: false, e.g. {"criteria": {"operation": "rent", "cities": ["madrid"], "keywords": [["salida de humos", "sortida de fums"], ["esquina", "chaflán"]], "exclude_keywords": ["se traspasa"]}, "check": false}; each keyword group met carries the sentence that matched (evidence) and the phrase it holds (matched).
Request body
Content type application/json. Required. Type: object.
briefstringcriteriaobject54 properties
operationstringrent sale eithercountrystringes decitiesstring[]provincesstring[]68 allowed values
a-coruna alava albacete alicante almeria asturias avila badajoz barcelona burgos caceres cadiz cantabria castellon ceuta ciudad-real cordoba cuenca girona granada guadalajara guipuzcoa huelva huesca islas-baleares jaen la-rioja las-palmas leon lleida lugo madrid malaga melilla murcia navarra ourense palencia pontevedra salamanca santa-cruz-de-tenerife segovia sevilla soria tarragona teruel toledo valencia valladolid vizcaya zamora zaragoza baden-wurttemberg bayern berlin brandenburg bremen hamburg hessen mecklenburg-vorpommern niedersachsen nordrhein-westfalen rheinland-pfalz saarland sachsen sachsen-anhalt schleswig-holstein thuringendistrictsstring[]typesstring[]hotel retail warehouse industrial office other_commercialarea_minnumberarea_maxnumberprice_minnumberprice_maxnumberrent_price_minnumberrent_price_maxnumbersale_price_minnumbersale_price_maxnumberprice_m2_minnumberprice_m2_maxnumberrent_price_m2_minnumberrent_price_m2_maxnumbersale_price_m2_minnumbersale_price_m2_maxnumberstreet_levelbooleanfrontage_min_mnumberfrontage_max_mnumberfloors_minnumberfloors_maxnumberceiling_min_mnumbersmoke_extractionbooleancornerbooleanshop_windowbooleanopen_planbooleanstep_freebooleanloading_accessbooleanlicencestringfood_service retail office gym nonelicence_activitiesstring[]transfer_price_minnumbertransfer_price_maxnumberbusiness_transferbooleanbusiness_typesstring[]keywordsstring[][]exclude_keywordsstring[]footfall_minnumberpop_walk10_minnumberpop_drive10_minnumbertransit_minnumbercompetitors_maxobject[]2 properties
kindstringrequiredrestaurants fast_food cafes shops supermarkets gymsmaxnumberrequiredown_stores_away_mnumbercompetitors_near_maxobject[]max businesses of a segment (or of the named chains) within within_m straight-line metres (1-1,000), from Overture Maps places. A property with an approximate pin gets no verdict.4 properties
segmentstringrequiredgym burger fast_food coffee bakery pharmacy supermarket fashion pizzawithin_mnumberrequiredmaxnumberrequiredchainsstring[]spending_per_resident_minnumberhigh_income_share_minnumberage_shares_minobject[]2 properties
bandstringrequired0_14 15_29 30_44 45_59 60pmin_pctnumberrequiredmeaningstringsortstringbest price_asc price_desc area_desc footfall_desc supply_gapgap_segmentstringgym burger fast_food coffee bakery pharmacy supermarket fashion pizzagap_radius_minteger300 600search_idstringlimitintegercursorstringstated_onlybooleanoffsetintegerpins_onlybooleanpins (id, lat, lon, precision, type, district, prices, area_m2) for up to 2000 matches a page, to draw a map. Needs no read-through and costs no results.checkbooleaninsightsbooleaninsights, charts as data over every match, each with a one-sentence answer, its count, scope, source and date: per criterion how many matches meet it, leave it unsaid or contradict it (and how many would state everything without it); with one price limit, what it reaches among premises of this kind and place before the limit, else what the matches ask per m²; and where the matches are by district or town. Asking prices; each unit counted once.langstringen deExample request
Placeholders only: replace the token and the values with your own.
curl -X POST "https://platform.casafari.com/v1/claro/search" \
-H "Authorization: Bearer $CASAFARI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"criteria": {
"operation": "rent",
"cities": [
"madrid"
],
"keywords": [
[
"salida de humos",
"sortida de fums"
],
[
"esquina",
"chaflán"
]
],
"exclude_keywords": [
"se traspasa"
]
},
"check": false
}'Responses
200 Search commercial premises
No body.
Example from the API description (long arrays shortened)
{
"search_id": "s_7hQ2",
"criteria": {
"operation": "rent",
"cities": [
"madrid"
],
"area_min": 120,
"smoke_extraction": true
},
"counts": {
"matching": 14,
"all_criteria_stated": 6,
"some_not_stated": 8
},
"not_applied": [],
"results": [
{
"id": "pm_3kX9vQ2LmT8a",
"title": "Local comercial en esquina",
"type": "retail",
"city": "madrid",
"city_name": "Madrid",
"district": "Centro",
"address": null,
"location_precision": "approximate",
"coordinates": {
"lat": 40.42,
"lon": -3.705,
"precision": "approximate"
},
"for_rent": true,
"for_sale": false,
"currency": "EUR",
"rent_eur_month": 5000,
"sale_eur": null,
"area_m2": 200,
"floor_number": 0,
"street_level": true,
"floors": 1,
"frontage_m": null,
"smoke_outlet": true,
"business_transfer": false,
"criteria": [
{
"criterion": "smoke_extraction",
"status": "met",
"evidence": "con salida de humos"
}
],
"photos": [
"https://st2.retelligence.co/c/1234/c/de/abcde350.jpg"
],
"excerpt": "Local en esquina con salida de humos. Zona de mucho paso.",
"agency": {
"name": "Agencia Sol",
"listing_url": "https://agenciasol.es/1"
},
"fit": {
"fit": "good",
"reason": "Meets every point of the brief: the district and smoke outlet.",
"data_conflict": {
"about": [
"district"
],
"says": "Lavapiés",
"quote": "Local en esquina en Lavapiés",
"data": "Centro",
"note": "The description names “Lavapiés”; the property's data places it in Centro. Check the agency's ad."
}
},
"location": {
"footfall_daily_walk_5min": 50000,
"footfall_weekday_avg_walk_5min": 52000,
"footfall_weekend_avg_walk_5min": 41000,
"residents_walk_10min": 20000,
"residents_drive_10min": 300000,
"residents_age_30_44_walk_10min": 5200,
"households_walk_10min": 9000,
"households_income_above_57824_walk_10min": null,
"spending_power_total_eur_walk_10min": 310000000,
"spending_power_per_resident_eur_walk_10min": 15500,
"cafes_walk_5min": 12,
"transit_stops_walk_5min": 5
},
"location_sources": {
"computed_at": "2026-10-12",
"groups": [
{
"fields": [
"footfall_daily_walk_5min",
"footfall_weekday_avg_walk_5min"
],
"unit": "footfall index: summed per-cell daily count within the walk, not distinct people (weekday/weekend are daily averages; the others split the daily count)",
"source": "Location Intelligence footfall estimates (collection 234)",
"vintage": "2024"
},
{
"fields": [
"residents_walk_10min",
"residents_drive_10min"
],
"unit": "residents",
"source": "Location Intelligence, MB Research sociodemographics (collection 87)",
"vintage": "2024"
}
]
}
}
],
"page": {
"offset": 0,
"limit": 200,
"total": 14
},
"next_cursor": null,
"notes": [
"The read-through of the results' text (check) runs only for pages of up to 50; results are ranked by criteria and meaning only."
]
}400 Invalid request
Type: object.
Show the response shape (3 fields)
errorobject2 properties
codestringrequiredmessagestringrequired401 Missing or invalid key
Type: object.
Show the response shape (3 fields)
errorobject2 properties
codestringrequiredmessagestringrequired403 No access
Type: object.
Show the response shape (3 fields)
errorobject2 properties
codestringrequiredmessagestringrequired429 Rate limited
Type: object.
Show the response shape (3 fields)
errorobject2 properties
codestringrequiredmessagestringrequired