The Realtime Listings Service Documentation 2.3

1. Introduction

Thank you for your interest in the Zoopla Property Group (ZPG) Real-time Listings Service.

ZPG operates a number of property websites; the principal ones being Zoopla and PrimeLocation. Our mission is to provide the most useful online resources to property consumers, and be the most effective partner to property professionals.

To achieve this, data about available properties needs to be transferred from estate agents' software systems to ZPG. Traditionally the data transfer involves exporting large volumes of data from a database, providing a comprehensive picture of the estate agent's properties at that time. This method has the benefit of being very easy to implement but it is also very slow (due to the amount of data involved) and inefficient (most of that data has not changed since the previous export). These limitations mean that it is usually only performed once a day, overnight.

The level of service that users and estate agents now expect means that the daily bulk transfer of data is no longer suitable; the ZPG Real-time Listings Service is its replacement. It allows estate agents to make changes on their system and have those changes reflected on ZPG's websites within minutes. It achieves this by reducing the amount of data that needs to be transferred: only information about listings which have actually changed needs to be transmitted (i.e. updates are incremental).

What follows is the technical specification of the ZPG Real-time Listings Service so that anyone who wishes to integrate it with their systems may do so.

2. Overview

The ZPG Real-time Listings Service is designed to interact with a central data provider. Estate agents manage their properties using either a cloud-based property management solution or locally installed software which logs changes to a central data system. As changes are registered on this central system it sends messages to the ZPG Real-time Listings Service, in order to update ZPG's version of that data, which is displayed on its websites.

2.1 Simple technical overview

The ZPG Real-time Listings Service uses a fairly conventional web service design. Clients communicate with the service using standard HTTP over a secure connection (HTTPS). Each method (action) that the service provides has its own dedicated URL. The data required for the method is sent in a JSON formatted message.

The service runs in two environments: sandbox and live. The sandbox environment is used for testing your system's messaging interactions; whilst the live environment is for data you intend to be published to our websites. Initially we will provide you with access to the sandbox environment and once you are happy with your implementation you will be granted access to the live environment.

There are two principal entities which are tracked: branches and listings. A branch can have many listings associated with it but a listing can only belong to one branch. Whenever a change to a branch or listing is registered by your system, its full details should be sent to us. We will then replace our record entirely with your new version.

The media content for a listing (e.g.: images; brochures) is not transferred directly via the service. Instead, the content should be hosted on a web server and associated URLs included in a listing/update message. We will then download that content from your web server.

2.2 Simple workflow

The ZPG Real-time Listings Service is used in the following way:
  1. When information about a branch changes, you send a listing/update message to replace the data we have.
  2. When information about a listing changes, you send a branch/update message to replace the data we have. When sending this message you also include some metadata (ZPG-Listing-ETag) which will enable you to detect data synchronisation issues at a later date.
  3. When a listing becomes inactive, you send a listing/delete message.
  4. In order to check that the listing data for a branch has been synchronised properly, you can send a listing/listmessage. This will return information about all of the branch's listings, including the ZPG-Listing-ETags that were previously sent. You can then ascertain if there are any data differences between ZPG's system and yours, and correct any issues by sending listing/update and listing/delete messages as appropriate.

For a more detailed description of this workflow please see Workflow overview.

3. Security and authentication

There are two aspects to security: privacy and identity. By using HTTPS we can guarantee both: communications are encrypted (privacy) and both parties are assured that they are communicating directly with the person/system they expect (identity). HTTPS uses standard public-private key-pair cryptography (messages that are encrypted with one key can only be decrypted with the other key) which is wrapped up in an identity exchange mechanism called X.509 Certificates. The set-up process is:
  1. You create a public-private key-pair. The private key is integral to proving your identity; it should never leave your corporate network, nor be given to any third-party, including ZPG. The public key, as its name suggests, can be given to anyone.
  2. The public key, plus details about your corporate identity (name) are combined to generate a certificate signing request file. (Since anyone can perform steps 1 and 2, this cannot be used as a certificate on its own; it needs to be verified and signed by a certificate authority. In this case, ZPG will be acting as the certificate authority.)
  3. You send your certificate signing request file (in PEM format) to ZPG via our certificate signing request submission page. This page will check that it is both formatted correctly and does not use encryption settings which are no longer secure. Upon acceptance of your certificate signing request, you will be provided with a verification token (which looks like "XXXX-XXXX-XXXX") that you should write down and keep safe.
  4. ZPG will contact you and verbally confirm that you sent us a certificate signing request and ask for your verification token.
  5. Having confirmed your identity and your request, ZPG will sign the certificate signing request and return the resulting signed certificate to you.
  6. You will need to configure your software so that it can use the signed certificate and private key when contacting our service, so that both systems can authenticate each other's identity and encrypt communications.

3.1 Example: creating keys and certificate signing request with OpenSSL on Linux

How you generate a public-private key-pair and associated certificate signing request will be dependent on your particular software platform. For reference, this is how you might do it on Linux using openssl:

1. Create the public-private key-pair.

openssl genrsa -out private.pem 2048

This generates a key-pair using the RSA algorithm with keys that are 2048 bits long, which is then output to the file private.pem. Note that this file includes everything about the generated key-pair and the public key can be produced from the information it contains. Reminder: private.pem should never leave your corporate network.

We suggest that when you create your key-pair you do not specify an accompanying password. Otherwise you'll have to provide that password (to decrypt the file) every time your system is restarted. The lack of a password will not affect the security of the connection itself. The example given here does not set a password.

If you are interested, you can look at the contents of private.pem:

openssl rsa -in private.pem -text

2. Create a certificate signing request.

openssl req -new -sha256 -key private.pem -out public.csr
This creates a new certificate signing request, using the SHA-256 cryptographic hash algorithm, which includes the public key component contained in private.pem. You will be prompted to enter details about your company:
  • Country Name: ISO 3166-1 alpha-2 country code.
  • State or Province Name: county.
  • Locality Name: town/city.
  • Organization Name: company name.
  • Organizational Unit Name: department (optional).
  • Common Name: (optional).
  • Email Address: (optional).
  • A challenge password: (optional).
  • n optional company name: (optional).

The certificate signing request is output to file public.csr and is the file you would submit to our certificate signing request submission page.

If you are interested, you can look at the contents of public.csr:

openssl req -in public.csr -text

3.2 Example: testing authentication using Curl on Linux

How you configure your system to use the private key and signed certificate to establish an HTTPS connection will be dependent on your particular software platform. Consequently our ability to advise you on how to troubleshoot authentication issues is limited. However, if you use Linux you can test that the private key and signed certificate work together correctly by:

echo '{"branch_reference":"test"}' | curl --key /path/to/private.pem --cert /path/to/certificate.crt --data @- --header "Content-type: application/json; profile=http://realtime-listings.webservices.zpg.co.uk/docs/v2.0/schemas/listing/list.json" https://realtime-listings-api.webservices.zpg.co.uk/sandbox/v2/listing/list

which should receive the following response:

{
  "status": "OK",
  "listings": [],
  "branch_reference": "test"
}

You can test send any of the message examples in a similar way, although you may need to include additional headers (see 4. Messaging).

3.3 Certificate revocation

If at any point you believe that your private key may have been compromised (seen by anyone outside your company) then you should inform ZPG immediately so that we can revoke the associated signed certificate, thus preventing anyone from masquerading as you. Then, repeat the above procedure to generate a new private key and obtain a new signed certificate. You can confirm that your previous signed certificate has been revoked by consulting our Certificate Revocation List.

3.4 Supported TLS versions

The ZPG Real-time Listings Service only accepts secure connections using the TLS 1.2 protocol.

Since security is so important it is worth explaining why this is the case. As previously discussed, security is composed of two parts: identity and privacy. Whilst the data being sent to the Real-time Listings Service is not particularly sensitive (privacy), being assured that the person sending the data is actually who they claim to be (identity) is paramount: no-one should be able to read/change data except its legitimate owner.

(ZPG also expects to launch other services in future. Those services may be dealing with data that is sensitive and should therefore be transmitted in a suitable manner. The Real-time Listings Service is the first of these services, and so we have taken the opportunity to establish best practice standards at the outset, so that partners are familiarised with our security requirements, leading to fewer suprises or problems in future.)

There are a number of industry-standard secure communication protocols - many of which have become obsolete due to flaws in their design :

  • SSL 1.0, 2.0, 3.0 are all insecure. There are known exploits and no-one should be using them any more.
  • TLS 1.0 is insecure. There are known exploits and no-one should be using it any more.
  • TLS 1.1 is believed to be secure but is not the latest version.
  • TLS 1.2 is believed to be secure and is the latest version, with support for additional, stronger cipher algorithms than TLS 1.1.
(A summary of cipher and protocol attacks on TLS has been published by the IETF.)

After reviewing library support for TLS across programming languages and operating systems, we determined that, in the vast majority of cases, if TLS 1.1 was supported then TLS 1.2 was too. We therefore feel comfortable that by restricting access to TLS 1.2 we are following best practice guidelines, should not cause undue disruption, and is in the interest of all users of our services.

4. Messaging

The ZPG Real-time Listings Service uses JSON as its messaging format. JSON has a simple structural syntax; is easy to read; is familiar to software developers; and has excellent library support across many software platforms. We have no plans to support XML.

