{"openapi":"3.1.0","info":{"title":"Expat Living Italy — data API","version":"1.0.0","description":"Honest, sourced numbers for people relocating to or retiring in Italy: population, foreign residents by citizenship, property purchase and rent price, and verified tax-regime eligibility, at comune and province grain. Every value carries provenance (source, vintage, extraction date, coverage) and missing data returns null with a reason — never a zero, never an imputed average. Tax-eligibility results describe places, not people: they are not advice.","contact":{"url":"https://www.expatliving.it"}},"servers":[{"url":"https://www.expatliving.it/api/v1","description":"Production"}],"paths":{"/comuni/{istatCode}":{"get":{"operationId":"getComune","summary":"Get one comune's profile","description":"Population, foreign residents by citizenship, purchase and rent price, price-to-rent, verified tax-regime eligibility, and a province rollup, for one Italian comune identified by its 6-digit ISTAT code. The workhorse endpoint — always cite the vintage and source in any answer built from it.","parameters":[{"name":"istatCode","in":"path","required":true,"description":"6-digit ISTAT comune code, e.g. 075029.","schema":{"type":"string","pattern":"^[0-9]{6}$"}}],"responses":{"200":{"description":"The comune's profile.","content":{"application/json":{"schema":{"type":"object","properties":{"place":{"type":"object","properties":{"istatCode":{"type":"string","description":"6-digit ISTAT comune code, e.g. 075029."},"slug":{"type":"string","description":"Stable URL slug — never changes even if a comune merges (brief §4)."},"name":{"type":"string"},"province":{"type":"string"},"provinceCode":{"type":"string"},"provinceSlug":{"type":"string"},"region":{"type":"string"},"regionSlug":{"type":"string"},"lat":{"type":"number"},"lng":{"type":"number"}},"required":["istatCode","slug","name","province","provinceCode","provinceSlug","region","regionSlug","lat","lng"],"additionalProperties":false},"population":{"type":"object","properties":{"value":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"unit":{"type":"string"},"source":{"type":"string"},"vintage":{"type":"string","description":"The period the value describes, e.g. \"2025H2\" or \"2025\" — not when it was fetched."},"extractedOn":{"type":"string","description":"ISO date this value was extracted from the source."},"coverage":{"description":"How many of Italy's places this dataset covers at all, e.g. 7587 of 7894 comuni.","type":"object","properties":{"in":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"of":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["in","of"],"additionalProperties":false},"method":{"type":"string","description":"URL to the methodology page for this dataset."},"license":{"type":"string"},"reason":{"description":"Present only when value is null: why this place has no figure.","type":"string"}},"required":["value","unit","source","vintage","extractedOn","method","license"],"additionalProperties":false},"foreignResidentsByCitizenship":{"type":"object","properties":{"value":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"number"}},{"type":"null"}]},"unit":{"type":"string"},"source":{"type":"string"},"vintage":{"type":"string","description":"The period the value describes, e.g. \"2025H2\" or \"2025\" — not when it was fetched."},"extractedOn":{"type":"string","description":"ISO date this value was extracted from the source."},"coverage":{"description":"How many of Italy's places this dataset covers at all, e.g. 7587 of 7894 comuni.","type":"object","properties":{"in":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"of":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["in","of"],"additionalProperties":false},"method":{"type":"string","description":"URL to the methodology page for this dataset."},"license":{"type":"string"},"reason":{"description":"Present only when value is null: why this place has no figure.","type":"string"}},"required":["value","unit","source","vintage","extractedOn","method","license"],"additionalProperties":false,"description":"Counts by ISO-2 citizenship code. Citizenship, not birthplace — excludes foreign-born Italian citizens."},"totalForeignResidents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"purchasePriceEurM2":{"type":"object","properties":{"value":{"type":["number","null"]},"unit":{"type":"string"},"source":{"type":"string"},"vintage":{"type":"string","description":"The period the value describes, e.g. \"2025H2\" or \"2025\" — not when it was fetched."},"extractedOn":{"type":"string","description":"ISO date this value was extracted from the source."},"coverage":{"description":"How many of Italy's places this dataset covers at all, e.g. 7587 of 7894 comuni.","type":"object","properties":{"in":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"of":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["in","of"],"additionalProperties":false},"method":{"type":"string","description":"URL to the methodology page for this dataset."},"license":{"type":"string"},"reason":{"description":"Present only when value is null: why this place has no figure.","type":"string"}},"required":["value","unit","source","vintage","extractedOn","method","license"],"additionalProperties":false},"rentPriceEurM2Month":{"type":"object","properties":{"value":{"type":["number","null"]},"unit":{"type":"string"},"source":{"type":"string"},"vintage":{"type":"string","description":"The period the value describes, e.g. \"2025H2\" or \"2025\" — not when it was fetched."},"extractedOn":{"type":"string","description":"ISO date this value was extracted from the source."},"coverage":{"description":"How many of Italy's places this dataset covers at all, e.g. 7587 of 7894 comuni.","type":"object","properties":{"in":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"of":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["in","of"],"additionalProperties":false},"method":{"type":"string","description":"URL to the methodology page for this dataset."},"license":{"type":"string"},"reason":{"description":"Present only when value is null: why this place has no figure.","type":"string"}},"required":["value","unit","source","vintage","extractedOn","method","license"],"additionalProperties":false},"priceToRentYears":{"type":"object","properties":{"value":{"type":["number","null"]},"unit":{"type":"string"},"source":{"type":"string"},"vintage":{"type":"string","description":"The period the value describes, e.g. \"2025H2\" or \"2025\" — not when it was fetched."},"extractedOn":{"type":"string","description":"ISO date this value was extracted from the source."},"coverage":{"description":"How many of Italy's places this dataset covers at all, e.g. 7587 of 7894 comuni.","type":"object","properties":{"in":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"of":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["in","of"],"additionalProperties":false},"method":{"type":"string","description":"URL to the methodology page for this dataset."},"license":{"type":"string"},"reason":{"description":"Present only when value is null: why this place has no figure.","type":"string"}},"required":["value","unit","source","vintage","extractedOn","method","license"],"additionalProperties":false,"description":"Years of rent that equal the purchase price. Not a yield, an ROI, or a payback period."},"taxRegimeEligibility":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"label":{"type":"string"},"href":{"type":"string","description":"Path to this regime's own page on expatliving.it."},"maxPopulation":{"description":"The regime's population ceiling, when it has one.","type":"number"},"headroom":{"description":"Residents between this comune and the ceiling.","type":"number"},"ruleIsIncomplete":{"type":"boolean","description":"True when the rule admits comuni by routes not yet verified — silence about OTHER regimes proves nothing."}},"required":["slug","label","href","ruleIsIncomplete"],"additionalProperties":false},"description":"Verified regimes only — \"placesNotPeople\": geographic eligibility, not personal advice."},"provinceRollup":{"type":"object","properties":{"name":{"type":"string"},"code":{"type":"string"},"slug":{"type":"string"},"purchasePriceEurM2":{"type":"object","properties":{"value":{"type":["number","null"]},"unit":{"type":"string"},"source":{"type":"string"},"vintage":{"type":"string","description":"The period the value describes, e.g. \"2025H2\" or \"2025\" — not when it was fetched."},"extractedOn":{"type":"string","description":"ISO date this value was extracted from the source."},"coverage":{"description":"How many of Italy's places this dataset covers at all, e.g. 7587 of 7894 comuni.","type":"object","properties":{"in":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"of":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["in","of"],"additionalProperties":false},"method":{"type":"string","description":"URL to the methodology page for this dataset."},"license":{"type":"string"},"reason":{"description":"Present only when value is null: why this place has no figure.","type":"string"}},"required":["value","unit","source","vintage","extractedOn","method","license"],"additionalProperties":false},"rentPriceEurM2Month":{"type":"object","properties":{"value":{"type":["number","null"]},"unit":{"type":"string"},"source":{"type":"string"},"vintage":{"type":"string","description":"The period the value describes, e.g. \"2025H2\" or \"2025\" — not when it was fetched."},"extractedOn":{"type":"string","description":"ISO date this value was extracted from the source."},"coverage":{"description":"How many of Italy's places this dataset covers at all, e.g. 7587 of 7894 comuni.","type":"object","properties":{"in":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"of":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["in","of"],"additionalProperties":false},"method":{"type":"string","description":"URL to the methodology page for this dataset."},"license":{"type":"string"},"reason":{"description":"Present only when value is null: why this place has no figure.","type":"string"}},"required":["value","unit","source","vintage","extractedOn","method","license"],"additionalProperties":false}},"required":["name","code","slug","purchasePriceEurM2","rentPriceEurM2Month"],"additionalProperties":false}},"required":["place","population","foreignResidentsByCitizenship","totalForeignResidents","purchasePriceEurM2","rentPriceEurM2Month","priceToRentYears","taxRegimeEligibility","provinceRollup"],"additionalProperties":false}}}},"404":{"description":"No comune with that ISTAT code.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false}}}}}}},"/datasets":{"get":{"operationId":"listDatasets","summary":"List every dataset this API can serve","description":"The catalogue: every dataset's vintage, geographic grain, license, and whether it is currently servable. A dataset still in draft status is listed with servable: false and returns no values elsewhere in the API until it is verified — publishing the gap is deliberate.","responses":{"200":{"description":"The dataset catalogue.","content":{"application/json":{"schema":{"type":"object","properties":{"datasets":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"label":{"type":"string"},"source":{"type":"string"},"vintage":{"type":"string"},"extractedOn":{"type":"string"},"license":{"type":"string"},"grain":{"type":"string","enum":["comune","province","region","national"]},"servable":{"type":"boolean","description":"False for datasets still \"draft\" — see CLAUDE.md non-negotiable #9."}},"required":["slug","label","source","vintage","extractedOn","license","grain","servable"],"additionalProperties":false}}},"required":["datasets"],"additionalProperties":false}}}}}}}}}