flatin.pt Places API

Where to live, municipality figures, construction barometer and the glossary — the same answers as the MCP tools.

GitHub OpenAPI
Business capability
Property Data AE-230.60

Operations 7

0 of 7 operations are conformant: apis.io called them with no credentials and the responses matched this contract; 3 more answered but could not be checked against a schema. Checked 2026-11-11. how this works · status file

GET /api/v1/where-to-live Where-to-live guides: the list of cities and regions observed #
GET /api/v1/where-to-live/{city} Where to live in a city: verdict by area, noise and safety #
GET /api/v1/municipalities/compare Compare 2 to 5 municipalities side by side #
GET /api/v1/municipalities/{municipality}/stats Everything flatin.pt publishes about one municipality #
GET /api/v1/construction-barometer Construction barometer: building-works cases and INE licences observed #
GET /api/v1/glossary Glossary of Portuguese home-buying terms: the list observed #
GET /api/v1/glossary/{term} One glossary term: definition, law reference and page #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/flatin-pt:flatin-pt-places-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

flatin-pt-places-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: flatin.pt Places API
  summary: 'Portuguese home buying, machine-readable: new-build developments, where-to-live guides, municipality data, IMT and stamp duty (Imposto do Selo) on a purchase, IMI rates for all 308 municipalities.'
  description: 'Keyless public API of flatin.pt. Numbers are the same as on the site and come from the official tables; every successful JSON answer carries an attribution field — show it next to the numbers. Rate limits: 120 requests per minute per IP address, HTTP 429 with Retry-After when exceeded. Status: https://flatin.pt/status/. MCP server: https://flatin.pt/mcp.'
  termsOfService: https://flatin.pt/en/legal/terms/
  contact:
    name: flatin.pt
    url: https://flatin.pt/en/tools/api-and-data/
    email: info@flatin.pt
  license:
    name: CC BY 4.0 (data)
    url: https://creativecommons.org/licenses/by/4.0/
  version: 1.0.0
servers:
- url: https://flatin.pt
tags:
- name: Places
  description: Where to live, municipality figures, construction barometer and the glossary — the same answers as the MCP tools.