(Note that in JSON nomenclature an object's attributes are called "properties", which is somewhat unfortunate given the industry we operate in. In order to remove any possibility of ambiguity, this documentation refers to "attributes" instead and the only use of the word "properties" in our schemas is as required by the JSON standard, not as the name of a data attribute.)

For the API method you wish to call, you should construct a JSON message which conforms to the schema definition for that method. We recommend you perform a schema validation check before sending us the message so that you can detect and respond to any validation errors earlier in your messaging process. Our service will always validate your message against the associated schema and reject those that fail.

The JSON message would then be sent to the method's URL endpoint using an HTTP POST. Having received your message the service will respond with a standard HTTP response status code and provide additional information in the response content, formatted in JSON.

4.1 Method endpoints

The ZPG Real-time Listings Service operates in two environments:

  • sandbox, for testing:https://realtime-listings-api.webservices.zpg.co.uk/sandbox/v2/

  • live, for data destined for our websites:https://realtime-listings-api.webservices.zpg.co.uk/live/v2/

Having chosen the correct environment, you then append the name of the method you wish to call. For example:

  • https://realtime-listings-api.webservices.zpg.co.uk/sandbox/v2/branch/update
  • https://realtime-listings-api.webservices.zpg.co.uk/sandbox/v2/listing/update
  • https://realtime-listings-api.webservices.zpg.co.uk/sandbox/v2/listing/delete
  • https://realtime-listings-api.webservices.zpg.co.uk/sandbox/v2/listing/list

You would then use an HTTP POST to send your JSON message to that endpoint, along with the appropriate HTTP headers.

Reminder: your software will need to have been configured so that it can access both the signed certificate and private key, discussed in 3. Security and authentication, when you contact either of these environments. This is so that the secure HTTPS connection can be established.

Please note that the endpoints reference the major component of the API version number you wish to use, whilst the JSON schemas also include minor version components, which must be specified in the Content-Type profile.

(You will initially be given access to the sandbox environment to test your system integration. Data sent here will not affect ZPG's websites. When you are happy that your system integration is complete, you will need to contact us to gain access to the live environment. At that time we will then discuss the best way to perform an initial upload of all your branch and listing data, as well as how to migrate any existing clients who currently use an FTP feed.)

Note that some schema versions may not be available in the live environment; for example, during the development and testing of new versions, or because an old version has been retired. Please refer to our current message schemas to see which environments support the API version documented here.

4.2 HTTP request

The JSON message should be sent to the URL endpoint for the method you wish to use, via a POST.

4.3 HTTP headers

4.3.1 Content-Type

The Content-Type should be set to application/json, along with a profile definition, which is the URL of the specific version of the message schema you are conforming to. e.g.:

Content-Type: application/json; profile=https://realtime-listings.webservices.zpg.co.uk/docs/v2.3/schemas/listing/update.json

4.3.2 ZPG-Listing-ETag (only required for listing/update)

ZPG-Listing-ETag is the mechanism for ensuring that the listings on your system and ours are synchronised. Whenever you send us a listing/update message we will replace the data we have with the new version. At a later date you may wish to check whether the data we have is indeed the same as yours. Rather than sending the entire message back to you - which would then require you to compare all the individual attributes to find differences - we instead ask that you provide us with metadata that will allow your system to quickly determine whether the listing data we have is synchronised with yours. This metadata is sent via the ZPG-Listing-ETag header with each listing/update message, which can later be retrieved via the listing/list method.

The ZPG-Listing-ETag value is a string that you define (up to 255 characters in length) that indicates the overall state of the listing, as represented by the listing/update message. Its value should:

  • remain constant for a given listing/update message
  • change when data within the listing/update message is modified
  • be unlikely to be duplicated in future

i.e. if something changes on your system that would change the listing/update message you would send to us, then the accompanying ZPG-Listing-ETag should change to reflect that.

We recommend using a checksum of the canonicalised listing/update message. Depending on how your system tracks changes to listing data (and how it is sent to us) an auto-incrementing revision_id, or a last-modified date may also be suitable.

The ZPG-Listing-ETag you provide will be returned by the listing/list method. By comparing its value with the one your system would produce now, you can determine whether it is necessary to refresh the listing on our system. Please see 10.3 Periodically check synchronisation for additional information about this process.

5. Methods

The service supports the following methods:

  • branch/update: create or update information about a branch (e.g.: their name; address).
  • listing/update: create or update information about a listing, associated with a branch (e.g.: description; price).
  • listing/delete: delete a listing from a branch's inventory.
  • listing/list: retrieve a branch's inventory list.

Please see the current message schemas and example messages for each method.

5.2 listing/update method

This method allows you to describe a listing. It is used for both creation and update purposes and, in either case, the listing should be described in its entirety.

There are a small number of mandatory attributes:

  1. branch_reference
  2. category
  3. detailed_description
  4. life_cycle_status
  5. listing_reference
  6. location
  7. pricing
  8. property_type

The remaining attributes are all optional according to our schema and specification, however some are strongly advised, where they relate to material information required as published in guidance by the National Trading Standards Estate and Letting Agency Team (NTSELAT). All the additional information you can provide improves our ability to successfully match the listing to a user's search. If you do not have any data for a particular attribute, then do not include it in your message - do not default it. This will make it less likely for the message to fail validation rules which use the attribute and you won't accidentally introduce meaning (and consequence) where there was none before.

There are three attributes which define how we will interpret the listings's data:

  1. location:country_code: "Where is it?" (This can be further reduced to: "Is this a UK or overseas listing?")
  2. category: "Is this listing for a property which is residential (people will live in it) or commercial (a place of business)?"
  3. pricing:transaction_type: "What kind of financial transaction will take place: sale or rent?"

Attributes which are nonsensical when considered in the above context will be ignored (for example: council_tax_band will be ignored if the location:country_code indicates an overseas (non-UK) listing).

Message attributeRequirementsTypeDescriptionExample
accessibilityarray of enumWhether the property includes accessibility features for disabled people. Where a particular option is not appropriate, we advise that the accessibility improvements be described in more detail via feature_list or detailed_description.lateral_living, step_free_access, wheelchair_accessible, wet_room, disabled_features, level_access, ramped_access, lift_access, stair_lift, wide_doorways, level_access_shower, variable_height_kitchen_surfaces
administration_feesstringA description of the estate agent's administration fees."£10 per person."
annual_business_ratesnumberThe annual business rate (UK national non-domestic tax rate) applicable to this property.150.00
areasBest practice (commercial); Mandatory (when providing EITHER pricing:price_per_unit_area OR price_qualifier="non_quoting")areas objectThe internal/external areas of the property.
available_bedroomsintegerThe number of vacant bedrooms being offered in shared accommodation. Note that if supplying this attribute, shared_accommodation must be present and true, although the relationship is asymmetric. See shared_accommodation for more details.2
available_from_dateBest practice (rent)datetimeThe earliest date that a property can be moved into by the new owner/tenant."2010-01-31"; "2010-01-31T12:00:00"
basementbooleanWhether the property has a basement/cellar.true
bathroomsBest practice (residential)integerThe number of bathrooms (or shower rooms) within the property.1; 3
bills_includedarray of enumWhich utility bills are included in the rental price."electricity", "gas", "internet", "satellite_cable_tv", "telephone", "tv_licence", "water",
branch_referenceMandatorystringYour unique identifier for the branch, previously sent via branch/update:branch_reference."1234"; "kd-789d"
broadband_supplyarray of enumAn accurate information as to the nature of the supply (or supplies) of internet broadband to the property"adsl", "cable"
Click for full list
building_safety_issuesarray of stringsAn accurate description of any known building safety issues as well as any planned or required works needed to rectify any identified defect/hazard"Unsafe cladding", "Lack of emergency lighting where required"
burglar_alarmbooleanWhether the property has a burglar alarm installed.true
business_for_salebooleanWhether the business currently operating at the premises is included as part of the sale.true
buyer_incentivesarray of enumThe list of applicable incentive schemes available to the buyer of the property."equity_loan", "help_to_buy", "mi_new_home", "new_buy", "part_buy_part_rent", "shared_equity", "own_new_rate_reducer", "deposit_unlock", "part_exchange"
categoryMandatoryenumWhether the property is commercial or residential."commercial", "residential"
central_heatingenumThe extent to which a property has central heating."full", "partial", "none"
chain_freebooleanWhether the sale of the property is unencumbered by the current owner needing to purchase another property.true
commercial_use_classesarray of stringsThe commercial use classes for which the property is currently approved.["A3", "D2"]
connected_utilitiesarray of enumA list of utilities which are connected to the property."electricity", "fibre_optic", "gas", "satellite_cable_tv", "telephone", "water"
conservatorybooleanWhether the property has a conservatory.true
construction_yearintegerThe year the property was constructed.2010; 1701
construction_materialsno, but cannot be an empty listarray of stringsa list of notable materials involved in the building's construction"brick", "concrete", "thatched roof"
contentBest practicearray of content objectsA list of media content associated with the listing. (These will be displayed in the order provided.)
decorative_conditionenumAn indication of the general decorative state of the property. "excellent", "good", "average", "needs_modernisation"
depositnumberThe tenancy deposit amount. (This should be in the same currency as pricing:currency_code.)500.00
detailed_descriptionMandatoryarray of description objectsThe detailed description of the property. Please see 8. Structuring of detailed descriptions for additional information, including examples of usage.
display_addressstringThe address string to be displayed on the website. Please note that the display of this string is subject to our data validation and presentation rules . It must be formatted with minimum of 1 comma and minimum of 2 addressing entities. For Example: "street_name, locality, town_or_city" OR “street_name, town_or_city”"Barker Road, Sutton Coldfield, Birmingham"
double_glazingbooleanWhether the property has double glazed windows.true
electricity_supplyarray of enumAn accurate description or statement as to the nature of the supply (or supplies) of electricity to the property - may be more than one."mains_supply","private_supply", "solar_pv_panels", "wind_turbine","generator","other"
epc_ratingsepc_ratings objectThe Energy Performance Certificate (EPC) ratings.
feature_listarray of stringA list of important aspects about the property the agent wishes to highlight; "bullet points". Please see 8. Structuring of detailed descriptions for more information about how these are displayed.["Newly carpeted throughout", "Remodelled kitchen"]
fireplacebooleanWhether the property has a room with a fireplace.true
fishing_rightsbooleanWhether ownership of the property also grants the owner the right to fish in waters that cross the property's borders.true
floor_levelsarray of enumWhich floors the property occupies in a multi-storey building. Please see our floor labelling convention.["ground", 1]
Click for more
floorsintegerThe total number of floors that the property occupies.2
furnished_stateBest practice (residential rent)enumThe amount of furnishing provided by the landlord."furnished", "furnished_or_unfurnished", "part_furnished", "unfurnished"
google_street_viewgoogle_street_view objectPosition and orientation for Google Street View.
ground_rentground_rent objectInformation about the ground rent payments and their related rate increases100.00
gymbooleanWhether the property has access to a private or communal gym.true
heating_sourcearray of enumAn accurate description or statement as to the nature of the supply/supplies of heating at the property"biomass_boiler", "electric_mains", "gas_mains"
Click for full list
known_planning_considerationsno, but cannot be an empty stringstringInformation about any known or in progress planning permissions, requirements both at and around the property"article 4 (or related) directions from the local authority apply to this property" "neighbor is building and extension that may impact on privacy or light"
letting_arrangementsBest practice (residential rent, where applicable). Holding depositstringIf a residential rental listing will not confer a residential tenancy which the average consumer would expect to obtain (e.g. an assured shorthold tenancy in England), the alternate letting arrangements should be described here. If a holding deposit is required, this must be clearly stated on the listing. You must comply with any specific requirements in the devolved nations that apply in respect of the holding deposit amount, e.g. Tenant Fees Act 2019 in England and the Renting Homes (Fees etc.) (Wales) Act 2019 in Wales.Non-assured shorthold tenancy "1000"
life_cycle_statusMandatoryenumAn indication as to where the listing is in its life cycle, from initial availability, through offers being made, to its legal conclusion.

For rent: available -> under_offer -> let_agreed -> let.
For sale: available -> under_offer -> sold_subject_to_contract -> sold.
"available", "under_offer", "sold_subject_to_contract", "sold", "let_agreed", "let",
listed_building_gradeenumThe grade assigned to the property should it be listed as a building of special architectural or historic interest."category_a", "category_b", "category_c", "grade_a", "grade_b", "grade_b_plus", "grade_one", "grade_two", "grade_two_star", "locally_listed"
listing_referenceMandatorystringYour unique identifier for the listing. This should be unique across your entire system, not just for its associated branch (i.e. this is the PRIMARY KEY). If your identifiers are based on those submitted by the agent themselves then you may wish to concatenate, with an unambiguous separator, your branch reference and their listing reference to ensure uniqueness (e.g. "branch_id|agent_listing_id")."5678"; "dfhd-kjdf-1"
living_roomsBest practice (residential)integerThe number of living rooms within the property.1
local_authorityBest practice (residential)local_authority objectInformation about charges issuable by a local authority.
locationMandatorylocation objectInformation about the location of the property, such as its address.
loftbooleanWhether the property has a loft/attic.true
new_homebooleanWhether the property is newly built and has had no previous occupants.true
open_daydatetimeThe date of the next open-to-all viewing of the property."2010-01-31"
outbuildingsbooleanWhether the property has additional outbuildings, such as stables or a greenhouse.true
outside_spacearray of enumWhat outside areas are available."balcony", "communal_garden", "private_garden", "roof_terrace", "terrace"
parkingarray of enumWhat parking facilities are available."double_garage", "off_street_parking", "residents_parking", "single_garage", "underground"
Click for full list
pets_allowedbooleanWhether the landlord accepts tenants who have pets.true
porter_securitybooleanWhether the property resides in a complex or building which has an on-site porter/attendant.true
pricingMandatorypricing objectInformation about how the listing is priced.
property_typeMandatoryenum or stringThe broad architectural type of the property. Please note that a particular property_type is only valid within certain contexts."maisonette"
Click for more
rateable_valuenumberThe estimated open market annual rental value of the premises (in GBP).15000.00
rental_termminimum_contract_length object or enumAn indication of the duration of the rental contract."fixed_term", "long_term", "short_term"
repossessionbooleanWhether the sale is for a repossessed property.true
retirementbooleanWhether the property is for retirees-only.true
restrictionsrestrictions objectattributes or information relating to restrictions on or around this property
rights_and_easementsrights_and_easements objectattributes or information relating to easements on or around this property
risksrisks objectAn accurate description or statement as to any known risk of, or actual damage to the property.
sap_ratingintegerThe SAP rating for this property.85
service_chargeservice_charge objectThe service charge applicable to the property.
servicedbooleanWhether the premises are serviced.true
sewerage_supplyarray of enumAn accurate description or statement as to the nature of the sewerage arrangements at the property."mains"
Click for full list
shared_accommodationbooleanWhether the listing is for shared accommodation (i.e. the listing is for a room, or rooms, within an existing house/flatshare). If this attribute is true, we recommend also supplying the available_bedrooms attribute.true
summary_descriptionstringA brief summary of the property. This is displayed in search results and recommend that it is limited to 255 characters."A well decorated house with lots of space with easy access to nearby shops and public transportation."
swimming_poolbooleanWhether the property has a swimming pool.true
tenantedbooleanWhether the property being sold is currently occupied by renting tenants.true
tenant_eligibilitytenant_eligibility objectThe eligibility of potential tenant classes that can apply (e.g. students only).
tennis_courtbooleanWhether the property has a tennis court.true
tenuretenure objectThe tenure of the property.
total_bedroomsBest practice (residential)integerThe total number of bedrooms within the property. When describing shared accommodation, see also available_bedrooms.3
utility_roombooleanWhether the property has a utility room.true
waterfrontbooleanWhether the property is close by to a large body of water such as the sea, a lake or river.true
water_supplyarray of enumAn accurate description or statement as to the nature of the supply of water to the property"mains", "private_well"
Click for more
wood_floorsbooleanWhether the property has rooms with exposed wooden floors.true

5.1 branch/update method (optional)

This method allows you to describe a branch, to which listings are then associated. The address and other contact details allow us to identify the equivalent branch on our system and map your branch_reference to ours.

Note that this method is optional. If you do not use it then the branch information will need to be transferred to ZPG in some other way (typically via an emailed CSV spreadsheet), although this will likely delay the integration of branches with our system.

Message attributeRequirementsTypeDescriptionExample
branch_referenceMandatorystringYour unique identifier for the branch. (We do not generally issue these as it should be the identifier that is native to your system. This makes debugging easier for you and means you do not need to wait for any additional information from us before you can start uploading listing data for a branch.)"1234"; "kd-789d"
branch_nameMandatorystringThe name of the branch. This is usually the name of the company and may also include some location information in order to differentiate it from other branches in the company."Estate Agent Ltd - Shepherd's Bush"
locationMandatorylocation objectInformation about the location of the branch, such as its address.
telephonestringTelephone number."02079460184"; "+1 246-123-4567"
emailstringEmail address."[email protected]"
websitestringThe URI-encoded URL for the branch's website, or that of its parent company if it doesn't have one of its own."http://www.estateagentltd.co.uk"

5.3 listing/delete method

This method allows you to remove a listing from a branch's inventory list.

Message attributeRequirementsTypeDescriptionExample
listing_referenceMandatorystringYour unique identifier for the listing that you wish to remove, previously sent via listing/update:listing_reference."1234"; "kd-789d"
deletion_reasonenumWhy the listing is being deleted."withdrawn", "offer_accepted", "exchanged", "completed", "let"

5.4 listing/list method

Because of the incremental nature of the service it is possible for the data that ZPG has to drift relative to yours (because of network problems or uncaught errors, for example). It is recommended that you periodically check the synchronisation of data between our system and yours. The listing/list method allows you retrieve a summary of the listing inventory for a branch and their state.

Message attributeRequirementsTypeDescriptionExample
branch_referenceMandatorystringYour unique identifier for the branch, previously sent via listing/update:branch_reference."1234"; "kd-789d"

The response will include the listing inventory for the branch as an array of:

Response attributeTypeDescriptionExample
listing_referencestringYour unique identifier for the listing, previously sent via listing/update:listing_reference."1234"; "kd-789d"
listing_etagstringThis is the string that you specified in the ZPG-Listing-ETag HTTP header when you last called listing/update, referring to listing_reference. If the value is not the same as the one you expect then there is a synchronisation issue and you should call listing/update again to refresh the data that ZPG has."18ab1f2e4c8ed62882fa57380c9b7b026413a663"
urlstringA link to the listing's detail page. (When using the sandbox environment this links to a preview page; when using the live environment it is a redirect to the detail page on Zoopla's website.)

Please see 10. Workflow overview for additional information about how to use this method.

6. Objects

If you include an attribute in your method call that uses an object to represent it, a valid object must be supplied. When discussing objects, a constituent attribute described as being mandatory is with reference to how to produce a valid object; it does not imply that the object, nor the attribute that uses that object, is mandatory when calling a particular method. Please refer to the method itself to see whether a particular attribute is mandatory.

area object

This describes a single area. It is a constituent of a number of other objects. This should not be confused with the areas object.

Object attributeRequirementsTypeDescriptionExample
valueMandatorynumberThe area value.54.5
unitsMandatoryenumThe units of measurement used.sq_feet, sq_yards, sq_metres, acres, hectares

areas object

The internal/external areas of the property.

Object attributeRequirementsTypeDescriptionExample
externalmin_max_area objectThe external area of the property.
internalMandatory (when specifying pricing:price_per_unit_area)min_max_area objectThe internal area of the property.

content object

A content object specifies a single piece of media content associated with the listing, such as an image or brochure. The listing/update:content attribute is an array of these content objects, which will be displayed in the order provided. Please see 9. Retrieval of media content for more information about how the content will be retrieved from the specified URLs.

Object attributeRequirementsTypeDescriptionExample
urlMandatorystringThe URI-encoded URL for the media content to download."http://www.estateagentltd.co.uk/properties/images/1234.jpg"
typeMandatoryenumThe content type."audio_tour,brochure,document,epc_graph,epc_report,floor_plan,home_pack,image,site_plan,virtual_tour
captionstringA short description of the content. This will be displayed alongside the content or, where appropriate, used as the hyperlink text."The entrance hall."

coordinates object

This object describes the geographic location of a point on the Earth's surface using the latitude/longitude system. We recommend you store latitude/longitude with a precision of at least 5 decimal places, which allows for locating a point to within approximately 1 metre.

Object attributeRequirementsTypeDescriptionExample
latitudeMandatorynumberThe latitude, measured in degrees, of the property.-90.000000; 54.123456; 90.000000
longitudeMandatorynumberThe longitude, measured in degrees, of the property.-180.000000; 119.265984; 180.000000

description object

The description is expressed as an array of description objects, each of which represent a paragraph or section. For additional information about how to use this object, including examples, please see section 8. Structuring of detailed descriptions.

Object attributeRequirementsTypeDescriptionExample
headingSee belowstringThe title of the section."Kitchen"
dimensionsdimensions object or stringThe dimensions of the room, when the section is describing a individual room. (The dimensions object is the preferred and recommended representation because the string variant is subject to our data validation and presentation rules and so may not be displayed.)
textSee belowstringThe main text for this section.

Requirements: you must provide at least one of heading or text per object, whilst dimensions is optional (but contingent on the presence of a heading).

dimensions object

Information about the dimensions of a room.

Object attributeRequirementsTypeDescriptionExample
lengthMandatorynumberThe length of the room.12
widthMandatorynumberThe width of the room.10
unitsMandatoryenumThe units of measurement used.feet,metres

This will be displayed as "length x width" with appropriate unit markers. Traditionally, length is greater than width, but this is not required.

epc_ratings object

The Energy Performance Certificate (EPC) provides information about the energy efficiency and environmental impact of the property.

Object attributeRequirementsTypeDescriptionExample
eer_current_ratingintegerThe current Energy Efficiency Rating (EER).80
eer_potential_ratingintegerThe potential Energy Efficiency Rating (EER).95
eir_current_ratingintegerThe current Environmental Impact (CO2) Rating (EIR).50
eir_potential_ratingintegerThe potential Environmental Impact (CO2) Rating (EIR).100

risks object

Disaster Risks - accurate information as to any known risk of, or actual damage to the property, if a risk is present then it's attribute cannot be empty or null. at least 1 risk mush be provided and cannot be null/empty

Object attributeRequirementsTypeDescriptionExample
flooding_risksflooding_risks objectdetails regarding any risks related to flooding which affect the property
coastal_erosion_riskbooleanare there any coastal erosion risks which affect the propertyfalse
mining_risksmining_risks objectdetails regarding any risks related to mining activity which affect the property

flooding_risks object

Flooding Risk - provides users with relevent information around risk of flooding at the property. if configured cannot be empty

Object attributeRequirementsTypeDescriptionExample
flooded_within_last_5_yearsbooleanHas the property has experienced a flood event within the past 5 yearsfalse
sources_of_floodingMandatory, but only if flooded_within_last_5_years is truearray of enumlist of sources of any exposure to flooding[ "river", "lake" ]
Click for full list
flood_defenses_presentMandatory, but only if flooded_within_last_5_years is truebooleandeclare whether there are any flood defences at the propertytrue

mining_risks object

Mining Risk - prvoides infomation where a property is known to be on the coalfield or directly impacted by the effect of other mining activity. if configured cannot be empty

Object attributeRequirementsTypeDescriptionExample
coalfieldsbooleanIs the property on a coalfieldfalse
other_mining_activities booleanare there any other mining related activities which may affect this propertytrue

google_street_view object

Google Street View provides users with the ability to virtually explore outdoor areas. This is becoming increasingly valuable to users, who are able to, for example: plan routes to bus stops; see which services are provided by local shops.

Object attributeRequirementsTypeDescriptionExample
coordinatesMandatorycoordinates objectThe coordinates of the point where StreetView should be initially located.
headingMandatorynumberThe angle of rotation to the right of the view, measured in degrees, relative to north. Also known as compass heading, or bearing.0 (north); 74.5; 90 (east); 360 (north)
pitchMandatorynumberThe angle of rotation up/down of the view, measured in degrees, relative to the horizon.-90 (straight down); 5.4; 90 (straight up)

ground_rent object

The annual ground rent both review period or date_of_next_review info are optional
Object attributeRequirementsTypeDescriptionExample
amountMandatorynumberThe annual amount payable. This value will be considered to be in the same currency as pricing:currency_code.1100

The following fields are optional

Object attributeRequirementsTypeDescriptionExample
review_periodnumberThe number of years between reviews of the ground rent amount.2
date_of_next_reviewstringThe date that the ground rent is next due to be reviewed, particularly for when review_period is greater than 1 year. Note that this is a date-like string whose validation is not as restrictive as the datetime used for other attributes. It may be any of the following formats: YYYY-MM-DD; YYYY-MM; YYYY."2026-01-31"; "2026-01"; "2026"

council_tax_band object

council_tax_band represents one of a set of submittable values. Either the band itself as a simple string, or one of two objects representing that the property is exempt, or that the band is unknown at this point in time. The latter is most likely used for newbuild properties where bands have not yet been decided. Either exemption or unknown status must also provide a reason as part of the submission.

Please note that Council Tax (UK) is considered material information and must be included in the listing. In very limited circumstances, listings may be exempt from council tax. If that is the case, a reason for the exemption must be provided within the listing description as per below.

Either a simple string such as: "A" or an object containing one of the following two keys: "B", "C", "D", "E", "F", "G", "H", "I"

Object attributeRequirementsTypeDescriptionExample
exemptmandatory reason to be provided if declaredstringThe property itself is exempt from the payment of council tax for the given reason."Student hall of residence"
not_yet_knownmandatory reason to be provided if declaredstringThe band is unknown at this point in time for the reason provided."A band has not been assigned to this new subdivision yet."

domestic_rates object

domestic_rates represents one of a set of submittable values. Either a number value Northern Ireland domestic rates annual payable value. Either the rate itself as a number (taken as per annum), or one of two objects representing that the property is exempt from paying rates, or that the rate is unknown at this point in time. Either exemption or unknown status must also provide a reason as part of the submission.

Either a simple non-zero number such as: "100" or an object containing one of the following two keys:

Please note that Domestic Rates (NI) is considered material information and must be included in the listing. In very limited circumstances, listings may be exempt from council tax. If that is the case, a reason for the exemption must be provided within the listing description.

Object attributeRequirementsTypeDescriptionExample
exemptmandatory reason to be provided if declaredstringThis should only be used where the property itself is exempt from the payment of domestic rates for the explicit legalreasons."Student hall of residence"
not_yet_knownmandatory reason to be provided if declaredstringThe domestic rates are non yet known at this point in time for the reason provided."rates have not been assigned to this new subdivision yet."

local_authority object

Charges issuable by a local authority. One of the following keys must be specified if the local_authority key is submitted.

Object attributeRequirementsTypeDescriptionExample
council_tax_bandcouncil_tax_band objectBritish council tax details
domestic_ratesdomestic_rates objectNorthern Ireland domestic rates annual payable details.730

location object

Providing an accurate address and location for the property is incredibly important because a large number of existing and future features on our websites depend on it. For example: which council is responsible for the maintaining and taxing the local area; or average travel times between the property and other locations of interest to the user.

Object attributeRequirementsTypeDescriptionExample
property_number_or_nameBest practice; mandatory when not providing street_name.stringThe public designation of the property.15; "14A"; "Flat B, 41"; "The Wildings"
street_nameBest practice; mandatory when not providing property_number_or_name.stringThe name of the road on which the property is principally adjacent."Barker Road"; "Chestnut Street"
localitystringThe familiar name of the area as it is referred to by local residents. This is usually a traditional, historic name and may refer to an aspect of the area which has ceased to exist."Sutton Coldfield"; "North Beach"
town_or_cityMandatorystringThe nearest large urban area to the property. This is usually included in the property's postal address and sometimes referred to as "post town".

Note that this does not imply that the property resides within the boundaries of this urban area (for example, it might be in an outlying village - which would be referenced via the locality).
"Birmingham"; "San Francisco"
countystringThe largest territorial area division within the country which the property resides in. (Synonymous with e.g.: province; principality.)"West Midlands"; "California"
postal_codeMandatory (UK)stringThe postal area code issued by the primary postal service in the country. For example, for the UK, this would be Royal Mail's postcode; for the US, the United States Postal Service's ZIP code."B19 4JY"; "94112"
country_codeMandatorystringThe ISO 3166-2(preferred) orISO 3166-1 alpha-2country code.
Listings for properties in Guernsey, Jersey and the Isle of Man should use the 'GB' country code.
"GB-BIR"; "US"
coordinatesBest practicecoordinates objectThe geographic location of the property.
paf_addresspaf_address objectRoyal Mail's address reference.
paf_udprnstringRoyal Mail's Unique Delivery Point Reference Number (UDPRN)."00001234"
uprnstringThe Unique Property Reference Number (UPRN) is a unique identifier assigned to each addressable property in the United Kingdom (UPRN). is a unique number up to 12 characters in length"1234", "00001234

Note that there is a hierarchical order to the address attributes, so in order of increasing size:

  • property_number_or_name
  • street_name
  • locality
  • town_or_city
  • county
  • country_code

If your software does not currently support the separation of the property_number_or_name from street_name (i.e. they are stored as a single string value; for example: "29 Acacia Road"), then please supply that string via street_name.

minimum_contract_length object

The rental_term attribute can be specified with a minimum_contract_length object or, if the contract length is not currently known, by an enum that roughly indicates its likely duration (e.g. "short_term").

Object attributeRequirementsTypeDescriptionExample
minimum_lengthMandatorynumberThe minimum duration of the contract.6
unitsMandatoryenumThe units of measurement used.days,weeks,months,years

min_max_area object

The min_max_area object defines an area range. Where only one is specified, we will regard them both as having the same value - i.e. a fixed area.

Object attributeRequirementsTypeDescriptionExample
minimumarea objectThe minimum area.
maximumarea objectThe maximum area.

restriction object

supporting information pertaining to any known statutory/contractual restrictions or obligations that relate, restrict or require the use of land, restrictions on resale and/or require it to us used, maintained or preserved is a certain manner. If provided cannot be empty or null

Object attributeRequirementsTypeDescriptionExample
conservation_areabooleando any restrictions apply due to the property being in a conservation area
lease_restrictionsbooleanare there any restrictions in the lease (provide details in the listing description if yes)true
listed_buildingbooleando any restrictions apply due to the property having a listed building statustrue
permitted_developmentbooleanare there any restrictions on what kind of property development is permittedfalse
real_burdensbooleanApplies in Scotland only. Does a real burden apply to this property. This is normally an obligation affecting land or buildings.false
holiday_home_rentalbooleanare there any holiday home rental restrictions on this propertyfalse
restrictive_covenantbooleanare there any restrictive covenants which apply to this propertyfalse
business_from_propertybooleanare there any restrictions on running a business from this propertyfalse
property_sublettingbooleanare there any terms or restrictions regarding subletting this property
tree_preservation_orderbooleanare there any tree preservation orders related to this propertyfalse
otherbooleanare there any other or additional restrictions not mentioned above. Please put details in the listing descriptionfalse

rights_and_easements object

supporting information pertaining to any known (or in progress) easements or rights that relate to the use of land, resale and/or require it to us used, maintained or preserved is a certain manner. If provided cannot be empty or null ained or preserved is a certain manner. If provided cannot be empty or null

Object attributeRequirementsTypeDescriptionExample
right_of_way_publicbooleanare there any public rights of way (footpath, byway etc...) that relate to this propertytrue
right_of_way_privatebooleanare there any private rights of way (footpath, byway etc...) that relate to this propertytrue
registered_easements_hmlrbooleanare there any registered (or in the process of registering) easements/rights with the hmlr (land registry)true
servitudesbooleanNormally only applies in Scotland. Are there any servitudes that affect this propertytrue
shared_drivewaybooleanis there a driveway shared with a different propertytrue
loft_accessbooleandoes the property have to grant loft access to occupants of properties below, or have the right to access the loft via a property above (e.g. to maintain a water tank)true
drain_accessbooleandoes the property have to grant access to the land for the maintenance of drainstrue
otherbooleanare there any other easements or rights associated with this property not otherwise given above. Please put details in the listing descriptiontrue

paf_address object

Royal Mail's addressing scheme is known as Postcode Address File (PAF). Many third-party systems use this to facilitate the selection of an address from an initial postcode. Per Royal Mail's specification: "Each address on PAF® has an eight-digit number associated with it - the Address Key. This number in conjunction with the Organisation Key and Postcode Type identifies the address."
Object attributeRequirementsTypeDescriptionExample
address_keyMandatorystringThe 8-digit Address Key."02341509"
organisation_keyMandatorystringThe 8-digit Organisation Key."00000000"; "00001150"
postcode_typeMandatoryenumThe Postcode Type."L"; "S"

Note that Royal Mail's UDPRN (see location:paf_udprn) is generally preferred to paf_address because it is more stable with respect to changes in property utilisation (e.g. commercial becoming residential).

price_per_unit_area object

This object describes a price which is provided as a function of floor area.

Object attributeRequirementsTypeDescriptionExample
priceMandatorynumberThe per unit area price.100.00
unitsMandatoryenumThe units of measurement used.sq_feet, sq_yards, sq_metres, acres, hectares

pricing object

The pricing object's structure is determined by whether its component attribute transaction_type indicates that the listing is for sale or rent. Please note that we do not currently support multiple pricing, nor multiple transaction_types, for a single listing. If you do have multiple pricing models, perhaps due to a range of incentive schemes being available, then you should supply the non-subsidised price in the pricing object and indicate available incentive plans via listing/update:buyer_incentives.

Object attributeRequirementsTypeDescriptionExample
transaction_typeMandatoryenumThe type of financial transaction for this listing.rent,sale
currency_codeMandatorystringThe ISO 4217 currency code for the stated price. Other monetary attributes (e.g. deposit) also use this as their currency."GBP"; "JPY"
priceMandatory (residential)numberThe non-subsidised price of the listing.

Note that the price should be quoted in its natural currency (i.e. the currency the vendor/landlord has specified), which is usually the official currency of the country that the property resides in. To be clear: this value should not be the result of a currency conversion.
100000.00; 250
price_per_unit_areaBest practice (commercial)price_per_unit_area objectThe price quoted as a function of floor area. This is generally only used with commercial properties.
rent_frequencyMandatory (rent)enumThe frequency with which rent is required to be paid.per_person_per_week,per_week,per_month,per_quarter,per_year
price_qualifierenumAdditional information about the price which requires emphasis, usually for legal reasons.coming_soon,fixed_price,from,guide_price,non_quoting,offers_in_the_region_of,offers_over,sale_by_tender
auctionbooleanWhether the sale will be transacted by an auction.true

Because pricing is so important there are a number of schema-enforced dependencies for some of the pricing object's attributes. In particular:

  • When transaction_type = "rent", rent_frequency must be specified.

  • When providing a price_per_unit_area you must also provide an areas attribute with an internal area.

  • price_qualifier = "non_quoting" is only valid for location:country_code = "gb" and category = "commercial".

  • When stating price_qualifier = "non_quoting" then you must not provide pricing/price nor pricing/price_per_unit_area.

    • You must however, still provide an areas object that specifies the minimum internal area.
    • Note that you do not have to supply both price and price_per_unit_area, although that is allowed. Do not calculate one price attribute from the other.
    • price_qualifier = "coming_soon" is only valid for new homes listings, for all other cases it will not be parsed

service_charge object

This object describes any ongoing service charges which are applicable. and charge amount must be suplied and you may optionally also supplement per_unit_area_units or frequency (or both if relevant)

Object attributeRequirementsTypeDescriptionExample
chargeMandatory (cannot be 0)numberThe service charge amount.100
per_unit_area_unitsenumWhen the charge is a function of unit area (usually for commercial properties), the units of area measurement.sq_feet, sq_yards, sq_metres, acres, hectares
frequencyenumWhen the charge is a fixed amount (usually for residential properties), the frequency with which the service charge is required to be paid.per_person_per_week,per_week,per_month,per_quarter,per_year

shared_ownership object

Use this object to indicate whether this leasehold purchase is shared ownership. If none of the sub-values are known then submit the key with an empty object, otherwise include the keys/values as appropriate.

Object attributeRequirementsTypeDescriptionExample
percentagenumberNormally a figure from 25-75 (inclusive) but can be as low as 1 or as high as 99. Represents the proportion of ownership the purchaser will be taking on initially.30
detailsstringAny further details about shared ownershipInitial ownership % can be increased after x years

The following fields are not mandatory, but if one is included then the other must be as well.

Object attributeRequirementsTypeDescriptionExample
rentNon-mandatory, but if given then rent_frequency must also be provided.numberThe amount of rent payable per rent_frequency period.300
rent_frequencyNon-mandatory, but if given then rent must also be provided.enum"per_day", "per_week", "per_month", "per_quarter", "per_year"

tenure object

The tenure of the property. This object describes both the type of tenure and any related information where applicable.
All tenure objects have an associated required type field, the other keys/values of the object are specific to the submitted type.
Object attributeRequirementsTypeDescriptionExample
typeenumFeudal should not be used as a tenure type. Please contact customer support if requiring feudal as a listing tenure"commonhold", "feudal", "freehold", "leasehold", "share_of_freehold", "non_traditional"
For the following types there are further fields available or required:

commonhold

Commonhold properties are an alternative to leasehold for properties sharing communal areas or services. Instead of the shared segment being freehold to a third party in commonhold you own your property as a freehold indefinitely with the shared areas owned by the commonhold association.
Object attributeRequirementsTypeDescriptionExample
detailsstringAdditional information specific to the commonhold arrangement (parts included in the arrangement outside of the freehold unit itself, commonhold association management structure, basic description of articles of association, etc.)

leasehold

For leasehold properties, information about the leasehold expiry and any shared ownership details should be provided if applicable.

For properties where a share of ownership is being purchased, the shared_ownership object should be provided, as below:

Object attributeRequirementsTypeDescriptionExample
shared_ownershipshared_ownership objectInformation about the share of ownership (if applicable)

The expiry of leasehold tenure can be expressed as the actual expiry date or the number of years remaining on the lease.

Object attributeRequirementsTypeDescriptionExample
expiry_dateMandatorystringThe date when the lease expires. Note that this is a date-like string whose validation is not as restrictive as the datetime used for other attributes. It may be any of the following formats: YYYY-MM-DD; YYYY-MM; YYYY."2014-01-31"; "2014-01"; "2014"

or

Object attributeRequirementsTypeDescriptionExample
years_remainingMandatoryintegerThe number of years remaining on the lease.99

share_of_freehold

For some share_of_freehold properties there may be an associated lease component. In such cases information about the lease expiry can be provided to supplement this tenure

The expiry of any lease component of a share_of_freehold tenure (if relevant) can optionally be expressed as either the actual expiry date or the number of years remaining on the lease. if provided only one of the following is permitted and not both at once

Object attributeRequirementsTypeDescriptionExample
expiry_dateoptional should not be provided if years_remaining is givenstringThe date when the lease component of the share_of_freehold expires. Note that this is a date-like string whose validation is not as restrictive as the datetime used for other attributes. It may be any of the following formats: YYYY-MM-DD; YYYY-MM; YYYY."2014-01-31"; "2014-01"; "2014"

or

Object attributeRequirementsTypeDescriptionExample
years_remainingoptional but should not be provided if expiry_date is givenintegerThe number of years remaining on the lease comopnent of the share_of_freehold.99

tenant_eligibility object

This allows you to specify the eligibility of various classifications of applicant for a tenancy. Note that you do not have to specify eligibility for all classifications.

Note: as of April 2019, the dss attribute in this object is ignored. Please see"Zoopla to end 'No DSS' wording in rental adverts" for more details.

Object attributeRequirementsTypeDescriptionExample
dssenumThe eligibility for applicants who are receiving Housing Benefit.accepted,excluded,only
studentsenumThe eligibility for applicants who are students.accepted,excluded,only

7. Responses

After processing your message we will send you a response that includes a standard HTTP status code and a JSON object in the content body that provides more detailed feedback.

7.1 Success

A response with a 200 OK HTTP status code indicates a successfully processed message. For convenience the JSON response object includes the primary identifiers provided in the original message. The methods respond as follows:

7.1.1 branch/update

{
  "status": "OK",
  "branch_reference": "<message's branch_reference>",
  "new_branch": true
}

If this was the first time that we have received a message about branch_reference then new_branch will be true, otherwise false.

7.1.2 listing/update

{
  "status": "OK",
  "listing_reference": "<message's listing_reference>",
  "listing_etag": "<message's ZPG-Listing-ETag header>",
  "url": "<URL for this listing>",
  "new_listing": true
}

If this was the first time that we have received a message about listing_reference then new_listing will be true, otherwise false.

In both sandbox and live environments the response contains a url attribute:

  • in the sandbox environment, this is a link to a web page where you can preview how the listing will be displayed on our websites.

  • in the live environment, this is a link which, once your listing has been processed and published, will redirect to the detail page of this listing on Zoopla.

7.1.3 listing/delete

A listing/delete message will return a 200 OK if the listing_reference is no longer active on our system. If your message deleted listing_reference then you will receive:

{
  "status": "OK",
  "listing_reference": "<message's listing_reference>"
}

whereas if the listing_reference was already inactive, or previously unknown to us, then you will receive:

{
  "status": "UNKNOWN",
  "listing_reference": "<message's listing_reference>"
}

The effect is the same but you may wish to investigate these cases since this may be indicative of a synchronisation issue.

7.1.4 listing/list

listing/list allows you to retrieve listing inventory information for a branch:

{
  "status": "OK",
  "branch_reference": "<message's branch_reference>",
  "listings": [
    {
      "listing_reference": "<listing_reference 1>",
      "listing_etag": "<ZPG-Listing-ETag 1>",
      "url": "<URL for this listing>"
    },
    {
      "listing_reference": "<listing_reference 2>",
      "listing_etag": "<ZPG-Listing-ETag 2>",
      "url": "<URL for this listing>"
    }
  ]
}

The listing_etag attribute contains the value of the ZPG-Listing-ETag you provided with your last listing/update message relating to listing_reference. Using this value you can check the synchronicity of the listing's data between ZPG's system and yours.

The url attribute behaves in exactly the same way as that described for the listing/update response.

If branch_reference has no listings then it will not be treated as an error and an empty list will be returned:

{
          "status": "OK",
          "branch_reference": "<message's branch_reference>",
          "listings": []
}

7.2 Errors

If there was a problem with the message then the response will include an HTTP status code in the 4xx range. The accompanying JSON response object will include more detailed information about the error to help you diagnose and fix it.

An error response will always include the following attributes:

Response attributeTypeDescription
error_namestringA unique string identifier for the error.
error_advicestringA description of the error and some advice as to how to fix it.

If there are problems parsing your message as JSON, there will also be:

Response attributeTypeDescription
request_contentstringThe content body of your request (which should have been a JSON object).
json_validationstringThe reason(s) why request_content could not be parsed as a JSON object.

If there are problems determining which schema or method should be used, there will also be:

Response attributeTypeDescription
methodstringThe method your message was sent to.
profilestringThe JSON schema you declared your message would conform to.

If there are problems validating the message against its associated JSON schema, there will also be:

Response attributeTypeDescription
errorsarray of JSON objectsThe errors that were generated when validating your message against the schema.
schemastringThe JSON schema your message was validated against.
statusstringThis will be set to "FAILURE". (See also the status attribute returned by successful responses.)

For example, if you were to send a correctly formatted message to the incorrect method endpoint you would receive:

{
  "error_name": "schema_method_mismatch",
  "error_advice": "The schema referenced in the Content-Type profile does not match the method endpoint where the message was sent. Please check that you are using the correct message schema and that the message is being sent to the correct endpoint.",
  "method": "/sandbox/undefined/branch/update",
  "profile": "http://realtime-listings.webservices.zpg.co.uk/docs/v2.3/schemas/listing/update.json"
}

7.2.1 Referencing of JSON attributes

The most common errors relate to problems with the JSON message itself (for example, invalid data or a missing mandatory attribute). The JSON validator will reference attributes of interest via a hierarchical path, with "#/" denoting the root level of the object:

#/category{
  "category": "residential"
}
#/location/coordinates/latitude{
  "location": {
    "coordinates": {
      "latitude": 120.659815,
      "longitude": -7.846114
    }
  }
}

