Efestio Data Feed Service
1. Introduction
This document will provide instructions on how to import properties to efestio.com using the Efestio RESTfull API. This documentation will assume that you are already familiar with RESTfull services, HTTP requests and JSON documents. Before actually importing your listings, you must first test your application in our Sandbox API. The sandbox api is identical to the public api except the fact that it uses different resourses and only serves as a training ground for developers that wish to use our API. In order to gain access to the Sandbox, firstly you register at https://www.efestio.eu (which is the sandbox front end) and then contact us to request RTDF access. Using those you will be able to connect to the sandbox and start testing your application.
1.1 Real Time Data Feed Documentation
In order to import properties automatically using our API, you must follow our RTDF (Real Time Data Feed) Specifications.
The basic requirements for using the API are the following:
- Understanding REST architecture
- Experience with Token Based Authentication
- Experience with JSON Format
In order to qualify for the public version of the API you must firstly ensure that you can add/update/delete properties in the sandbox version of the efestio website ( www.efestio.eu ).
2. Simple technical overview
2.1 Requests
Each request must have the following headers:
Key | Value |
---|---|
Content-type | application/json |
expiry | 1510664874 |
uid | example@mail.com |
access-token | aKQfdsdssdsadQOOg |
client | S90sadsadasOKIQ |
Each and everyone of your requests to the API must have the above headers included.
2.2 Authentication
For the v1 version of the API, we are using Token Based Authentication. In order to use the API you must first register a user at www.efestio.com (after you have tested your application in the sandbox). Using the credentials of this user, you can login to the system and start uploading. Upon sending the authentication request, the server will return a JSON document with the user’s data along with the token, user id, the client id and the expiration date of the session in the response’s headers like so:
2.2.1 JSON RESPONSE
"data": {
"id": 1,
"email": "example@somemail.gr",
"provider": "email",
"uid": "example@somemail.gr",
"name": null,
"nickname": null,
"image": null,
"type": "user"
}
Headers
The required headers below are necessary for the authentication process. After this, in order to authenticate each request, you must include these headers every time.
Key | Value | Required |
---|---|---|
access-token | aKQfdsdssdsadQOOg | true |
cache-control | max-age=0, private, must-revalidate | |
client | S90sadsadasOKIQ | true |
content-type | application/json; charset=utf-8 | |
etag | W/"02685dasadsadse8e73dfb" | |
expiry | 1507635738 | true |
token-type | Bearer | |
transfer-encoding | chunked | |
uid | example@somemail.com | true |
vary | Origin | |
x-content-type-options | nosniff | |
x-frame-options | SAMEORIGIN | |
x-request-id | ad07ad72-a589-4050-96ba-0007a008035d | |
x-runtime | 0.454054 | |
x-xss-protection | 1; mode=block |
2.2 Endpoints
The main endpoints of our service are 4 ( four ) in number : Login, Update/Create, Delete and Get Branch.
Endpoint name | URL | http request | Description |
---|---|---|---|
Login | https://api.efestio.eu/auth/sign_in | POST | Authentication endpoint. Get the necessary headers needed for any request. |
Update/Create | https://api.efestio.eu/v1/rtdfhomes/ | POST | This endpoint is used to create and update properties using the API |
Get Branch | https://api.efestio.eu/v1/rtdfhomes | GET | This endpoint is used to retrieve a list of listings that are already imported. You will notice that the list contains both the internal (our system) ID and the external ID (your ID). The response is paginated. You must note that the GetBranch endpoint will only return listings that were imported via the RTDF system. This means that if you manually uploaded a listing, it will not appear in your GetBranch response. |
Delete | https://api.efestio.eu/v1/rtdfhomes/:listing-id | DELETE | This endpoint is used to delete listings that are no longer available from our system. According to REST schema, the resourse of your listing can be found under the controller “rtdfhomes”. The only difference here is that you can delete a listing using only your external id. The server will search your listings and delete it. If no such listing is found, then the server returns an appropriate response letting you know that no such listing was imported by your account. |
3. Objects Model
In this section, we will explore the data schema of our API and what it means. Using the information in this chapter, you will be able to create appropriate JSON documents to import your listings and to interpret the server’s responses.
3.1 The Property Model
Object attribute | Requirements | Type | Description | Example |
---|---|---|---|---|
base_price | mandatory | integer | Listing price | 98000, should be >0 |
base_area | mandatory | integer | The area of the property in square meters. This value is the base value of the area that is used for all search queries. If the property is land, you must assign the area of the plot to this attribute as well | 80, should be >0 |
lat | mandatory | float | GPS Latitude | 23.23452345 |
lon | mandatory | float | GPS Longitude | 16.00003004 |
amenities | mandatory to present ( the aminities could be empty or false ) | JSON string | Includes the available amenities of the property | See Amenities Model below |
images | mandatory | JSON string | Includes the images for the property | See Images Model below |
bedrooms | Best Practice | integer | Number of bedrooms | should be >= 0 |
bathrooms | Best Practice | integer | Number of bathrooms | should be >= 0 |
rooms | Best Practice | integer | Number of rooms. This is the total number of rooms and may well include the bathrooms and bedrooms | should be >= 0 |
floors | Best Practice | integer | Number of property floors. It may well be ommited if the property has only one floor | should be >= 0 |
floor_id | Best Practice | integer | Represents the floor where the apartment is located on. | [-2..6] |
year_built | Best Practice | integer | The year the property was built | should be >=1960 and <= current_year |
home_cat_id | mandatory | integer | The listings parent category | [1..3] *See home categories below |
home_type_id | mandatory | integer | The property type | [1..9] *See properties types below |
distance_sea | Best Practice | integer | Distance from the sea in meters | should be >= 0 |
distance_city | Best Practice | integer | Distance from the city center in km | should be >= 0 |
distance_port | Best Practice | integer | Distance from the nearest port in km | should be >= 0 |
distance_airport | Best Practice | integer | Distance from the nearest airport. This attribute is actually ommited since the server will automatically detect the nearest airport in a 400km radius using the coordinates of the property | should be >= 0 |
seaview | Best Practice | boolean | View of the sea | |
cityview | Best Practice | boolean | View of the city | |
forrestview | Best Practice | boolean | View of the forrest | |
mountainview | Best Practice | boolean | View of the mountains | |
plot_area | Best Practice | integer | The area of the plot where the property is built on. If the property type is “Land” then it is the area of the land itself. | should be > 0 |
living_area | Best Practice ( only for residential category types) | integer | The actual living space of the property | should be > 0 |
rentability | Best Practice | boolean | If the property is available for rent | |
income_year | Best Practice (If the type is “Commercial” then it is strongly recommended) | integer | The possible income someone can generate per year with this property. Refers to all property types. | should be >= 0 |
taxes_year | Best Practice | integer | The possible taxation of this property in an annual basis | should be >= 0 |
utilities_year | Best Practice | integer | The utilities cost of the property on an annual basis | should be >= 0 |
video_id | Best Practice | string | The youtube video id | |
user_updated_at | mandatory | DateTime | The modified date of your property in your system | "dd'-'MM'- 'yyyyHH:mm:ss" |
descriptions | Best Practice | JSON String | An array of JSON objects | See below for the description model |
Notes :
- The system supports properties with price on request. In order to proclaim a property with price on request you must set the base_price value to “999999999”. In any other case, the price will be shown and your property will likely be removed for inaccurate information.
- If you wish to update your properties, you can use the user_updated_at attribute to check if there have been any changes made to your listing before importing it again. If the dates match, then the server will not update the listing. Bare in mind that you are strongly discouraged to update all the listings regardless of modifications.
- Provide as much “accurate” information as possible. Each listing is assigned a value that determines it’s qualification to “Premium” status as well as it’s position in all search results. This value is influenced in part from the information you provide, especially images and descriptions.
- Provide descriptions in any language you have. Bare in mind that each description is evaluated based on the complexity and quality of the text. This means that if your description in some language is not good you should consider not including it.
3.2 Property Categories and Property Types
The listings in efestio, are subdivided into categories, and property types respectively, for example, one listing which belongs to residential category, cannot be bussines property or hotel, which belogns to commercial category.
Listings Categories and theirs ids:
ID | Category Type |
---|---|
1 | Residential |
2 | Commercial |
3 | Land |
Listings Types and theirs ids:
ID | Category Type |
---|---|
1 | Apartment |
2 | Duplex |
3 | Towhouse |
4 | Cottage |
5 | Villa |
6 | Business |
7 | Store |
8 | Hotel |
9 | Land |
3.3 The Amenities Model ( JSON String )
In this subchapter we will explore the structure of the amenities JSON string. A sample of such string can be seen here:
amenities: "{
"wifi": false,
"parking": false,
"ac": true,
"basement": false,
"storage": false,
"elevator": true,
"fireplace": true,
"hvac": false,
"bbq": true,
"garden": false,
"pool": false,
"road_access": false,
"corner": false,
"watter_supply": false,
"heat_type": 0,
"electricity": false
}"
Notice that the whole object is wrapped in double quotes ""
, this is because as we said earlier, the amenities are represented as JSON String, in order to be easily parsed from javascript, and keep the database as simple as possible.
Not all amenities are always available. There are different amenities for each parent category. For example, if the listing has hope_type_id = 1
(e.g Appartment), the amenities that belongs to Land or Commercial listings ( watter supply, road access, corner, etc.. ) will be ignored, regardless if they are set to true in the amenities object.
Below is a list with the Amenities that every category has
Property Category | Amenities |
---|---|
Residential | wifi, parking, ac, basement, storage, elevator, fireplace, hvac, bbq, garden, pool |
Commercial | wifi, parking, ac, basement, storage, elevator, fireplace, hvac |
Land | water_supply, electricity, road_access, corner |
3.4 The Images Model ( JSON String )
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.
Images are stored as JSON object string attribute, that contains some attributes respectively. The first attribute is the “featured” key, which is the link of the featured image of the listing ( that will be shown on the single property view) and “image_array” which are the links of the images themselves. You can see an example of such object for a single image of the array here:
"{
"featured": "https://cdn2.examplecdn.com/images/large/example.jpg",
"image_array": [
{"image_name":"388428fsdf823f.jpg","image_name_no_guid":null,"original_url":"...","large":"...","medium":"...","small":"...","thumbnail":"...","floor_id":0,"image_name_no_extension":"388428fsdf823f"},
{"image_name":"388428fsdf823f.jpg","image_name_no_guid":null,"original_url":"...","large":"...","medium":"...","small":"...","thumbnail":"...","floor_id":0,"image_name_no_extension":"388428fsdf823f"},
{"image_name":"388428fsdf823f.jpg","image_name_no_guid":null,"original_url":"...","large":"...","medium":"...","small":"...","thumbnail":"...","floor_id":0,"image_name_no_extension":"388428fsdf823f"},
{"image_name":"388428fsdf823f.jpg","image_name_no_guid":null,"original_url":"...","large":"...","medium":"...","small":"...","thumbnail":"...","floor_id":0,"image_name_no_extension":"388428fsdf823f"},
{"image_name":"388428fsdf823f.jpg","image_name_no_guid":null,"original_url":"...","large":"...","medium":"...","small":"...","thumbnail":"...","floor_id":0,"image_name_no_extension":"388428fsdf823f"}
]
}"
Notice that the whole object is wrapped in double quotes""
, this is because as we said earlier, the Images are represented as JSON String, in order to be easily parsed from javascript, and keep the database as simple as possible.
There are several fields for each image. You can use all the fields or you can just provide the “large” image url. Our server automatically will try to download the images but it would be best practice if your provided all the information depicted above. You can include up to 25 images for each listing. You should remember that choosing images with high quality increases greatly the value of each listing.
Object Attribute | Requirements | Type | Description |
---|---|---|---|
featured | mandatory | string URL | The featured image of the listing |
image_array | mandatory | array | Array of all images that listing contains |
image_name | mandatory | string | the full image name ( usually GUID name ) |
image_name_no_guid | optional | string | original image name without GUID |
original_url | Best Practice | string URL | The original URL of the image ( used by our systems, when user uploads manually a property ) |
large | mandatory | string URL | The large size of the image ( our system will automatically generate and resize the smaller images, based on this one ) |
medium | Best Practice ( if not provided, will be generated automatically) | string URL | |
small | Best Practice ( if not provided, will be generated automatically) | string URL | |
thumbnail | Best Practice ( if not provided, will be generated automatically) | string URL | Thumbnail ( usually small image, below 160x160, used to images preloading in our system) |
floor_id | mandatory ( default value should be 0 ) | integer | The floor that the image is belong |
image_name_no_extension | optional | string | The image name ( with GUID ) without the extension (e.g *.jpg) |
The featured image should ideally be of the exterior of the property.
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.
3.5 The Descriptions Model ( JSON String )
The “descritpions” attribute is fairly simple as seen bellow
{
{"lang_id":"en","text": "Property description"},
{"lang_id":"gr","text": "Περιγραφή"},
{"lang_id":"ru","text": "Описание недвижимости"}
}
Each object has two fields, “lang_id”
and “text”
. The first is used to declare the language of the description, and it uses ISO 639-1 coding. The second one is the description itself which should contain only text with no special characters or mark-up language. You can add descriptions in all languages, not just the ones that are available on our website. This is because our site will be always expanding and when those languages will be available, your listings will have already descriptions.
4. XML Data Feed Specification
Efestio XML feed provides a fully automated way to keep properties on the website up to date and synchronized with listing agencies' real estate software and XMLs.
4.1 Feed Processing
In order to upload properties to efestio.com through XML Feed, you need to:
- Generate an xml-file in an appropriate format ( listed below )
- Place this xml-file on your site / hosting server
- Send us a link to your xml-file (for example, http://api.efestio.com/samplexml.xml)
- Set an automatic update of the xml-file on your server
- Register / Create new user account on efestio.com
- Contact Us to request RTDF access
The properties are updated daily from a 'live' URL of the feed. All the images are getting downloaded to our servers and the website serves them from there. We record the download URL of every image and re-download them only after URL change. Please make sure the image URLs contain last updated timestamp or file checksum in case it is possible for the images to change with no change in the URL.
You can use any XML format you want to, but some XML attributes are mandatory:
Refer to efestio 3.1 The Property Model
without those attributes, properties cannot be uploaded to efestio
Example of such XML format, can be seen below:
<root>
<properties>
<property>
<id>22456</id>
<price>88000</price>
<currency_id>EUR</currency_id>
<updated_at>19-0-2017T:14:334:454</updated_at>
<created_at>19-0-2017T:14:334:454</created_at>
<location>
<langitutde>33.9488599</langitutde>
<longitutde>26.4445454</longitutde>
</location>
<area>45</area>
<living_space>23</living_space>
<plot_area>143</plot_area>
<rooms>3</rooms>
<property_type>4</property_type>
<images>
<image>https://cdn.example.com/image/example.jpg</image>
<image>https://cdn.example.com/image/example.jpg</image>
<image>https://cdn.example.com/image/example.jpg</image>
<image>https://cdn.example.com/image/example.jpg</image>
<image>https://cdn.example.com/image/example.jpg</image>
<image>https://cdn.example.com/image/example.jpg</image>
</images>
<yaer_build> 2012</yaer_build>
<forret_view> true </forret_view>
<distance_from_sea> 100 </distance_from_sea>
<amenities>
<wifi> true </wifi>
<pool> true </pool>
<parking> true </parking>
</amenities>
<floors> 1 </floors>
<floor_level>3</floor_level>
<description>
<en> This is simple description </en>
<es> Esta es una descripción simple </es>
</description>
</property>
</properties>
</root>
Some explenation about XML attributes
- currency_id is not present in efstio 3.1 The property model, although it should exist in the XML feed, otherwise we assume that the price is in EUR.
- Langitude / longitude is the coordinates of the property ( i.e where is located ). If there is no langitute/longitude available for the property, then at least location fields should be present ( country – region – city etc.. ), without those, property cannot be uploaded to efestio
- images container for images. A property without any image cannot be uploaded. Allowed image formats are *.jpg, *.gif, *.png
- image container for each image.
- property_type Type of the property. Mandatory, numeric [0-9] field. refer to efestio property types.
If your company cannot generate this specific format for us, we are accepting other XML formats aswell, like XML Prian.ru format and homeoverseas , Nevertheless is best practice to provide us with the appropriate format like the example above. Keep in mind, that if you want to provide to us your own XML format, the above properties are mandatory (location, price, area, currency_id, id, images, and updated/create date), we will need also a readable documentation about your XML scehma.
5. Test environment
5.1 Sandbox environment and API
This is an exact copy of the live environment but is isolated from our public website. 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. The tested enviroment is located on www.efestio.eu
Appendix 1. Additional notes on attributes
A1.1 Datetime attributes
Dates should be expressed using format: dd-mm-yyyy. 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:
- 19-09-1991
- 19-09-1991T12:34:56
A1.2 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'
A1.3 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. 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.4 Monetary attributes
All costs/prices should be stored as integers. Our system will interpreted it then as currency ( for XML Feed, the current currency is specified via currency_id value, e.g currency_id: 'EUR'
A1.5 floor_levels
The layout of floors within a multi-storey building is defined as follows:
Id | Name |
---|---|
0 | Basement |
1 | Semi-Basement |
2 | Ground Floor |
3 | First Floor |
A1.6 home_type_id
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.
When home_cat_id = "residential"
, our schema will rejecthome_type_id = "hotel"
home_type_id | Display string | Residential | Commercial | Land |
---|---|---|---|---|
1 | Apartment | | ||
2 | Duplex | | ||
3 | Townhouse | | ||
4 | Cottage | | ||
5 | Vila | | ||
6 | Store | | ||
7 | Hotel | | ||
8 | Business | | ||
9 | Land | |
Appendix 2. Schema changelog
Date | Version | Schema(s) changed | Change description |
---|---|---|---|
08-06-2017 | v0.1 |
| Initial draft. |
Appendix 3. Documentation changelog
- 16-08-2018: v0.1
- initial draft.