paths:
  /api/v1/where-to-live:
    get:
      tags:
      - Places
      summary: 'Where-to-live guides: the list of cities and regions'
      description: The cities and regions flatin.pt has a where-to-live guide for, with the municipalities each one covers and the guide's address in the requested language.
      operationId: where_to_live_index_api_v1_where_to_live_get
      parameters:
      - name: language
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: 'Language of the site content in the answer (verdicts, definitions, labels) and of the page links: pt, en, ru, ua (or uk), de, fr, nl. Field names and the summary stay English. Default: en'
          examples:
          - en
          enum:
          - pt
          - en
          - ru
          - ua
          - de
          - fr
          - nl
          - uk
          title: Language
        description: 'Language of the site content in the answer (verdicts, definitions, labels) and of the page links: pt, en, ru, ua (or uk), de, fr, nl. Field names and the summary stay English. Default: en'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '400':
          description: 'The request was not understood: `error` is one of bad_language, bad_profile, bad_verdict, bad_include, bad_measure, bad_granularity, bad_count, municipality_required, ambiguous (with `candidates` or `suggestions`)'
          content:
            application/json:
              example:
                error: ambiguous
                message: '''Vila'' matches several municipalities; pick one'
                candidates:
                - code: '0313'
                  name: Vila Verde
                  distrito: Braga
        '404':
          description: 'Nothing matches: `error` is not_found, with `suggestions` (or `guides`) to pick from'
          content:
            application/json:
              example:
                error: not_found
                message: municipality 'Atlantis' is not among the 308
                suggestions: []
        '503':
          description: 'The IMI table is being re-checked: data_unavailable'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/where-to-live/{city}:
    get:
      tags:
      - Places
      summary: 'Where to live in a city: verdict by area, noise and safety'
      description: 'The verdict of a flatin.pt guide by area — live (good to live), depends (depends on you) or avoid (we advise against) — with the reason as written on the site, who each area suits, and the sources of its numbers. Sections: noise in plain words (festivals, bars, aircraft under approach paths), safety as dated, sourced police operations (local reputation of a place, never a claim about its residents), prices, municipal housing, climate, transport. `city` is a guide name in any site language, its slug, or a municipality inside a guide (Gaia → Greater Porto). A profile keeps the areas that suit it plus every ''avoid'' area.'
      operationId: where_to_live_api_v1_where_to_live__city__get
      parameters:
      - name: city
        in: path
        required: true
        schema:
          type: string
          description: City, region or municipality
          examples:
          - Porto
          title: City
        description: City, region or municipality
      - name: language
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: 'Language of the site content in the answer (verdicts, definitions, labels) and of the page links: pt, en, ru, ua (or uk), de, fr, nl. Field names and the summary stay English. Default: en'
          examples:
          - en
          enum:
          - pt
          - en
          - ru
          - ua
          - de
          - fr
          - nl
          - uk
          title: Language
        description: 'Language of the site content in the answer (verdicts, definitions, labels) and of the page links: pt, en, ru, ua (or uk), de, fr, nl. Field names and the summary stay English. Default: en'
      - name: profile
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Keep areas that suit this profile (and every avoid area)
          enum:
          - family
          - car_free
          - retirees
          - remote
          - budget
          - nightlife
          title: Profile
        description: Keep areas that suit this profile (and every avoid area)
      - name: verdict
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Keep only areas with this verdict
          enum:
          - live
          - depends
          - avoid
          title: Verdict
        description: Keep only areas with this verdict
      - name: include
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: 'Comma-separated parts of the guide to return. Default: areas,noise,safety. `all` returns every section'
          examples:
          - areas,noise,safety,prices
          title: Include
        description: 'Comma-separated parts of the guide to return. Default: areas,noise,safety. `all` returns every section'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '400':
          description: 'The request was not understood: `error` is one of bad_language, bad_profile, bad_verdict, bad_include, bad_measure, bad_granularity, bad_count, municipality_required, ambiguous (with `candidates` or `suggestions`)'
          content:
            application/json:
              example:
                error: ambiguous
                message: '''Vila'' matches several municipalities; pick one'
                candidates:
                - code: '0313'
                  name: Vila Verde
                  distrito: Braga
        '404':
          description: 'Nothing matches: `error` is not_found, with `suggestions` (or `guides`) to pick from'
          content:
            application/json:
              example:
                error: not_found
                message: municipality 'Atlantis' is not among the 308
                suggestions: []
        '503':
          description: 'The IMI table is being re-checked: data_unavailable'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/municipalities/compare:
    get:
      tags:
      - Places
      summary: Compare 2 to 5 municipalities side by side
      description: The same figures as /municipalities/{municipality}/stats for two to five municipalities in one answer. Pass `municipalities` as a comma-separated list or repeat the parameter.
      operationId: municipalities_compare_api_v1_municipalities_compare_get
      parameters:
      - name: municipalities
        in: query
        required: false
        schema:
          type: array
          items:
            type: string
          description: Names or four-digit codes, 2 to 5
          examples:
          - - Porto
            - Matosinhos
            - Vila Nova de Gaia
          default: []
          title: Municipalities
        description: Names or four-digit codes, 2 to 5
      - name: language
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: 'Language of the site content in the answer (verdicts, definitions, labels) and of the page links: pt, en, ru, ua (or uk), de, fr, nl. Field names and the summary stay English. Default: en'
          examples:
          - en
          enum:
          - pt
          - en
          - ru
          - ua
          - de
          - fr
          - nl
          - uk
          title: Language
        description: 'Language of the site content in the answer (verdicts, definitions, labels) and of the page links: pt, en, ru, ua (or uk), de, fr, nl. Field names and the summary stay English. Default: en'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '400':
          description: 'The request was not understood: `error` is one of bad_language, bad_profile, bad_verdict, bad_include, bad_measure, bad_granularity, bad_count, municipality_required, ambiguous (with `candidates` or `suggestions`)'
          content:
            application/json:
              example:
                error: ambiguous
                message: '''Vila'' matches several municipalities; pick one'
                candidates:
                - code: '0313'
                  name: Vila Verde
                  distrito: Braga
        '404':
          description: 'Nothing matches: `error` is not_found, with `suggestions` (or `guides`) to pick from'
          content:
            application/json:
              example:
                error: not_found
                message: municipality 'Atlantis' is not among the 308
                suggestions: []
        '503':
          description: 'The IMI table is being re-checked: data_unavailable'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      x-flatin-example: /api/v1/municipalities/compare?municipalities=Porto,Matosinhos
  /api/v1/municipalities/{municipality}/stats:
    get:
      tags:
      - Places
      summary: Everything flatin.pt publishes about one municipality
      description: IMI rate with its history (Autoridade Tributária), INE median sale price per m², purchasing power and population, INE licensed buildings and new dwellings by year, municipal building-works cases by year where we collect them, the construction-barometer row, the number of new-build developments in the catalogue and the where-to-live guides. Every block names its source and its date; a figure that is not published is null, never estimated. `municipality` is a name (any case, accents optional, Lisbon/Oporto accepted) or the four-digit code.
      operationId: municipality_stats_api_v1_municipalities__municipality__stats_get
      parameters:
      - name: municipality
        in: path
        required: true
        schema:
          type: string
          description: Name or four-digit code
          examples:
          - Porto
          - '1312'
          title: Municipality
        description: Name or four-digit code
      - name: language
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: 'Language of the site content in the answer (verdicts, definitions, labels) and of the page links: pt, en, ru, ua (or uk), de, fr, nl. Field names and the summary stay English. Default: en'
          examples:
          - en
          enum:
          - pt
          - en
          - ru
          - ua
          - de
          - fr
          - nl
          - uk
          title: Language
        description: 'Language of the site content in the answer (verdicts, definitions, labels) and of the page links: pt, en, ru, ua (or uk), de, fr, nl. Field names and the summary stay English. Default: en'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '400':
          description: 'The request was not understood: `error` is one of bad_language, bad_profile, bad_verdict, bad_include, bad_measure, bad_granularity, bad_count, municipality_required, ambiguous (with `candidates` or `suggestions`)'
          content:
            application/json:
              example:
                error: ambiguous
                message: '''Vila'' matches several municipalities; pick one'
                candidates:
                - code: '0313'
                  name: Vila Verde
                  distrito: Braga
        '404':
          description: 'Nothing matches: `error` is not_found, with `suggestions` (or `guides`) to pick from'
          content:
            application/json:
              example:
                error: not_found
                message: municipality 'Atlantis' is not among the 308
                suggestions: []
        '503':
          description: 'The IMI table is being re-checked: data_unavailable'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/construction-barometer:
    get:
      tags:
      - Places
      summary: 'Construction barometer: building-works cases and INE licences'
      description: 'Without `municipality`: the 12-month count of municipal building-works cases for each municipality we collect, the change on the previous 12 months, cases per 1,000 residents, and the fixed-panel index. With `municipality`: our monthly (or yearly) series where we collect it, plus INE''s official yearly series of licensed buildings and new dwellings for any of the 308. A case is not a licence granted and not a building. The full series is at /api/v1/barometer/series.'
      operationId: construction_barometer_api_v1_construction_barometer_get
      parameters:
      - name: municipality
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Name or four-digit code
          examples:
          - Porto
          title: Municipality
        description: Name or four-digit code
      - name: measure
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: 'Kind of works. Default: total_works'
          enum:
          - total_works
          - new_build
          - alter_extend
          title: Measure
        description: 'Kind of works. Default: total_works'
      - name: granularity
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: 'Period of our own series. Default: month'
          enum:
          - month
          - year
          title: Granularity
        description: 'Period of our own series. Default: month'
      - name: language
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: 'Language of the site content in the answer (verdicts, definitions, labels) and of the page links: pt, en, ru, ua (or uk), de, fr, nl. Field names and the summary stay English. Default: en'
          examples:
          - en
          enum:
          - pt
          - en
          - ru
          - ua
          - de
          - fr
          - nl
          - uk
          title: Language
        description: 'Language of the site content in the answer (verdicts, definitions, labels) and of the page links: pt, en, ru, ua (or uk), de, fr, nl. Field names and the summary stay English. Default: en'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '400':
          description: 'The request was not understood: `error` is one of bad_language, bad_profile, bad_verdict, bad_include, bad_measure, bad_granularity, bad_count, municipality_required, ambiguous (with `candidates` or `suggestions`)'
          content:
            application/json:
              example:
                error: ambiguous
                message: '''Vila'' matches several municipalities; pick one'
                candidates:
                - code: '0313'
                  name: Vila Verde
                  distrito: Braga
        '404':
          description: 'Nothing matches: `error` is not_found, with `suggestions` (or `guides`) to pick from'
          content:
            application/json:
              example:
                error: not_found
                message: municipality 'Atlantis' is not among the 308
                suggestions: []
        '503':
          description: 'The IMI table is being re-checked: data_unavailable'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/glossary:
    get:
      tags:
      - Places
      summary: 'Glossary of Portuguese home-buying terms: the list'
      description: Every term of the flatin.pt glossary with its Portuguese and English name and its page in the requested language.
      operationId: glossary_index_api_v1_glossary_get
      parameters:
      - name: language
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: 'Language of the site content in the answer (verdicts, definitions, labels) and of the page links: pt, en, ru, ua (or uk), de, fr, nl. Field names and the summary stay English. Default: en'
          examples:
          - en
          enum:
          - pt
          - en
          - ru
          - ua
          - de
          - fr
          - nl
          - uk
          title: Language
        description: 'Language of the site content in the answer (verdicts, definitions, labels) and of the page links: pt, en, ru, ua (or uk), de, fr, nl. Field names and the summary stay English. Default: en'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '400':
          description: 'The request was not understood: `error` is one of bad_language, bad_profile, bad_verdict, bad_include, bad_measure, bad_granularity, bad_count, municipality_required, ambiguous (with `candidates` or `suggestions`)'
          content:
            application/json:
              example:
                error: ambiguous
                message: '''Vila'' matches several municipalities; pick one'
                candidates:
                - code: '0313'
                  name: Vila Verde
                  distrito: Braga
        '404':
          description: 'Nothing matches: `error` is not_found, with `suggestions` (or `guides`) to pick from'
          content:
            application/json:
              example:
                error: not_found
                message: municipality 'Atlantis' is not among the 308
                suggestions: []
        '503':
          description: 'The IMI table is being re-checked: data_unavailable'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/glossary/{term}:
    get:
      tags:
      - Places
      summary: 'One glossary term: definition, law reference and page'
      description: Definition, where the term comes up when buying, the articles of law with the official text and the date they were checked. `term` is the term's key, its Portuguese or English name, a name in any site language or an abbreviation (IMT, CPCV, VPT); close spellings are found.
      operationId: glossary_term_api_v1_glossary__term__get
      parameters:
      - name: term
        in: path
        required: true
        schema:
          type: string
          description: Term
          examples:
          - cpcv
          title: Term
        description: Term
      - name: language
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: 'Language of the site content in the answer (verdicts, definitions, labels) and of the page links: pt, en, ru, ua (or uk), de, fr, nl. Field names and the summary stay English. Default: en'
          examples:
          - en
          enum:
          - pt
          - en
          - ru
          - ua
          - de
          - fr
          - nl
          - uk
          title: Language
        description: 'Language of the site content in the answer (verdicts, definitions, labels) and of the page links: pt, en, ru, ua (or uk), de, fr, nl. Field names and the summary stay English. Default: en'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '400':
          description: 'The request was not understood: `error` is one of bad_language, bad_profile, bad_verdict, bad_include, bad_measure, bad_granularity, bad_count, municipality_required, ambiguous (with `candidates` or `suggestions`)'
          content:
            application/json:
              example:
                error: ambiguous
                message: '''Vila'' matches several municipalities; pick one'
                candidates:
                - code: '0313'
                  name: Vila Verde
                  distrito: Braga
        '404':
          description: 'Nothing matches: `error` is not_found, with `suggestions` (or `guides`) to pick from'
          content:
            application/json:
              example:
                error: not_found
                message: municipality 'Atlantis' is not among the 308
                suggestions: []
        '503':
          description: 'The IMI table is being re-checked: data_unavailable'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
components:
  schemas:
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
            - type: string
            - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
      - loc
      - msg
      - type
      title: ValidationError