Note that, in JSON, array elements are referenced using a zero-based index:

#/an_array/1{
  "an_array": [
    "element 0 => #/an_array/0",
    "element 1 => #/an_array/1",
    "..."
  ]
}

7.2.2 JSON schema validation

The JSON validator's error messages should be self-explanatory when describing problems about an individual attribute and its dependencies.

The JSON validator will attempt to validate your message against the schema by interpreting the listing's data in all possible contexts. If it is unable to find a successful match then it will return all the errors it encountered. Recall that there are three principal attributes that are used to interpret the listing's data (#/location/country_code, #/category, #/pricing/transaction_type) so, naturally, there are some schema-enforced rules related to these attributes. If one of these attributes has a problem then it may trigger multiple errors (each produced by considering the message in a different context), which may make it appear as though there are more problems than there actually are, so we recommend you investigate errors for these attributes first. For example, consider the following pricing object:

{
  "pricing": {
    "transaction_type": "rent",
    "currency_code": "GBP",
    "price": 10000
  }
}....

This produces two errors:

{
  "error_name": "json_does_not_validate",
  "error_advice": "The JSON message does not conform with the schema. Please check the 'errors' array for details.",
  "errors": [
    {
      "message": "'rent_frequency' is a required property",
      "path": "#/pricing"
    },
    {
      "message": "'rent' is not one of ['sale']",
      "path": "#/pricing/transaction_type"
    }
  ],
  "schema": "http://realtime-listings.webservices.zpg.co.uk/docs/v2.3/schemas/listing/update.json",
  "status": "FAILURE"
}

The validator has attempted to interpret the message as a rent listing and discovered that the required rent_frequency attribute is missing. Having failed to validate as a rent listing, the validator then attempted to interpret the message as a sale listing instead. That failed too because the transaction_type is incorrect for a sale listing. In order to fix this error the sender would have to decide what the correct transaction_type was and then either change the transaction_type or provide the rent_frequency .

8. Structuring of detailed descriptions

Providing a comprehensive description of the listing is very important: it is the estate agent's primary opportunity to convince the user that this property is exactly what they are looking for. Our detail page is divided into the following sections:

The description should provide an overview of the property and, if relevant, its constituent rooms. Presentation is also very important, from both structural and visual perspectives, as it allows the user to quickly find information about the property that they are specifically interested in. Unfortunately there is no standard as to how to structure descriptions, so our detailed_description attribute has been designed to be as flexible as possible, whilst providing a framework to encourage good practice.

The detailed_description is an array of description objects, each of which can have the following attributes:

  • heading
  • dimensions
  • text

These attributes populate a template with this structure:

heading (dimensions)
text

You must provide at least one of heading or text per object, whilst dimensions is optional (but contingent on the presence of a heading). The heading will be styled appropriately. By specifying a sequence of these objects, each using various combinations of header, dimensions and text, a wide variety of complex layouts can be achieved. A number of common scenarios are discussed below.

The text can include HTML. However, we only support a limited number of HTML tags in order to prevent unforeseen and undesirable interactions with our own HTML layout and styling. We currently only support:

  • <br> (line break)
  • <p> (paragraph)
  • <strong> or <b> (highlighted)
  • <em> or <i> (emphasised)
  • <u> (underlined)
  • <ul> and <li> (unordered list)

Note that any external links and contact details will be removed from the description text.

If your system only stores a single block of descriptive text then you would use one object with a single text attribute:

{
  "detailed_description": [
    {
      "text": "This is a single block of text."
    }
  ]
}
This is a single block of text.

Because there is no information about the structure of the text when provided this way, the author may need to embed HTML tags in order to achieve the layout they desire.

Example: sections

If your descriptions are split into sections then you would use multiple objects, one per section, specifying a heading for each:

{
  "detailed_description": [
    {
      "heading": "Section one",
      "text": "The text for section one."
    },
    {
      "heading": "Section two",
      "text": "The text for section two."
    }
  ]
}
Section one
The text for section one.
Section two
The text for section two.

Note that sections do not necessarily have to have a heading, in which case they will appear as paragraphs. A common use-case is to have an un-headed introductory paragraph, followed by headed sections:

{
  "detailed_description": [
    {
      "text": "Introductory overview of the property."
    },
    {
      "heading": "Section one",
      "text": "The text for section one."
    },
    {
      "heading": "Section two",
      "text": "The text for section two."
    }
  ]
}
Introductory overview of the property.
Section one
The text for section one.
Section two
The text for section two.

Example: sections for individual rooms

The most common (residential) use-case is an overview paragraph followed by sections that describe individual rooms. This is exactly the same as the sectioned description discussed previously but with the addition of the dimensions attribute:

{
  "detailed_description": [
    {
      "text": "Introductory overview of the property."
    },
    {
      "heading": "Room one",
      "dimensions": {
        "length": 12.2,
        "width": 10,
        "units": "metres"
      },
      "text": "Information about room one."
    },
    {
      "heading": "Room two",
      "dimensions": "10m x 8.2m",
      "text": "Information about room two."
    }
  ]
}
Introductory overview of the property.
Room one (12.2m x 10.0m)
Information about room one.
Room two (10m x 8.2m)
Information about room two.

If you do not have a description for a room (although that's not recommended) then you can just specify a heading in order to maintain consistency of presentation:

{
  "detailed_description": [
    {
      "text": "Introductory overview of the property."
    },
    {
      "heading": "Master bedroom",
      "dimensions": {
        "length": 20.1,
        "width": 15.2,
        "units": "feet"
      },
      "text": "A large bedroom with lots of storage space and an outlook over the valley."
    },
    {
      "heading": "Bedroom",
      "dimensions": "10' x 8'"
    },
    {
      "heading": "Bedroom",
      "dimensions": "9' x 9'"
    },
    {
      "heading": "Kitchen",
      "text": "The kitchen was recently refitted."
    }
  ]
}
Introductory overview of the property.
Master bedroom (20.1' x 15.2')
A large bedroom with lots of storage space and an outlook over the valley.
Bedroom (10' x 8')
Bedroom (9' x 9')
Kitchen
The kitchen was recently refitted.

Note that in the above example the dimensions of the kitchen are missing. This is permissible but not good practice when discussing individual rooms.

9. Retrieval of media content

A listing's content is not transferred to ZPG via the Real-time Listings Service directly. Instead the listing/update method includes a content attribute for you to specify a list of URLs from where that content can be obtained. It is likely that you already have a web server hosting this content, so this mechanism allows you to leverage your existing infrastructure to make the transfer of these assets more efficient. We support web servers using either HTTP or HTTPS.

Upon receipt of a listing/update message, we will request all the URLs specified, with appropriate HTTP headers to make the request conditional. So the first time a particular URL is mentioned we will download that content. For subsequent listing/update messages which mention that URL, we will modify our request to include the first of the following HTTP headers that we have an accompanying value for:

  • If-None-Match with the value from the HTTP ETag response header your web server returned when we previously requested the URL.
  • If-Modified-Since with the date from the HTTP Last-Modified response header your web server returned when we previously requested the URL.

In this way we will only download that content again when it changes. We recommend that your system support ETags in addition to last-modified dates. Whilst the generation of the ETag is not defined by the HTTP specification, many systems use a hashing algorithm (e.g.: MD5; SHA-1) since they are only generated from the binary data itself (so file system changes do not affect it), and the likelihood of two files producing the same hash is very small. This provides a high level of confidence that when the hash changes, the content is different; and vice versa.

Your web server probably behaves correctly when sent these headers already, particularly if you are using a commercial content delivery network. However, we nevertheless recommend you check its behaviour to be sure - especially since web browsers use the same mechanism to maintain their local data cache, so a misconfiguration could be enhancing your network traffic significantly.

Downloading your content

Our download process will identify itself as:

User-Agent: Zoopla Property Group automated download

If your content will be hosted on a private web server and therefore wish to use firewall rules to restrict access, please whitelist the following IPs:

  • '54.229.75.214'
  • '54.171.126.99'
  • '54.171.72.173'
  • '54.229.57.122'
  • '54.77.228.44'
  • '31.221.120.234'
  • '52.18.106.77'
  • '52.18.124.138'
  • '52.16.166.50'

MIME types

We only support web-safe formats for content. Acceptable MIME types are:

  • application/pdf
  • image/gif
  • image/jpeg
  • image/png

Images

Images can strongly influence a user's impression of a listing so it is important to provide good quality images which are representative of the property.

  • Please make available the original image (or the largest downscaled variant of the original if that is not possible). When resizing images for use on our websites and mobile apps, we only downscale because upscaling results in inferior quality images. Be careful not to accidentally submit URLs for image thumbnails.
  • The first image should ideally be of the exterior of the property.
  • We recommend including images for features and rooms which are highlighted in the description (e.g. a conservatory, or a recently remodelled kitchen).
  • Do not send agent logos or placeholder images. These will removed from our websites.
  • We recommend images have a size of at least 1280x960. Please note that we provide users access to original images and they should display larger than the default view on our listing detail page. Large images are particularly important for mobile devices when viewed full screen. For reference:
Mobile deviceScreen resolution
iPhone 3 (and previous generations)480 x 320
iPhone 4960 x 640
iPhone 5 (all variants)1136 x 640
iPhone 61334 x 750
iPhone 6 Plus1920 x 1080
Google Nexus 51920 x 1080
HTC One1920 x 1080
Samsung Galaxy 51920 x 1080
iPad Mini1024 x 768
iPad Retina display2048 x 1536
iPad Air2048 x 1536

Floor plans

Floor plans are also of great interest to our users when attempting to visualise the property. It is important to provide high resolution images for floor plans because otherwise text can become illegible.

10. Workflow overview

This section describes the workflow for how the ZPG Real-time Listings Service should be used and how to ensure that the data ZPG has is synchronised with your own.

10.1 Initial upload

10.1.1 A new estate agent is added to your system

For each branch that the estate agent owns, you send a branch/update.

10.1.2 Upload listing data

For each added branch, find the set of listings that they are responsible for. For each listing, send a listing/update message.

Recall that listing/update requires that it be accompanied by a ZPG-Listing-ETag HTTP header. The value of ZPG-Listing-ETag should be an identifier on your system which allows you to accurately determine that when two such values are different, the overall state of the listing is also different. Depending on how you track changes to your data (and how it is represented in a listing/update message) an auto-incrementing revision counter, or possibly a last-modified date may be suitable. However, we would recommend using a checksum based on the listing/update message itself:

  • Canonicalise the JSON listing/update message. (This is the default for many JSON software libraries but some require you explicitly perform that action, or possibly set a configuration flag to enable it.) This process ensures that the message is represented in a consistent fashion, regardless of the order in which you populated attributes within the message.
  • Produce a checksum hash (e.g.: MD5; SHA-1) of the canonicalised JSON message. Store this value on your system and send it as the ZPG-Listing-ETag.

10.2 Incremental changes

Amendments are made to a listing on your system

Send a listing/update message which details the complete state of the updated listing.

10.2.1 A listing ceases to be valid

Send a listing/delete message to delete it from our system.

10.3 Periodically check synchronisation

Because of the incremental nature of the updating process, should a message be lost (e.g. due to a networking problem), then the data that ZPG has will be different to yours and will need correcting. We therefore recommend that you periodically, once a week say, check the synchronisation of data:

10.3.1 Ask about the state of a branch's listings on ZPG's system

For each branch you maintain, send a listing/list request. In the response, for each of the branch's listings, we will provide you with your listing_reference and the ZPG-Listing-ETag that we last received for that listing.

10.3.2 Add listings

If listing/list is missing a particular listing, use listing/update to create it.

10.3.3 Remove listings

If listing/list includes a listing that is no longer valid, use listing/delete to remove it.

10.3.4 Update listings

For each listing that is common to both systems, compare the value of the ZPG-Listing-ETag with that of the relevant field in your system:

  • If the values are identical then the data is the same on both systems and you do not need to do anything. This should be the normal case.

  • If the values are different then ZPG's data is stale and you should use listing/update to refresh it.

11. Integration

11.1 Transitioning from an existing bulk data feed

If you currently send ZPG a bulk data feed then it may be useful to understand how the transition between that feed and the ZPG Real-time Listings Service will be handled before reading about how to build your implementation.

Data feeds received by ZPG are kept separate from each other: your data never interacts with anyone else's (nor theirs with yours) and should you send us multiple feeds they will not interact with each other either. We then choose which subsets of these data feeds will be shown on our websites (on a per-branch basis).

You should therefore design your system so that you can update ZPG via your bulk data feed and the Real-time Listings Service concurrently, thus maintaining two equivalent data sets simultaneously:

Once your Real-time Listings Service integration is complete and running smoothly, ZPG can then simply switch its websites over from using one data set to the other. This mechanism preserves your data's integrity; simplifies testing; makes it easier to QA attribute coverage and equivalence between both systems; and allows for a quick transition to having real-time behaviour for all branches simultaneously - if desired. (It also provides the security of a viable rollback option in the unlikely event that a major problem occurs during the migration.)

11.2 Test environment

11.2.1 Sandbox environment and API

This is an exact copy of the live environment but is isolated from our public websites. Any test messages you send here will only affect the data you previously sent to the sandbox environment; you cannot "break" anything. There are no restrictions on the number of messages you can send or listings you can store. Indeed, as part of your final testing you should maintain a copy of all your listing data in the sandbox environment (just as you would do in the live environment) in order to demonstrate that the system is mature and suitable for sending data to our public websites in real-time.

11.2.2 Preview listing web page

You can more easily visualise a particular listing's data via our listing preview page. Please note that whilst the preview is styled in a similar fashion to our websites it is only intended for illustrative purposes. The URL for a particular listing's preview page can be found in the responses from listing/update and listing/list.

The preview page will indicate whether we will be able to download the associated image and other content URLs, and for any images we could not access an "awaiting photos" placeholder will be shown. Please see 9. Retrieval of media content for more information about how we will retrieve your content and the set of IPs our download requests will originate from.

11.3 Building your implementation

Whilst you do not have to follow this exactly, we suggest:

  1. Check that your current image-hosting web servers respect If-None-Match and If-Modified-Since headers (see: 9. Retrieval of media content). If they don't then this could be having a negative impact on your infrastructure already.
  2. Obtain a signed certificate to allow HTTPS access to the ZPG Real-time Listings Service (see: 3. Security and authentication).
  3. Write code to communicate with the ZPG Real-time Listings Service. This can be facilitated by initially sending the example messages, rather than writing your own.
  4. Write code to generate and validate branch/update and listing/delete messages. These have relatively simple message formats which will make it easier for you to interpret schema validation errors.
  5. Write code to generate and validate listing/update messages. (You can preview how we will display that message by using the link provided in the url attribute of listing/update's response.)
  6. Determine if your system has a suitable field to use with ZPG-Listing-ETag. If there is nothing suitable then implement a hashing system as suggested in 10. Workflow overview.
  7. Having uploaded some listings, you can then use listing/list to see what was uploaded and can then implement your synchronisation mechanism, such as the one discussed in 10. Workflow overview.

11.4 Testing

Once you have a working system, it is important to thoroughly test it:

  1. Check that the ZPG-Listing-ETag is not using a temporary placeholder value and that it behaves correctly.
  2. Send actual listing data. During initial development you may have used our example messages, or written your own, which may not cover all the use-cases present in your actual data. We therefore recommend you send increasingly larger sets of real data to uncover any remaining issues:
    • A small random set of listings.
    • All listings for a branch.
    • All listings for a random set of branches.
    • All listings on your system.
    Check that these display correctly on their preview pages (see the url attribute in the responses for listing/update and listing/list) and that images could be downloaded by us.
  3. If you are able to upload all your listings without encountering any errors, then you should maintain those listings for a period of time (we suggest a week or two) just as you would in the live environment. In other words, perform a "dry run":
    • Send listing/update messages for all listings on your system. Find and remove previously sent test listings by utilising listing/list and listing/delete. (These steps are most easily achieved by running your synchronisation process.)
    • Send listing/update and listing/delete messages in real-time as agents edit their data.
    • Regularly check the synchronisation of data between your system and ours via listing/list. We suggest you also check the preview pages for a random sample of listings too in order to ensure that the data is indeed synchronised correctly.

11.5 Migrating to the live environment

It is expected that your system will communicate with the sandbox environment using actual data on a continual basis for at least a week, in order to prove that the combined system is stable, produces no unexpected errors and has no synchronisation issues. When you are happy that this is the case and it is therefore suitable to become the sole means of sending us listing data, please let us know so that you can be granted access to the live environment. The migration procedure is very similar to that used when testing in the sandbox environment:

  • Provide us with the details of all your branches. Please contact us if you do not wish to supply them via the branch/update method.

  • Send listing/update messages for all listings on your system to the live environment. (This is most easily achieved by running your synchronisation process. Please let us know when this initial upload has been completed.)

  • Send listing/update and listing/delete messages in real-time as agents edit their data.

  • Periodically check the synchronisation of data between your system and ours via listing/list.

Because the updating process will already have been shown to work correctly over an extended period in the sandbox environment, there should be no difficulties when using the live environment.

If you currently send ZPG a bulk data feed, please continue sending this to us - even after you start sending real-time updates to the live environment. Once your initial upload of data to the live environment has completed, please let us know. We will then change our branch configuration so that we stop using the listing data in your old bulk data feed and start using the data sent via the ZPG Real-time Listings Service instead. When we complete this branch migration process, we will inform you so that you can then terminate your old bulk data feed.

12. Conclusion

We hope that having read this documentation you have decided to integrate the ZPG Real-time Listings Service with your system.

If you have any questions about this documentation, schemas or the service in general, please contact our Support Team.

Thank you for your commitment to improving the quality of service that our mutual clients and users will receive by integrating your system with the ZPG Real-time Listings Service.

A1: Appendix Additional notes on attributes

A1.1 Boolean attributes

The majority of our boolean attributes are optional. You should only include a boolean attribute where you are confident that the value is correct; do not set it to a default value. The reason for this is that you may convey a meaning that you did not intend. For example if you were to default pets_allowed to:

  • true: potential tenants will complain if the landlord then rejects their application.
  • false: the landlord will receive fewer enquiries even though they might consider tenants with pets.,

Omitting boolean attributes where you do not know the correct value also has the benefit of reducing message sizes and making them easier to read when debugging.

A1.2 Datetime attributes

Dates should be expressed using standard ISO format: YYYY-MM-DD. Where appropriate, a time component may be included by appending the date with a literal T character separator, followed by the time as hh:mm:ss. Note that the time component should use the local time zone of the property. For example:

  • 2014-01-31
  • 2014-01-31T12:34:56

A1.3 Free-text string attributes

The quality of text supplied in free-text string attributes can vary considerably. In order to improve the user experience on our websites we may modify the display of these strings in order to present a consistent style and aid comprehension (e.g.: capitalisation; removal of HTML tags). If the quality of the text is particularly poor then, in some circumstances, we may choose not to display it at all (e.g. invalid data for the attribute). Care should therefore be taken at the initial data-entry stage to ensure that the correct attribute is being populated and that free-text intended to be read by the public is maintained appropriately (e.g.: spelling; grammar).

Our schemas use a regular expression to ensure that free-text attributes:

  • are neither empty nor only consist of whitespace
  • have no leading whitespace
  • have no trailing whitespace

Note that carriage returns (\r) and newlines (\n) are considered whitespace.

These rules are enforced by the schema via a regular expression, which will be included in any validation errors:

does not match '^\\S(|(.|\\n)*\\S)\\Z'

If you encounter this error you may find it easier to re-read the validation rules above in order to correct the text.

Please refer to 7.2 Errors for more information on error responses.

A1.4. Monetary attributes

All costs/prices should be quoted in the currency specified by pricing:currency_code.

A1.5. display_address

display_address is an optional attribute since it can be constructed from the dedicated address attributes: "street_name, locality, town_or_city". We recommend software providers provide a dedicated field for property_number_or_name, so that unique property address information will not be included in a constructed address. Software providers should encourage their clients to populate address attributes correctly, and to only use the display_address field when address information is conflicting and shows incorrectly on our site.

A1.6. Floor_levels

The layout of floors within a multi-storey building is defined as follows:

  • penthouse (top floor)
  • ... (increasing integer values)
  • 2
  • 1 (above street level)
  • ground (at street level)
  • basement (below street level)

A1.7. property_type

There are a lot of terms for describing house types. The distinctions between some of these types are sometimes unnecessary (for example: apartment vs flat) and broader groupings that just convey the core aspects of the architecture are preferred. Consequently we only support a relatively limited number of property types. When deciding which property type to use, you should choose the most applicable property type that we support. If you believe that there is a significant difference between your property type and those that we support, then send your property type as a readable string. In such cases we will display property type as "Property", but the string you supplied will be considered during our periodic review of property types to ensure that we are supporting the needs of our users adequately. (Please note that our supported property_type enums use all-lowercase characters; alternative case-variants will be displayed as "Property".)

Some property_types in your system may be conveyed by the appropriate use of other attributes. For example:

  • a "duplex" is a property_type = "flat" with floors = 2
  • a "triplex" is a property_type = "flat" with floors = 3
  • a "penthouse" is a property_type = "flat" with floor_levels = ["penthouse"]

When category = "residential", our schema will reject property_type = "studio" if total_bedrooms is also present and has a value greater than 1, as we cannot determine which value is inaccurate; see 7.2.2 JSON schema validation for more information about how we reject ambiguous messages.

Note that the display of the property_type is also dependent on the associated country_code and category of the listing. The schema does not enforce these rules. If an inappropriate property_type is specified for a particular country_code-category combination then it will be displayed as "Property" (residential) or "Commercial Property" (commercial). The list of supported property_types and their validity is as follows:

property_typeDisplay stringUK residentialOverseas residentialUK commercialOverseas commercial
barn_conversionBarn conversion
block_of_flatsBlock of flats
bungalowBungalow
business_parkBusiness park
chaletchalet
chateauChâteau
cottageCottage
country_houseCountry house
detachedDetached house
detached_bungalowDetached bungalow
end_terraceEnd terrace house
equestrianEquestrian property
farmFarm
farmhouseFarmhouse
fincaFinca
flatFlat
hotelHotel/guest house
houseboatHouseboat
industrialIndustrial
landLand
leisureLeisure/hospitality
light_industrialLight industrial
link_detachedLink-detached house
lodgeLodge
longereLongère
maisonetteMaisonette
mewsMews house
officeOffice
park_homeMobile/park home
parkingParking/garage
pub_barPub/bar
restaurantRestaurant/cafe
retailRetail premises
riadRiad
semi_detachedSemi-detached house
semi_detached_bungalow Semi-detached bungalow
studioStudio
terracedTerraced house
terraced_bungalowTerraced bungalow
town_houseTown house
villaVilla
warehouseWarehouse

A2. Appendix Message examples

  • Latest version.
  • 2023-08-01: v2.1
    • The accessibility feature has shifted from a boolean value to an enum list, now encompassing "lateral_living", "step_free_access", "wheelchair_accessible", and "wet_room".
    • Secondly, the "shared_ownership" object has been expanded to include a new field called "details."
  • 2022-06-30: v2.0
    • Changed gb residential sale example to demonstrate new structure for tenure/leasehold/ground_rent, added an example of the use of the new accessibility types, added an example of the new positioning of council tax bands.
    • Changed gb residential rent example to include new NI domestic rates example.
  • 2015-05-13 v1.0
    • Promoted version 0.1 to 1.0.
  • 2014-11-11: v0.1
    • Initial set of message examples.

A3: Appendix Schema changelog

Latest version
DateVersionSchema(s) changedChange description
2025-01-31v2.3listing/update

updatebuyer_incentives with additional terms "own_new_rate_reducer", "deposit_unlock" "part_exchange", as valid buyer_incentives

2024-03-19v2.3listing/update

"construction_materials" added - optional attribute listing of strings declaring notable materials in a buildings construction

"water_supply" added - optional attribute listing of fixed values indicating one or more sources of water to the property

"heating_source" added - optional attribute listing of fixed values indicating one or more supplies of heating to the property

"sewerage_supply" added - optional attribute listing of fixed values which best describe sewage managment for the property

"broadband_supply" added - optional attribute listing of fixed values accurately describing the nature of the supply (or supplies) of broadband to the property

"electricity_supply" added - optional attribute listing of fixed values which describe how electrical power is supplied to the property

"parking" extended with new fixed values which describe the parking options at the property

"building_safety_issues" added - optional attribute listing of strings declaring notable building safety concerns at this address

"risks" added - optional object containing relevant environmental property risks. includes "flooding_risks", "coastal_erosion_risk" and "mining_risks" as different risk categories

"known_planning_considerations" added - optional attribute free-text field declaring any known or notable property planning concerns/permissions at this address or nearby

"restrictions" and "rights_and_easements" added - optional attributes listing of fixed values which best describe any known or notable property restrictions and easements

expanded "accessibility" options. now prevents duplicate values and empty list. description edited to clarify

added "uprn" optional attribute. is a string of 1-12 characters max

2024-03-04v2.2listing/update

Tenure added - "non_traditional" is now an possible "tenure"

Extended "tenure:share_of_freehold" with optional "years_remaining" or "expiry_date" for any lease component (if relevant).

Deprecated and removed "review_period" from service_charge object.

In the ground_rent object, deprecated "percentage_increase", added "date_of_next_review".

2023-08-01v2.1listing/update

Firstly, the accessibility feature has shifted from a boolean value to an enum list, now encompassing "lateral_living", "step_free_access", "wheelchair_accessible", and "wet_room". Secondly, the "shared_ownership" object has been expanded to include a new field called "details."

Added a new field to shared_ownership object

2022-06-22v2.0listing/update

Addition of NTS fields and adjustments to existing structures to support these.

Added a domestic_rates object to cover the to expand the newly added Northern Ireland domestic_rates. This greatly restructures this attirbute to provide detail as to why the band would be unknown (new developments), and where a property is excluded from domestic rates. strictly speaking this should only apply to Northen Island properties though this is not enforced here.

2022-06-22v2.0listing/update

Addition of NTS fields and adjustments to existing structures to support these.

Converted "tenure" from a simple string to the tenure object, supporting sub-items specific to that tenure type.

Removed "shared_ownership" from buyer_incentives into the tenure[type=leasehold]:shared_ownership -specific entry.

Added a local_authority object to cover the moved council_tax_band and the newly added Northern Ireland domestic_rates. council_tax_band has also been restructured to provide detail as to why the band would be unknown (new developments), and where a property is exempt from council-tax.

Converted ground_rent from a single number to the ground_rent object to permit the addition of review_period and percentage_increase values. The original numeric value of ground_rent can now be submitted under the amount element of said object.

Added "coming_soon" as a pricing:price_qualifier and removed "price_on_application".

Added review_period to service_charge object

Moved lease_expiry values (expiry_date and years_remaining) under tenure[type=leasehold]

Added the letting_arrangements field to allow for descriptions of non-standard letting arrangements.

2017-06-14v1.2
  • branch/update
  • listing/update

Ensured the constraints within the location object in the branch/update schema matched those in the listing/update schema.

Added support for equity_loan to buyer_incentives.

Removed constraint on the maximum value of all epc_ratings object attributes, and sap_rating.

Updated the JSON schema draft v4 link on the schemas page.

2015-08-10v1.1listing/update

Added support for per_person_per_week frequency to service_charge:frequency and pricing:rent_frequency.

Implemented constraints for pricing:price_qualifier = "non_quoting" when location:country_code = "gb" and category = "commercial".

2015-05-13v1.0
  • branch/update
  • listing/delete
  • listing/list
  • listing/update
Promoted version 0.1 to 1.0.
2015-05-08v0.1listing/updateChanged the constraints concerning location:property_number_or_name and location:street_name so that at least one must be provided.
2015-03-19v0.1listing/updateChanged the constraints surrounding shared_accommodation and available_bedrooms.
2015-03-19v0.1listing/updateCorrected the spelling of shared_accommodation.
2015-03-13v0.1listing/updateFixed a bug with how total_bedrooms and property_type = "studio" interact.
2015-01-07v0.1= listing/update = Added sap_rating attribute.
2014-12-11v0.1listing/updateFixed constraints for residential listings so that total_bedrooms and bathrooms are not mandatory, as per the documentation.
2014-12-10v0.1
  • branch/update
  • listing/delete
  • listing/list
  • listing/update
Updated regular expression validation for free-text attributes.
2014-11-21v0.1branch/updateUpdated regular expression validation for attributes containing URL data so they are consistent: no whitespace is allowed. Where necessary, whitespace and other meta characters should be URI-encoded.
2014-11-14v0.1listing/updateUpdated the list of supported property_types so they are consistent with the documentation.
2014-11-10v0.1listing/update

Fixed typo in attribute name administration_fees

Added document to the list of valid type values for a content object.

2014-09-12v0.1
  • branch/update
  • listing/delete
  • listing/list
  • listing/update
Initial draft.

A4: Appendix Documentation changelog

  • 2025-01-31: v2.3
    • Added support for own_new_rate_reducer, deposit_unlock and part_exchange to buyer_incentives.
  • 2024-04-19: v2.3
    • Added "construction_materials" as a new optional attribute
    • Added "water_supply" as a new optional attribute
    • Added "heating_source" as a new optional attribute
    • Added "sewerage_supply" as a new optional attribute
    • Added "broadband_supply" as a new optional attribute
    • Added "electricity_supply" as a new optional attribute
    • Extended "parking" with new values
    • Added "building_safety_issues" as a new optional attribute
    • Added "risks" as a new optional object. contains the sub object "flooding_risks", "mining_risks" and "coastal_erosion_risk"
    • Added "known_planning_considerations" as a new optional attribute
    • Added "restrictions" and "rights_and_easements" as a new optional attributes
    • expanded "accessibility" options. now prevents duplicate values and empty list. description edited to clarify
    • add optional "uprn" attribute
  • 2024-03-04: v2.2
    • Added "non_traditional" as a possible option for "tenure"
    • Removed "percentage_increase" from "ground_rent" requirement.
    • Added "date_of_next_review" to "ground_rent". Clarified requirements for each field
    • Removed "review_period" attribute from "service_charge", also clarified requirements for each field
    • When giving a "tenure" of "share_of_freehold", you can now have an optional lease info component
  • 2023-08-01: v2.1
    • Change to "Accessibility" feature from boolean to enum of features. Change to the "Shared Ownership" object with addition of "details" field
  • 2019-05-20: v1.2
    • Added a note explaining that the dss attribute in the tenant eligibility object is now ignored.
  • 2017-06-14: v1.2
    • Ensured the constraints within the location object in the branch/update schema matched those in the listing/update schema.
    • Added support for equity_loan to buyer_incentives.
  • 2015-06-17: v1.0
    • Clarifying that the ZPG-Listing-ETag should be representative of the state of the associated listing/update message.
  • 2015-05-13: v1.0
    • Promoted version 0.1 to 1.0.
  • 2015-03-31: v0.1
    • Reworked the schema changelog to include which schemas were affected by each change.
  • 2015-03-10: v0.1
    • Summarising the flow of data to the ZPG Real-time Listings Service in 2. Overview.
    • Summarising the components of our test environment in 11. Integration.
  • 2015-03-03: v0.1
    • Clarifying that the role of ZPG-Listing-ETag only relates to checking data synchronicity. It does not affect how we interpret the listing/update message, which will always replace the previous version.
  • 2015-02-27: v0.1
    • Documenting all the possible attributes that might be returned in an error response.
  • 2015-02-12: v0.1
    • Added section 2.1 Simple workflow which provides the reader with a better context for understanding the rest of the document.
    • Added section 11. Integration which discusses:
      • a suggested sequence of steps to build your implementation of the service (this was previously discussed in the Conclusion)
      • testing methodology
      • migrating to the live environment
    • Defining the expected behaviour of ZPG-Listing-ETag more clearly.
    • Clarifying that listing/update:property_type should be supplied as an all-lowercase string (A1.7 property_type).
  • 2015-01-27: v0.1
    • Re-ordered appendices and added names to the menu.
    • Added link to example messages from section 5. Methods.
  • 2015-01-23: v0.1
    • preview_url has been renamed url, and this attribute is now present in the successful responses for listing/list and listing/update in both sandbox and live environments.
  • 2014-11-21: v0.1
    • The facility to preview how a listing will be displayed on our websites is now available. A listing-specific link is provided via the preview_url attribute in the responses for listing/update and listing/list.
  • 2014-09-12: v0.1
    • Initial draft.