Options Data for US Stocks: End-of-Day and Historical Learn more

Real Estate Data API (beta)

The EODHD Real Estate Data API delivers residential property price statistics for more than sixty countries, sourced from the Bank for International Settlements. It covers two BIS datasets: Selected Property Prices, a harmonised headline index that is comparable across countries, and Detailed Property Prices, a deeper set of national series broken down by dwelling type, region, and vintage. The data suits macro and real-estate analysts, quant researchers, and anyone tracking housing markets across countries on a consistent basis.

Four endpoints share the same authentication and the same JSON response envelope: a country list, the Selected Property Prices series for a country, the Detailed Property Prices observations for a country, and the catalogue of detailed series available for a country. Selected Property Prices are quarterly, with periods expressed as year and quarter, for example 2020-Q1. Detailed Property Prices carry their own frequency per series, which may be monthly, quarterly, half-yearly, or annual.

Overview

Every endpoint is reached over HTTPS with a GET request and authenticated by an api_token query parameter, the same token used across the EODHD API. Requests return a JSON object with three top-level keys: data, the array of records; meta, which carries the total row count, the active page window, and dataset provenance such as source and base year; and links, which holds the pagination link to the next page. Results are paged with page[offset] and page[limit], where the default page size is 50 rows and the maximum is 500. Add fmt=csv to any endpoint to receive the same data as a CSV download.

All endpoints live under a common base path. Country codes are two-letter ISO codes and are case insensitive; lowercase input is accepted and normalised to uppercase.

https://eodhd.com/api/real-estate/{code}?api_token=YOUR_TOKEN

Country Coverage

Before requesting price data, list the countries that are available and check which datasets each one carries. Some countries have Selected Property Prices only, some have Detailed Property Prices only, and most have both. A handful of entries are BIS aggregates that group several economies rather than a single country.

Country List

Returns every available country with two boolean flags indicating which datasets are present. Use these flags to decide whether to call the Selected Property Prices endpoint, the Detailed Property Prices endpoint, or both for a given country.

https://eodhd.com/api/real-estate/countries?api_token=YOUR_TOKEN

Method GET. Authentication by api_token. Pagination by page[offset] and page[limit]. Response is a JSON envelope with data, meta, and links.

Parameters

api_token string required
Your EODHD API token
page[limit] integer optional
Rows per page, default 50 (Default: 1-500)
page[offset] integer optional
Rows to skip, default 0

Request Example

https://eodhd.com/api/real-estate/countries?api_token=YOUR_TOKEN
(Sign up for free to get an API token)
curl --location "https://eodhd.com/api/real-estate/countries?api_token=YOUR_TOKEN&fmt=json"
(Sign up for free to get an API token)
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => 'https://eodhd.com/api/real-estate/countries?api_token=YOUR_TOKEN&fmt=json',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'GET',
));

$data = curl_exec($curl);
curl_close($curl);

try {
    $data = json_decode($data, true, 512, JSON_THROW_ON_ERROR);
    var_dump($data);
} catch (Exception $e) {
    echo 'Error. '.$e->getMessage();
}
(Sign up for free to get an API token)
import requests

url = f'https://eodhd.com/api/real-estate/countries?api_token=YOUR_TOKEN&fmt=json'
data = requests.get(url).json()

print(data)
(Sign up for free to get an API token)
library(httr)
library(jsonlite)

url <- 'https://eodhd.com/api/real-estate/countries?api_token=YOUR_TOKEN&fmt=json'
response <- GET(url)

if (http_type(response) == "application/json") {
    content <- content(response, "text", encoding = "UTF-8")
    cat(content)
} else {
    cat("Error while receiving data\n")
}
(Sign up for free to get an API token)
New to coding? Our ChatGPT assistant can generate code in any language tailored to our API. Simply describe how you want to use our data, and get a working piece of code. Don’t forget to replace the API token with your own.

