Transaction Statistics
POST
transactions/statistics
Returns transaction statistics for the specified administrative division and time period. For example, average yearly sale prices in Zurich for a time period between 2010 and 2014 can be obtained.
Statistics can only be obtained for one administrative division at a time. If you want to obtain statistics for multiple administrative divisions, you need to make multiple calls.
Request#
Example Request 1#
curl -X POST 'https://api.pricehubble.com/api/v1/transactions/statistics' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer 74126eab0a9048d993bda4b1b55ae074' \
-d '{
"statistics": [
{
"metric": "sale_price",
"type": "mean"
},
{
"metric": "sale_price",
"type": "count"
},
{
"metric": "sale_price",
"type": "percentile",
"parameters": {
"percentileRank": 50
}
},
{
"metric": "sale_price",
"type": "percentile_rank",
"parameters": {
"percentileValue": 750000
}
},
{
"metric": "sale_price",
"type": "percentile_rank",
"parameters": {
"percentileValue": 1000000
}
}
],
"filters": {
"propertyType": "apartment",
"divisionLevel8": "261",
"transactionDate": {
"min": "2017-01",
"max": "2018-12"
}
},
"dossierId": "3bac39b8-2d84-4ae9-a693-40502071ea5d",
"countryCode": "CH"
}'
Example Request 2 (group by year)#
curl -X POST 'https://api.pricehubble.com/api/v1/transactions/statistics' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer 74126eab0a9048d993bda4b1b55ae074' \
-d '{
"statistics": [
{
"metric": "sale_price",
"type": "count"
}
],
"groupBy": {
"field": "transaction_date",
"period": "year"
},
"filters": {
"propertyType": "apartment",
"divisionLevel8": "261",
"transactionDate": {
"min": "2017-01",
"max": "2018-12"
}
},
"dossierId": "3bac39b8-2d84-4ae9-a693-40502071ea5d",
"countryCode": "CH"
}'
Example Request 3 (group by price)#
curl -X POST 'https://api.pricehubble.com/api/v1/transactions/statistics' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer 74126eab0a9048d993bda4b1b55ae074' \
-d '{
"statistics": [
{
"metric": "sale_price",
"type": "count"
}
],
"groupBy": {
"field": "sale_price",
"groups": [
{
"upperBound": 1000000
},
{
"lowerBound": 1000000,
"upperBound": 2000000
},
{
"lowerBound": 2000000
}
]
},
"filters": {
"propertyType": "apartment",
"divisionLevel8": "261",
"transactionDate": {
"min": "2017-01",
"max": "2018-12"
}
},
"dossierId": "3bac39b8-2d84-4ae9-a693-40502071ea5d",
"countryCode": "CH"
}'
Either filters.coordinates
and filters.radius
or exactly one filters.divisionLevel*
must be provided.
If you would like to filter by division levels but only have an address or coordinates and don't know the official ID of the administrative division, you can use the Administrative Divisions endpoint to look up the administrative division and the respective ID.
Field | Description | Type | Remarks |
---|---|---|---|
statistics | array of objects | ||
statistics[i].type | string | Valid values are mean , count , percentile or percentile_rank |
|
statistics[i].metric | string | Valid values are sale_price , sale_price_per_square_meter , living_area or number_of_rooms |
|
statistics[i].parameters | object | Parameters for the chosen statistic type, currently only required by percentile & percentile_rank . |
|
statistics[i].parameters.percentileRank | integer | - min: 0, max: 100 Only required by percentile statistic type (try 25 , 50 , 75 or 95 to get the 25th, 50th (median), 75th or 95th percentiles) |
|
statistics[i].parameters.percentileValue | integer | - min: 0 Only required by percentile_rank statistic type (the percentile rank of a value relative to the list of all values) |
|
groupBy | object | ||
groupBy.field | The field by which to group the results | string | Valid values are sale_price , sale_price_per_square_meter , living_area , number_of_rooms or transaction_date |
groupBy.groups | List of explicit groups | array | required if groupBy.field is sale_price , sale_price_per_square_meter , living_area or number_of_rooms ; min items: 1, max items: 24 |
groupBy.groups[i] | object | Either lowerBound or upperBound is required |
|
groupBy.groups[i].lowerBound | float or integer | ||
groupBy.groups[i].upperBound | float or integer | upperBound is excluded of the group. That way upperBound of one group can be the lowerBound of the next group. | |
groupBy.period | string | Valid values are month , quarter or year ; required if groupBy.field is transaction_date |
|
filters | object | ||
filters.transactionDate | Filter on the transactions' sale date | object | |
filters.transactionDate.min | string | Format: YYYY-MM | |
filters.transactionDate.max | string | Format: YYYY-MM | |
filters.coordinates | Filter by location from the given set of coordinates | Coordinates | Requires filters.radius to be passed along |
filters.radius | Radius of the location filter, in m | integer | min: 0, max: 10'000 Requires filters.coordinates to be passed along |
filters.divisionLevel6 | The official ID of the level 6 division | string | |
filters.divisionLevel8 | The official ID of the level 8 division | string | |
filters.divisionLevel100 | The official ID of the level 100 division | string | |
filters.salePrice | Filter on transaction sale price | object | |
filters.salePrice.currency | Currency of the sale price filter | Currency | |
filters.salePrice.min | Lower bound for transaction sale price | integer | |
filters.salePrice.max | Upper bound for transaction sale price | integer | |
filters.propertyType | string | Valid values are apartment or house |
|
filters.livingArea | Filter on net living area | object | |
filters.livingArea.min | Lower bound for net living area | integer | In m2 For UK : in sq.ft |
filters.livingArea.max | Upper bound for net living area | integer | In m2 For UK : in sq.ft |
filters.buildingYear | Filter on building year | object | |
filters.buildingYear.min | Lower bound for building year | integer | |
filters.buildingYear.max | Upper bound for building year | integer | |
filters.numberOfRooms | Filter on number of rooms | object | |
filters.numberOfRooms.min | Lower bound for number of rooms | float | |
filters.numberOfRooms.max | Upper bound for number of rooms | float | |
filters.isNew | Filter on transaction's isNew flag |
boolean | |
dossierId | ID of the dossier | string | If this field is added to the request, then the location must be the same as the dossier's location (address or coordinates) |
countryCode | ISO country code | string | Only CH , FR and UK |
Response#
Example Response 1#
{
"items": [
{
"statistics": [
{
"metric": "sale_price",
"type": "mean",
"value": 1328515.26
},
{
"metric": "sale_price",
"type": "count",
"value": 544
},
{
"metric": "sale_price",
"parameters": {
"percentileRank": 50
},
"type": "percentile",
"value": 1200000.0
},
{
"metric": "sale_price",
"parameters": {
"percentileValue": 750000
},
"type": "percentile_rank",
"value": 13.6
},
{
"metric": "sale_price",
"parameters": {
"percentileValue": 1000000
},
"type": "percentile_rank",
"value": 34.38
}
]
}
]
}
Example Response 2 (group by year)#
{
"items": [
{
"groupId": "2017",
"statistics": [
{
"metric": "sale_price",
"type": "count",
"value": 265
}
]
},
{
"groupId": "2018",
"statistics": [
{
"metric": "sale_price",
"type": "count",
"value": 279
}
]
}
]
}
Example Response 3 (group by price)#
{
"items": [
{
"groupId": "0",
"groupUpperBound": 1000000,
"statistics": [
{
"metric": "sale_price",
"type": "count",
"value": 187
}
]
},
{
"groupId": "1",
"groupLowerBound": 1000000,
"groupUpperBound": 2000000,
"statistics": [
{
"metric": "sale_price",
"type": "count",
"value": 290
}
]
},
{
"groupId": "2",
"groupLowerBound": 2000000,
"statistics": [
{
"metric": "sale_price",
"type": "count",
"value": 67
}
]
}
]
}
Prices are returned in the country's main currency.
Field | Description | Type | Remarks |
---|---|---|---|
items | List of statistics; per “group" if grouping was requested | array of objects | If grouping by transaction_date was requested, the list is sorted by time in ascending order and the length of the array is equal to the number of periods between request.filters.transactionDate.min and request.filters.transactionDate.max ; if any other grouping was requested the order corresponds to the order of the groups in the request (i.e. the order of request.groupBy.groups ) and the length of the array is equal to the length of request.groupBy.groups |
items[i].groupId | string | E.g. "2018-01", "2018-Q1" or "2018" if grouping by transaction_date was requested, or the (zero-based) index of the group (as a string) if any other grouping was requested |
|
items[i].groupLowerBound | float or integer | Corresponds to what was set in request.groupBy.groups[i].lowerBound |
|
items[i].groupUpperBound | float or integer | Corresponds to what was set in request.groupBy.groups[i].upperBound |
|
items[i].statistics | array of objects | ||
items[i].statistics[i].type | string | Valid values are mean , count , percentile or percentile_rank |
|
items[i].statistics[i].metric | string | Valid values are sale_price , sale_price_per_square_meter , living_area or number_of_rooms |
|
items[i].statistics[i].parameters | Parameters for the chosen statistic type, if provided in the request | object | |
items[i].statistics[i].value | Value of the requested statistic | float or integer | Not set if there is not enough data to compute the requested statistic for the requested group |