# Search listings
# Overview
The listings search can be implemented as a classic faceted search, where customers can narrow down search results by applying multiple filters, or just like a standard based-form search, where customers specified all search parameters before every search.
The approach to use will depend on your interest, but we recommend using a faceted search because it would help customers to find what they are looking by narrowing down search results without the frustration of getting empty results. Once defined the approach to use, we add some settings to your Portal, so that the search will behave accordingly.
# Initial settings
Besides your decision of using a faceted search or a based-form search, there are other parameters, which right setup can help improving the performance and speed of the searches.
- Your portal need to display results on a map. In this case all possible matches are returned in an extra field, and you can choose between returning an extended resource for or just the basic resource.
- In case of using a faceted search, the facets do you want to get returned.
- When not using facets, which extra boolean filters to add, matching some of the features the platform provides.
- The normal behaviour is omitting extra data when the request page is not the first one, because it's supposed that those extra data didn't change since the previous request. If you want we can overwrite this behaviour.
# Filters and parameters
# Faceted search
When using facets the initial results are based on two groups of parameters:
- Basic parameters, which include the
occupancy_type,location,radiusandsource. - Eligibility parameters, which include the flag
eligible_onlyto determine if you want to return eligible listings only, and parametershousehold_income,deposit,home_local_authorityandwork_local_authority.
The response will contain all the facets the customer can use to narrow down the results. There are two kind of facets: static and dynamic. Static facets are connected to some fixed listing or property attributes, these ones include:
max_deposit: only whenoccupancy_typeis for-sale. Possible options are obtained by a discretization of values between min and max using a fixed step.max_full_value: only whenoccupancy_typeis for-sale. Possible options are obtained by a discretization of values between min and max using a fixed step.max_share_value: only whenoccupancy_typeis for-sale. Possible options are obtained by a discretization of values between min and max using a fixed step.max_monthly_rent: only whenoccupancy_typeis to-rent. Possible options are obtained by a discretization of values between min and max using a fixed step.schemes: possible schemes: shared ownership, help to buy, etc.status: availability statusnew_homes: it contains two options: New build and Resaletypes: property type: house, flat, etc.bedrooms: all possible amount of bedroomsbathrooms: all possible amount of bathrooms
On the other hand dynamic facets are build dynamically based on some of the features the listings have like:
parking: off street parking, garage, etc.other_featureswheelchair accessible, pets allowed, etc.
In the case of schemes, status, types, bedrooms, bathrooms and all dynamic facets, the query string parameters are interpreted as a collection, that's why these parameters should be sent ending in [], repeated for any selected option. Example:
bedrooms[]=2&bedrooms[]=3
# Based-form search
When using based-form search, you can use any of the basic, eligibility and static facet filters, and some other listed below:
min_deposit: only whenoccupancy_typeis for-salemin_full_value: only whenoccupancy_typeis for-salemin_share_value: only whenoccupancy_typeis for-salemin_monthly_rent: only whenoccupancy_typeis to-rentmin_bedrooms: min of bedroomsmax_bedrooms: max of bedroomsmin_bathrooms: min of bathroomsmax_bathrooms: max of bathrooms
We can also customise for you some additional filters to match some of the listing features provided by the platform. Example:
wheelchair_accesibleoff_street_parkingpets_allowed
To get possible schemes, types, full market price range and full monthly rent range, you can use the following endpoints:
GET /search-lists/schemes
GET /search-lists/types
GET /search-ranges/full-market-price
GET /search-ranges/monthly-rent
The first two will return a collection of objects with two fields id and name, and the last two will return an object with two fields: min and max.
# Basic parameters
| Name | Possible values |
|---|---|
occupancy_type | for-sale or to-rent |
location | Based on the Place Auto-complete service provided by the Google Places API and restricted to places in the UK. |
radius | Any number greater or equal to 0, but it's recommended a number in the set 0, 1, 3, 5, 10, 15, which are interpreted as 'This area only', 'Within 1 mile', 'Within 3 miles' and so on. |
source | This parameter should be sent when the search is the result of a redirection from another partner portal like sharedownership.net (opens new window), which redirect url will contain this parameter. For that specific case, its value will be sharedownership.net. By using this parameter, the API will implicit apply some filters and will sort results in a way that listings from clients in partnership with the source are displayed first. |
When requesting under a source, listing field partnerImageUrl can contain an image that should be displayed to identify listings from clients in partnership with the source.
partnerImageUrl
When some of these parameters are not specified, the engine will use the default values.
occupancy_type: for-salelocation: United Kingdomradius: 3
# Eligibility parameters
| Name | Possible values |
|---|---|
eligible_only | Set to 1, true, on or yes when you want to use this flag. |
household_income | A number with the total household income of the home seeker. |
deposit | A number with the deposit or savings of the home seeker. |
home_local_authority | An integer that represent the id in the database of the local authority where the home seeker lives. |
work_local_authority | An integer that represent the id in the database of the local authority where the home seeker works. |
Two more parameters can be sent: home_postcode and work_postcode with the postcode where the home seeker lives and works, respectively, but those parameters are not sent to check eligibility, they are used to get a more precise position on the map to compute distance to listings and provide a better ranking in some scenarios.
To get the a local authority id from a postcode, send a request to
GET /api/rest/portal/postcode/{postcode}
Notice that if the customer has signed in, and you want to use the values in his record to return only eligible listings, instead on the parameters, you only need to send eligible_only in true and the customer authorization token.
Based on the initial parameters, the API finds all listings for the desired occupancy type, which coordinates are inside the rectangle obtained by expanding the location rectangle boundaries according to the radius. If the flag eligible_only is set to true, only listings the customer is eligible for are returned, depending on the rest of the eligibility parameters.
# Featured and premium listings
Premium listings are listings that are highlighted and more prominent than regular listings, but they can be displayed at any position in the results, basically in their natural position according to the sorting criteria.
Featured listings are listings that are displayed on top of the results, and should be also highlighted, but probably in a different, more eye-catching way.
As part of the listings returned when searching listings, there is a field, displayAs, that return how the listing should be displayed.
It can return one of the possible values:
featured: it is a featured listing
premium: it is a premium listing
regular: it is just a regular listing
Premium and featured listings will always match the search filters, but the same featured listings can be displayed in different pages on the same search. The maximum total of featured listings coming in every page is set up in the back-end, but the number can be overwritten, by sending the parameter max_featured, although if this number is greater than the one in the settings, the latest will be used. The advantage of allowing overwriting this value, is that, depending on the view port, page design, etc., a different amount of featured listings could be more suitable to display on top.
# Sort and pagination
Results are paginated based on parameters page (page number, optional, default is 1) and size (maximum number of records to return per page, optional, default is 10), and can be sorted using parameter sort_by, where possible values are returned in every API response, as extra data in field sortOptions. By default listings will be returned sorted by the first sort option.
# Endpoint
The endpoint to search listings is:
GET /api/rest/portal/search
Below headers are not required, but default values will be used if they are omitted.
| Name | Possible values | Default value |
|---|---|---|
Accept-Version | number, indicating the version | Last version available |
Portal-Id | number, indicating the portal id | Keaze portal id |
QueryString parameters should be used to filter, sort and define pagination details.
# API response structure
All responses are JSON encoded, and when the request is correct, they will have the following fields. Notice that depending on the request parameters, the result could contain no items.
| Field name | Type | Description |
|---|---|---|
data | array | An array of object, where each object contains the listing details. |
pagination | object | An object with the pagination details. |
links | object | An object with links to first (first), previous (prev), next (next) and last (last) page. |
center | object | An object containing the latitude (lat) and longitude (lng) computed from the location parameter to identify the center of the area. See Location related fields. |
rectBounds | object | An object containing the bounds of the rectangle computed from the location parameter. See Location related fields. |
clearLocation | boolean | When passing an incorrect location, the API will use the default parameter and will return this parameter in false. |
mapListings | array | An array of all the listings returned by the search to be displayed on a map. Objects contains only a reduced set of fields, although there are two possible variants depending on the settings of your Portal. |
facets | array | An array of object, where each object represent a facet. |
sortOptions | array | An array with all possible values that can be used to sort the results. Every object in the array has two fields: value and text. The first item value will be used as default when the sort parameter is not sent. |
By default, when requesting a page, other than the first, the API will only return fields data, pagination and links. To change this behaviour get in touch with us, although it will attempt against the performance and speed of your searches.
Depending on your Portal settings, mapListings and facets could be excluded from your response.
# Listings
Every listing in data contains all the relevant information.
Listings are one of the key pieces of the platform, used to advertise developments and independent properties in different portals and third-party platforms. Unlike other housing platforms, in Keaze a listing can be used to advertise a group of new-build properties from the same building, that's why the same listing can be related to different bedrooms, although, depending on the home seeker preferences about the amount of bedrooms, the listing price and other attributes can change according to the search filters.
It's important to notice that no matter the occupancy type, the resource will be the same, so, some fields will only make sense when the listings are for sale, and other when the listings are to rent.
For a better understanding, fields will be grouped according to their uses and occupancy type.
| Field name | Type | Nullable | Description |
|---|---|---|---|
id | number | false | Reference Id to use when calling API for details. |
name | string | false | Listing name to display. |
slug | string | false | Slug to use in friendly urls to identify the listing. |
mainImage | object | true | Object that contains the main image urls for different view ports: largeSize (1080px width), mediumSize (720px width) & thumbnail (360px width). All versions use the aspect ratio 16x9. |
schemes | array | false | Array that contains details about the schemes for the listing. Every item is an object containing two fields: text (label of the tag) & color (hexadecimal color value, starting with #) |
shortDescription | string | true | A short description about the listing. The maximum length of the text is 512 characters. |
housingProvider | object | false | Object that contains the id, name and logoUrl of the housing provider that owns the listing. |
propertyTypeGroup | string | false | A text with the general property type, which match the facet type. Example: House, Flat. |
propertyType | string | false | A text with a more specific property type. Example: Bungalow, Terraced house. |
availabilityStatus | object | false | Object that contains the code & name of the availability status. Regardless the occupancy type, there are only 4 possible values. Codes don't depend on the occupancy type, but names do. Codes are: coming-soon, available, under-offer & closed, and they can be used to associate colors to each status. |
displayAs | string | false | Possible values: featured, premium and regular. |
forSale | boolean | false | The listing is for sale, otherwise is to rent. |
firstDibs | boolean | false | The listing is under a first dibs scheme, where it's only available for Londoners for a period of time. |
partnerName | string | true | When the search was redirected from a partner site, this field will contain the partner name (usually the same value as the source parameter) for listings in partnership with the source (listings from clients in partnership with the source). Those listings usually come first in the result, no matter the sort criteria. |
partnerImageUrl | string | true | When partnerName contains a value, this field will contain an image url that can be displayed on listings in partnership with the source. |
favourite | boolean | true | The listing is in the customer's favourite list. When there is no signed-in customer, this value will be null. |
createdAt | string | false | Date-time when the listing was created. |
| Address | |||
displayAddress | string | false | The address to display in the listing. The address doesn't contain the postcode. |
postcode | string | true | UK postcode for the listing. |
latitude | number | false | The latitude where the listing is. |
longitude | number | false | The longitude where the listing is. |
| Premises details | |||
newBuild | boolean | false | true is the listing if for new build properties. |
bedrooms | array | false | An array containing the different amount of bedrooms of the listing properties. Its values can be altered based on the search filters. |
bathrooms | array | true | An array containing the different amount of bathrooms of the listing properties. Its values can be altered based on the search filters. |
receptionRooms | array | true | An array containing the different amount of reception rooms of the listing properties. Its values can be altered based on the search filters. |
furnitureStatus | array | true | An array containing the different furniture status of the listing properties. Its values can be altered based on the search filters. Possible values are: unfurnished, part-furnished & furnished. |
tenure | string | false | Condition on which a property is held: leasehold or freehold. |
propertyFeatures | array | false | Array of objects describing all property features. Every object has two fields: section (text with the property feature section, e.g.: Parking ) & values (an array of string, containing all the property features for the section). |
| For sale | |||
fullMarketPrice | number | true | The minimum full price. |
depositValue | number | true | The minimum deposit value. |
isSharedOwnership | boolean | false | The listing scheme is shared ownership, so there's a share to buy and the rest to rent. |
minSharePercentage | number | true | The minimum share percentage if isSharedOwnership. |
minShareValue | number | true | The minimum share value if isSharedOwnership. |
subsidisedMonthlyRent | number | true | The minimum amount to pay for rent of the part you don't own when isSharedOwnership. |
maxGovernmentLoanPercent | number | true | Depending on the scheme, eligible buyers could receive a government loan. In such a case, this value is the maximum government loan percent. |
maxGovernmentLoanValue | number | true | The maximum government loan value. |
monthlyServiceCharge | number | true | Monthly bill that covers the costs of any repairs or maintenance to the structure of the building, including drainage, insurance and management charges. |
annualGroundRent | number | true | Rent to pay annually to the freeholder or landlord of the leasehold property. |
reservationFee | number | true | Reservation fee to a developer that allows a buyer to reserve a property for a period. |
| To rent | |||
monthlyRent | number | true | Monthly rent. |
weeklyRent | number | true | Weekly rent. |
rentalDeposit | number | true | Rental deposit value. |
minTenancyMonths | number | true | Minimum tenancy term in months. |
maxTenancyMonths | number | true | Maximum tenancy term in months. |
| Both: For sale & To rent | |||
administrationFee | number | true | Fee charged by an agency to cover expenses related to record-keeping and/or other. |
# Response example for a listing
{
"id": 5157,
"name": "Lister Gardens",
"slug": "lister-gardens",
"mainImage": {
"thumbnail": "https://static.propertybooking.co.uk/assets/developments/5157/gallery/360/external.jpg",
"mediumSize": "https://static.propertybooking.co.uk/assets/developments/5157/gallery/720/external.jpg",
"largeSize": "https://static.propertybooking.co.uk/assets/developments/5157/gallery/1080/external.jpg"
},
"schemes": [
{
"text": "Shared ownership",
"color": "#FF4F35"
}
],
"shortDescription": "",
"housingProvider": {
"id": 50,
"name": "Redwing",
"logoUrl": "https://static.propertybooking.co.uk/assets/housing-providers/50/logo.png"
},
"propertyTypeGroup": "Flat",
"propertyType": "Flat",
"availabilityStatus": {
"name": "Coming soon",
"code": "coming-soon"
},
"propertyFeatures": [
{
"section": "Parking",
"values": ["Off street parking"]
},
{
"section": "Others",
"values": ["Pets allowed"]
}
],
"displayAs": "regular",
"forSale": true,
"firstDibs": false,
"displayAddress": "Crosby Road North, Liverpool",
"postcode": "L22 0AB",
"latitude": 53.4755929,
"longitude": -3.0272693,
"newBuild": true,
"bedrooms": [1, 2],
"bathrooms": [1],
"receptionRooms": [1],
"furnitureStatus": ["furnished"],
"tenure": "leasehold",
"isSharedOwnership": true,
"fullMarketPrice": 125000,
"depositValue": 2500,
"minSharePercentage": 40,
"minShareValue": 50000,
"subsidisedMonthlyRent": 172,
"maxGovernmentLoanPercent": null,
"maxGovernmentLoanValue": null,
"monthlyServiceCharge": 110,
"annualGroundRent": 90,
"reservationFee": null,
"monthlyRent": null,
"weeklyRent": null,
"rentalDeposit": null,
"minTenancyMonths": null,
"maxTenancyMonths": null,
"administrationFee": null,
"createdAt": "2019-08-20T07:15:31+00:00"
}
# Listing payload for map
When mapListings is returned, it will contain a collection with all the listings matching the search criteria, although the payload for every listing only has relevant fields.
Depending on your map implementation, we can set up our system to return one of the two possible payloads: basic or extended. While the second one contains more fields, it could affect the performance of the search, so, use only this option if required.
# Extended Payload
| Field name | Type | Nullable | Description |
|---|---|---|---|
id | number | false | Reference Id to use when calling API for details. |
name | string | false | Listing name to display. |
slug | string | false | Slug to use in friendly urls to identify the listing. |
mainImage | object | true | Object that contains the main image urls for different view ports: largeSize (1080px width), mediumSize (720px width) & thumbnail (360px width). All versions use the aspect ratio 16x9. |
schemes | array | false | Array that contains details about the schemes for the listing. Every item is an object containing two fields: text (label of the tag) & color (hexadecimal color value, starting with #) |
propertyType | string | false | A text with a more specific property type. Example: Bungalow, Terraced house. |
availabilityStatus | object | false | Object that contains the code & name of the availability status. Regardless the occupancy type, there are only 4 possible values. Codes don't depend on the occupancy type, but names do. Codes are: coming-soon, available, under-offer & closed, and they can be used to associate colors to each status. |
displayAs | string | false | Possible values: featured, premium and regular. |
displayAddress | string | false | The address to display in the listing. The address doesn't contain the postcode. |
latitude | number | false | The latitude where the listing is. |
longitude | number | false | The longitude where the listing is. |
bedrooms | array | false | An array containing the different amount of bedrooms of the listing |
forSale | boolean | false | The listing is for sale, otherwise is to rent. |
isSharedOwnership | boolean | false | The listing scheme is shared ownership, so there's a share to buy and the rest to rent. |
fullMarketPrice | number | true | The minimum full price. |
minShareValue | number | true | The minimum share value if isSharedOwnership. |
monthlyRent | number | true | Monthly rent when properties are to rent. |
# Basic Payload
The basic payload only contains the fields: id, name, slug, schemes, latitude and longitude.
# Pagination details
The pagination object contains information useful to generate custom pagination component in the user interface.
| Field name | Type | Description |
|---|---|---|
currentPage | number | 1-based index of the current page. |
perPage | number | Total items displayed per page. |
from | number | Start item index displayed in the current page: (currentPage - 1)*perPage + 1. |
to | number | End item index displayed in the current page: min(currentPage*perPage, total). |
total | number | Total items in the whole result. |
lastPage | number | Index of the last available page, useful to request items for the last page. |
# Response example
{
...
"pagination": {
"currentPage": 1,
"perPage": 10,
"from": 1,
"to": 10,
"total": 909,
"lastPage": 91
},
...
}
# Location related fields
As expressed before, location parameter should be based on the Place Auto-complete service provided by the Google Places API, which should also be restricted to places in the UK. When this value is sent, the API calls the Google API to get the geometry location data, specifically the location rectangle boundaries which are used, along with the radius, to filter properties based on their latitude and longitude, and the location center latitude and longitude which are used to compute distances for sorting purposes.
The API will return the center and the bounds of the expanded rectangle (based on the radius); the first one as an object composed of two fields: lat (latitude) and lng (longitude), and the second one as an object composed of 4 fields: north (latitude of the north bound), south (latitude of the south bound), west (longitude of the west bound) and east (longitude of the east bound).
When the location and radius haven't changed, it's recommended to send back the parameters lat, lng, north, south, east and west in every subsequent request, so the API doesn't need to request the Google API to get those values.
# Response example
{
...
"center": {
"lat": 55.378051,
"lng": -3.435973
},
"rectBounds": {
"north": 60.9156999,
"east": 33.9165549,
"south": 34.5614,
"west": -8.8988999
},
"clearLocation": false,
...
}
# Facets
Facets values are dynamic built based on some settings and on the properties filtered from the initial parameters.
Static facets are always returned first and then the dynamic facets, and they will provide all the necessary information for the user interface to know how to deal with them.
# Facet structure
| Field name | Type | Description |
|---|---|---|
name | string | Facet name to display in the UI |
param | string | Parameter to send in the request when filtering the facet |
multiValue | boolean | When true, the facet parameter is interpreted as an array and should be sent using brackets, example: bedrooms[]=1&bedrooms[]=2 to send two values to the facet bedrooms. Notice that even when sending only one value for a multiValue facet, brackets should be used. |
options | array | Array of possible options the facet has |
# Facet option structure
| Field name | Type | Description |
|---|---|---|
value | number | string | The value to send when the customer choose the facet value |
text | string | Value to display in the UI |
count | number | Total of properties that match the facet value for the current filters |
To avoid getting no results when the customer select facets, facet options where count is zero, should be disabled in the UI.
As explained, some facets, computed from listing numerical fields (usually currency fields), are discretized in order to return a list of numerical options. In these cases, every option is interpreted as a range from 0 to the value itself.
Notice that every time the customer change a facet value, a new request should be sent to the API, including all selected facet values. Remember that multi-value facet parameters should include brackets at the end of parameter name.
The following request:
GET /api/rest/portal/search?occupancy_type=for-sale&location=London&radius=0&max_deposit=5500&bedrooms[]=1&bedrooms[]=2&schemes[]=1
will search listings for sale in London where the scheme is Shared Ownership (1), the maximum deposit is £5500, and they contain properties with 1 or 2 bedrooms. Notice that max_deposit is not multiValue, while bedrooms and schemes are.
# Response example
{
...
"facets": [
{
"name": "My deposit budget",
"param": "max_deposit",
"multiValue": false,
"options": [
{
"value": 1500,
"text": "£1,500",
"count": 6
},
{
"value": 3000,
"text": "£3,000",
"count": 28
},
{
"value": 4500,
"text": "£4,500",
"count": 117
},
...
]
},
...
{
"name": "Schemes",
"param": "schemes",
"multiValue": true,
"options": [
{
"value": 2,
"text": "Discounted market sale",
"count": 1
},
{
"value": 3,
"text": "Private sale",
"count": 27
},
{
"value": 1,
"text": "Shared ownership",
"count": 881
}
]
},
...
{
"name": "Bedrooms",
"param": "bedrooms",
"multiValue": true,
"options": [
{
"value": 1,
"text": "1",
"count": 373
},
{
"value": 2,
"text": "2",
"count": 476
},
{
"value": 3,
"text": "3",
"count": 55
},
{
"value": 4,
"text": "4",
"count": 3
}
]
},
...
],
}