Try it now (it's free)!

How to use it (YouTube)

Response Example

{
  "data": [
    { "code": "US", "name": "United States", "has_spp": true, "has_dpp": true },
    { "code": "AE", "name": "United Arab Emirates", "has_spp": false, "has_dpp": true }
  ],
  "meta": { "total": 64, "offset": 0, "limit": 50 },
  "links": { "next": "https://eodhd.com/api/real-estate/countries?fmt=json&page[offset]=50&page[limit]=50" }
}

Response Fields

FieldTypeDescription
codestringTwo-letter country code, or a BIS aggregate code
namestringCountry name
has_sppbooleanTrue when Selected Property Prices are available for this country
has_dppbooleanTrue when Detailed Property Prices are available for this country

Selected Property Prices

Selected Property Prices are the BIS headline residential property price series, harmonised so that levels and growth rates are comparable across countries. Each observation is available as a nominal value and as a real value, and as a price index or a year-on-year percentage change. Index values are rebased to a common base year, reported in the meta block.

Property Price Series

Returns the Selected Property Prices observations for one country. Without filters the response includes every combination of type and metric. Narrow the result with filter[type] and filter[metric], and restrict the period range with filter[from] and filter[to].

https://eodhd.com/api/real-estate/{code}?api_token=YOUR_TOKEN

Method GET. Authentication by api_token. Pagination by page[offset] and page[limit]. Response is a JSON envelope with data, meta, and links.

Parameters

api_token string required
Your EODHD API token
filter[type] enum optional
Price basis. Allowed values: nominal, real
filter[metric] enum optional
Measure. Allowed values: index, yoy. index is the price index level, yoy is the year-on-year percentage change
filter[from] string optional
Start period, format YYYY-Qn, for example 2020-Q1, inclusive
filter[to] string optional
End period, format YYYY-Qn, for example 2024-Q4, inclusive, on or after filter[from]
page[limit] integer optional
Rows per page, default 50 (Default: 1-500)
page[offset] integer optional
Rows to skip, default 0

Request Example

https://eodhd.com/api/real-estate/US?api_token=YOUR_TOKEN&filter[type]=nominal&filter[metric]=index&filter[from]=2020-Q1&filter[to]=2024-Q4
(Sign up for free to get an API token)
curl --location "https://eodhd.com/api/real-estate/US?api_token=YOUR_TOKEN&filter[type]=nominal&filter[metric]=index&filter[from]=2020-Q1&filter[to]=2024-Q4&fmt=json"
(Sign up for free to get an API token)
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => 'https://eodhd.com/api/real-estate/US?api_token=YOUR_TOKEN&filter[type]=nominal&filter[metric]=index&filter[from]=2020-Q1&filter[to]=2024-Q4&fmt=json',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'GET',
));

$data = curl_exec($curl);
curl_close($curl);

try {
    $data = json_decode($data, true, 512, JSON_THROW_ON_ERROR);
    var_dump($data);
} catch (Exception $e) {
    echo 'Error. '.$e->getMessage();
}
(Sign up for free to get an API token)
import requests

url = f'https://eodhd.com/api/real-estate/US?api_token=YOUR_TOKEN&filter[type]=nominal&filter[metric]=index&filter[from]=2020-Q1&filter[to]=2024-Q4&fmt=json'
data = requests.get(url).json()

print(data)
(Sign up for free to get an API token)
library(httr)
library(jsonlite)

url <- 'https://eodhd.com/api/real-estate/US?api_token=YOUR_TOKEN&filter[type]=nominal&filter[metric]=index&filter[from]=2020-Q1&filter[to]=2024-Q4&fmt=json'
response <- GET(url)

if (http_type(response) == "application/json") {
    content <- content(response, "text", encoding = "UTF-8")
    cat(content)
} else {
    cat("Error while receiving data\n")
}
(Sign up for free to get an API token)
New to coding? Our ChatGPT assistant can generate code in any language tailored to our API. Simply describe how you want to use our data, and get a working piece of code. Don’t forget to replace the API token with your own.

