# 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

When using facets the initial results are based on two groups of parameters:

  • Basic parameters, which include the occupancy_type, location, radius and source.
  • Eligibility parameters, which include the flag eligible_only to determine if you want to return eligible listings only, and parameters household_income, deposit, home_local_authority and work_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 when occupancy_type is for-sale. Possible options are obtained by a discretization of values between min and max using a fixed step.
  • max_full_value: only when occupancy_type is for-sale. Possible options are obtained by a discretization of values between min and max using a fixed step.
  • max_share_value: only when occupancy_type is for-sale. Possible options are obtained by a discretization of values between min and max using a fixed step.
  • max_monthly_rent: only when occupancy_type is 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 status
  • new_homes: it contains two options: New build and Resale
  • types: property type: house, flat, etc.
  • bedrooms: all possible amount of bedrooms
  • bathrooms: 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_features wheelchair 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

More details

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 when occupancy_type is for-sale
  • min_full_value: only when occupancy_type is for-sale
  • min_share_value: only when occupancy_type is for-sale
  • min_monthly_rent: only when occupancy_type is to-rent
  • min_bedrooms: min of bedrooms
  • max_bedrooms: max of bedrooms
  • min_bathrooms: min of bathrooms
  • max_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_accesible
  • off_street_parking
  • pets_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.

Tip

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-sale
  • location: United Kingdom
  • radius: 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}

Tip

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.

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.

Warning

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
    },
    ...
}

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).

Tip

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

Tip

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
                }
            ]
        },
        ...
    ],
}