Try it now (it's free)!

How to use it (YouTube)

Response Example

{
  "data": [
    { "period": "2020-Q1", "value": 158.4799, "type": "nominal", "metric": "index" },
    { "period": "2020-Q2", "value": 159.8064, "type": "nominal", "metric": "index" }
  ],
  "meta": {
    "country_code": "US",
    "country_name": "United States",
    "type": "nominal",
    "metric": "index",
    "base_year": "2010 = 100",
    "frequency": "quarterly",
    "source": "BIS",
    "total": 4,
    "from": "2020-Q1",
    "to": "2024-Q4",
    "offset": 0,
    "limit": 50
  },
  "links": { "next": null }
}

Response Fields

FieldTypeDescription
periodstringObservation quarter, format YYYY-Qn
valuenumberIndex level when metric is index, or percentage change when metric is yoy
typestringPrice basis, nominal or real
metricstringMeasure, index or yoy

Sign up & Get Data

Detailed Property Prices

Detailed Property Prices are the fuller set of national series that BIS collects from member central banks and statistical offices. Unlike the harmonised Selected Property Prices, the detailed series vary by country in what they cover: different dwelling types, regions, and index vintages. Each series is described along several BIS dimensions, given both as codes and as human-readable labels. Query the series catalogue first to see which combinations exist for a country and read their titles, then request the observations.

Detailed Observations

Returns the Detailed Property Prices observations for one country. Each row carries the BIS dimension codes that identify which series it belongs to, each with a matching human-readable label, alongside the unit of measure. Narrow the result with the dimension filters below.

https://eodhd.com/api/real-estate/{code}/detailed?api_token=YOUR_TOKEN

Method GET. Authentication by api_token. Pagination by page[offset] and page[limit]. Response is a JSON envelope with data, meta, and links.

Parameters

api_token string required
Your EODHD API token
filter[property_type] string optional
BIS property-type dimension code. Read the available codes and their meaning from the series catalogue endpoint
filter[area] string optional
BIS covered-area dimension code, identifying the region or geographic coverage. Read the available codes from the series catalogue endpoint
filter[vintage] string optional
BIS vintage dimension code, identifying the index vintage. Read the available codes from the series catalogue endpoint
filter[freq] string optional
Observation frequency code, one of Q quarterly, A annual, M monthly, or H half-yearly
filter[from] string optional
Start period, inclusive, in the period format of the series, for example 2020-01 or 2020-Q1
filter[to] string optional
End period, inclusive, in the same format as filter[from]
page[limit] integer optional
Rows per page, default 50 (Default: 1-500)
page[offset] integer optional
Rows to skip, default 0

Request Example

https://eodhd.com/api/real-estate/US/detailed?api_token=YOUR_TOKEN&filter[property_type]=1
(Sign up for free to get an API token)
curl --location "https://eodhd.com/api/real-estate/US/detailed?api_token=YOUR_TOKEN&filter[property_type]=1&fmt=json"
(Sign up for free to get an API token)
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => 'https://eodhd.com/api/real-estate/US/detailed?api_token=YOUR_TOKEN&filter[property_type]=1&fmt=json',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'GET',
));

$data = curl_exec($curl);
curl_close($curl);

try {
    $data = json_decode($data, true, 512, JSON_THROW_ON_ERROR);
    var_dump($data);
} catch (Exception $e) {
    echo 'Error. '.$e->getMessage();
}
(Sign up for free to get an API token)
import requests

url = f'https://eodhd.com/api/real-estate/US/detailed?api_token=YOUR_TOKEN&filter[property_type]=1&fmt=json'
data = requests.get(url).json()

print(data)
(Sign up for free to get an API token)
library(httr)
library(jsonlite)

url <- 'https://eodhd.com/api/real-estate/US/detailed?api_token=YOUR_TOKEN&filter[property_type]=1&fmt=json'
response <- GET(url)

if (http_type(response) == "application/json") {
    content <- content(response, "text", encoding = "UTF-8")
    cat(content)
} else {
    cat("Error while receiving data\n")
}
(Sign up for free to get an API token)
New to coding? Our ChatGPT assistant can generate code in any language tailored to our API. Simply describe how you want to use our data, and get a working piece of code. Don’t forget to replace the API token with your own.

Try it now (it's free)!

How to use it (YouTube)

Response Example

{
  "data": [
    {
      "period": "1975-Q4",
      "value": 22.481,
      "frequency": "Q",
      "covered_area": "0",
      "covered_area_label": "Whole country",
      "property_type": "1",
      "property_type_label": "All types of dwellings",
      "vintage": "1",
      "vintage_label": "Existing",
      "unit_measure": "426: Index, 2000 Jan = 100",
      "unit_measure_label": null
    }
  ],
  "meta": {
    "country_code": "US",
    "source": "BIS",
    "dataset": "DPP",
    "total": 202,
    "offset": 0,
    "limit": 50,
    "filters": { "property_type": "1" }
  },
  "links": { "next": "https://eodhd.com/api/real-estate/US/detailed?filter%5Bproperty_type%5D=1&page%5Boffset%5D=50&page%5Blimit%5D=50" }
}

Response Fields

FieldTypeDescription
periodstringObservation period. Format follows the series frequency, for example 2020-Q1 or 2020-01
valuenumberObservation value, in the units given by unit_measure
frequencystringObservation frequency, one of Q, A, M, or H
covered_areastringBIS covered-area dimension code
covered_area_labelstringHuman-readable label for covered_area, for example Whole country
property_typestringBIS property-type dimension code
property_type_labelstringHuman-readable label for property_type, for example All types of dwellings
vintagestringBIS vintage dimension code
vintage_labelstringHuman-readable label for vintage, for example Existing
unit_measurestringUnit of measure and index base, for example 426: Index, 2000 Jan = 100
unit_measure_labelstringHuman-readable label for the unit of measure, null when the raw unit is already descriptive

Series Catalogue

Returns the catalogue of Detailed Property Prices series available for one country. Each entry describes a series along the BIS dimensions and gives a human-readable title. Use this endpoint to interpret the dimension codes returned by the detailed observations endpoint, and to decide which combination to filter for.

https://eodhd.com/api/real-estate/{code}/detailed/series?api_token=YOUR_TOKEN

Method GET. Authentication by api_token. Response is a JSON envelope with data and meta.

Parameters

api_token string required
Your EODHD API token

Request Example

https://eodhd.com/api/real-estate/US/detailed/series?api_token=YOUR_TOKEN
(Sign up for free to get an API token)
curl --location "https://eodhd.com/api/real-estate/US/detailed/series?api_token=YOUR_TOKEN&fmt=json"
(Sign up for free to get an API token)
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => 'https://eodhd.com/api/real-estate/US/detailed/series?api_token=YOUR_TOKEN&fmt=json',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'GET',
));

$data = curl_exec($curl);
curl_close($curl);

try {
    $data = json_decode($data, true, 512, JSON_THROW_ON_ERROR);
    var_dump($data);
} catch (Exception $e) {
    echo 'Error. '.$e->getMessage();
}
(Sign up for free to get an API token)
import requests

url = f'https://eodhd.com/api/real-estate/US/detailed/series?api_token=YOUR_TOKEN&fmt=json'
data = requests.get(url).json()

print(data)
(Sign up for free to get an API token)
library(httr)
library(jsonlite)

url <- 'https://eodhd.com/api/real-estate/US/detailed/series?api_token=YOUR_TOKEN&fmt=json'
response <- GET(url)

if (http_type(response) == "application/json") {
    content <- content(response, "text", encoding = "UTF-8")
    cat(content)
} else {
    cat("Error while receiving data\n")
}
(Sign up for free to get an API token)
New to coding? Our ChatGPT assistant can generate code in any language tailored to our API. Simply describe how you want to use our data, and get a working piece of code. Don’t forget to replace the API token with your own.

Try it now (it's free)!

How to use it (YouTube)

Response Example

{
  "data": [
    {
      "covered_area": "0",
      "covered_area_label": "Whole country",
      "property_type": "1",
      "property_type_label": "All types of dwellings",
      "vintage": "1",
      "vintage_label": "Existing",
      "compiling_org": "2",
      "priced_unit": "0",
      "seasonal_adj": "1",
      "unit_measure": "426: Index, 2000 Jan = 100",
      "unit_measure_label": null,
      "title": "United States - Residential property price index, existing dwellings, whole country"
    }
  ],
  "meta": { "country_code": "US", "total": 5 }
}

Response Fields

FieldTypeDescription
covered_areastringBIS covered-area dimension code
covered_area_labelstringHuman-readable label for covered_area
property_typestringBIS property-type dimension code
property_type_labelstringHuman-readable label for property_type
vintagestringBIS vintage dimension code
vintage_labelstringHuman-readable label for vintage
compiling_orgstringBIS compiling-organisation dimension code
priced_unitstringBIS priced-unit dimension code
seasonal_adjstringSeasonal adjustment dimension code
unit_measurestringUnit of measure and index base
unit_measure_labelstringHuman-readable label for the unit of measure, null when the raw unit is already descriptive
titlestringHuman-readable description of the series

Pagination and CSV

The data endpoints are paged with page[offset] and page[limit]. The default page size is 50 rows and the maximum is 500; a larger page[limit] returns 422. The meta block reports the total row count and the active window, and links.next holds the URL for the following page, or null on the last page.

Add fmt=csv to any endpoint to receive the same data as a CSV file instead of JSON. The CSV is UTF-8 with a byte-order mark and is served as an attachment, and values are protected against spreadsheet formula injection. The column headers match the JSON field names.

https://eodhd.com/api/real-estate/US?api_token=YOUR_TOKEN&filter%5Btype%5D=nominal&filter%5Bmetric%5D=index&fmt=csv

Response Codes

CodeMeaning
200Success. Response body carries data, meta, and where applicable links
401Missing or invalid api_token
403Token is valid but the plan does not include access to this dataset
404Unknown country code. Codes are case insensitive and are normalised to uppercase
405Method not allowed. Only GET is supported
422Invalid parameter — a malformed period, page[limit] above 500, an end period before the start period, or an out-of-range filter value

Attribution and Licensing

All property price data is sourced from the Bank for International Settlements. When redistributing or displaying this data, cite the source as shown below.

SourceRequired attribution
BISSource: BIS residential property price statistics, Bank for International Settlements (www.bis.org)

Methodology and Limitations

  • Selected Property Prices are quarterly, with periods expressed as year and quarter, for example 2020-Q1, and filter[from] and filter[to] use this same format. Detailed Property Prices carry their own frequency per series, which may be monthly, quarterly, half-yearly, or annual, so their periods and filter bounds follow that frequency.
  • Selected Property Prices are harmonised and comparable across countries. Index values are rebased to a common base year, reported in the meta base_year field; a year-on-year metric is also provided. Both a nominal and a real basis are available.
  • Detailed Property Prices are national series and are not harmonised across countries. Their coverage, dwelling type, and index base differ by country, so compare like with like within a single country. Each observation carries BIS dimension codes with a matching human-readable label field; the series catalogue lists every combination available for a country.
  • Not every country carries both datasets. Check the has_spp and has_dpp flags from the country list before requesting data, and note that some entries are BIS aggregates covering several economies.
  • Country codes are case insensitive and are normalised to uppercase; an unknown code returns 404. The page[limit] maximum is 500. Filter keys and values are validated, and an unknown filter key or an out-of-range value returns 422.
Compare plans and find your fit
Free and paid plans for individual and commercial use
Go to Pricing
Chat