RETS RABBIT API DOCUMENTATION
RETS Rabbit is a robust real estate data solution designed to make working with real estate data easy and predictable for the average agent, broker, and developer.
Author: APC
API Version : 2.0
GETTING STARTED
The RETS Rabbit API is organized to conform to the OData v4.0 standard. It is meant to be compliant with the RESO Web API standards (http://www.reso.org/reso-web-api/).
The RETS Rabbit API is organized around REST. We designed the API so it will have predictable, resource-oriented URLs and use HTTP response codes for all responses (even errors). All responses will be returned as JSON, including errors.
Standard Rets Rabbit API endpoint
https://werx.retsrabbit.com/api
Getting an access token
We use oAuth 2.0 for authentication and authorization. To get an access code, send a POST request to /oauth/access_token.
Standard API endpoint
POST https://werx.retsrabbit.com/api/oauth/access_token? grant_type=client_credentials& client_id=<your client id>& client_secret=<your client secret>
All requests must be made over SSL (https). KEEP YOUR CLIENT ID & SECRET PRIVATE, do not share with anyone. After sending the request you should get an access token back.
Getting the access_token back in a request
{ "access_token":"<your access token>", "token_type":"bearer", "expires":<timestamp>, "expires_in":3600 }
Once you have the access token, you must include it in the request when calling the API. You can include it in the URL or pass it along in the header.
In the examples below, assume access_token is being passed
Getting the resources available in the API
A component of the RESO Web API standard is an endpoint describing the resources and endpoints available in the API. This can be retrieved using the datasystem endpoint.
https://werx.retsrabbit.com/api/datasystem
The response will contain the number of Resources you can access via the API, the RESO Web API versions support as well as other information about the API.
{ "@odata.context": "api/$metadata", "ID": 1, "Name": "Rets Rabbit", "SeviceURI": "/api/v2", "DateTimeStamp": "2016-06-06 7:06pm", "Transport": 1.4, "DataDictionaryVersion": 1.4, "Resources": [ { "Name": "Property", "ResourcePath": "/api/v2/property", "Description": "RESO Standard Property Resource", "DateTimeStamp": "2016-06-06 7:06pm", "TimeZoneOffset": 0, "Localizations": [] }, { "Name": "Media", "ResourcePath": "/api/v2/media", "Description": "RESO Standard Media Resource", "DateTimeStamp": "2016-06-06 7:06pm", "TimeZoneOffset": 0, "Localizations": [] } ] }
Getting Metadata for a Resource
Next, you’ll want to look up the metadata for a Resource. The metadata will contain information about the response fields & data a resource will return. For example, you can retrieve the metadata for a property resource using the following endpoint:
https://werx.retsrabbit.com/api/v2/property/$metadata
You’ll see an XML response of fields available when you query for either a collection or individual properties. Our output will largely follow the RESO Data Dictionary standard, which is an industry-wide data schema under adoption by MLSs in the United States.
Example Response:
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx
xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
<edmx:DataServices>
<Schema
xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Retsrabbit.Models.Property">
<Property Name="AboveGradeFinishedArea" Type="numeric"/>
<Property Name="AboveGradeFinishedAreaSource" Type="character varying"/>
<Property Name="AboveGradeFinishedAreaUnits" Type="character varying"/>
<Property Name="AccessCode" Type="character varying"/>
<Property Name="AccessibilityFeatures" Type="text"/>
<Property Name="AdditionalParcelsDescription" Type="character varying"/>
<Property Name="AdditionalParcelsYN" Type="boolean"/>
<Property Name="AnchorsCoTenants" Type="text"/>
<Property Name="Appliances" Type="text"/>
<Property Name="ApprovalStatus" Type="character varying"/>
<Property Name="ArchitecturalStyle" Type="text"/>
<Property Name="AssociationAmenities" Type="text"/>
<Property Name="AssociationFee" Type="numeric"/>
...
</Schema>
</edmx:DataServices>
</edmx:Edmx>
Properties
Now that you’ve retrieved the metadata, you can interact with the RETS Rabbit server to search for properties.
GET A SINGLE PROPERTY
A single property can be returned using the following
GET /v2/property(ListingId)
Where ListingId
is the unique id (or MLS number) of the property on the RETS server. The response will be a single JSON object containing the property & the fields as defined in the metadata.
Get a listing for ‘74958’
GET /v2/property(74958)
Response
{ "@odata.context": "api/v2/$metadata#property/$entity", "id": 2067, "ListingKey": "200", "ListingId": "74958", "StandardStatus": "Active", "MlsStatus": null, "ApprovalStatus": null, "ListingContractDate": "2016-04-12", ... "listing": { "server_hash": "86f93cfc06ceb49d6c837916857cef7d", "mls_id": "74958", "rets_class": "Listing", "active": true, "lat": null, "long": null, "geo_partial": false, "photos": [ { "id": 914, "mls_id": "74958", "filename": "74958_Photo_1.jpg", "url": "https://s3.amazonaws.com/rets-rabbit-bucket2/86f93cfc06ceb49d6c837916857cef7d/74958_Photo_1.jpg" }, ... ] } }
The complex value listing
is for Rets Rabbit specific information which also includes an array for photos. If you’d like to exclude photos from the response, see the $select
option (under Limiting results to specific field values in this section).
Running a Search
Filtering by a field value
Filtering properties by field values can be accomplished using the $filter
option. All the names in the $filter
option are case-sensitive and match the name of the fields provided by the property resource.
The following expression passed to $filter
will get properties where the Listing Agent’s last name (field ListAgentLastName) is ‘DOE’ (case sensitive):
GET /v2/property?$filter=ListAgentLastName eq 'DOE'
Example Response:
{ "@odata.context": "api/v2/$metadata#property", "@odata.count": 185, "@retsrabbit.total_results": 185, "value": [ { "id": 2154, "ListingKey": "287", "ListingId": "22680", "StandardStatus": "Active Under Contract", "ListingContractDate": "2016-02-08", "listing": { "server_hash": "86f93cfc06ceb49d6c837916857cef7d", "mls_id": "74958", "rets_class": "Listing", "active": true, "lat": null, "long": null, "geo_partial": false, "photos": [ { "id": 123, "mls_id": "74958", "filename": "74958_Photo_1.jpg", "url": "https://s3.amazonaws.com/rets-rabbit-bucket2/86f93cfc06ceb49d6c837916857cef7d/74958_Photo_1.jpg" }, ... ] } } ... }, { "id": 2064, "ListingKey": "197", "ListingId": "67787", "StandardStatus": "Closed", "ListingContractDate": "2015-11-24", ... }, ... ] }
value
is an array that will contain the results of the query, each item in the array represents a property. @odata.count
and @retsrabbit.total_results
will give you the # of results in the value array in the response and the number of records actually in the RETS Rabbit database. This is useful for pagination, see the Pagination section for more details.
Filtering by multiple field values
You can combine expressions together with or
and and
to perform more complex searches.
Getting properties for Listing Agent matching JOHN DOE:
GET /v2/property?$filter=ListAgentLastName eq 'Doe' and ListAgentFirstName eq 'John'
You can get properties where the listing agent’s last name is either ‘Smith’ or ‘Doe’:
GET /v2/property?$filter=ListAgentLastName eq 'Doe' or ListAgentLastName eq 'Smith'
“Not equals” filtering
Using ne
(not equals) it’s possible to filter properties that don’t contain a value:
GET /v2/property?$filter=ListAgentLastName ne 'Doe'
Filtering by wildcards
You can do wildcard or case insensitive searches by using the following special functions with the $filter
option. All of the functions are case-insensitive.
Get all properties whose listing agent’s first name starts with ‘joh’
GET /v2/property?$filter=startswith(ListAgentFirstName, 'joh')
Get all properties whose listing agent’s first name ends with ‘ohn’
GET /v2/property?$filter=endswith(ListAgentFirstName, 'ohn')
Get all properties whose listing agent’s first name contains the string ‘oh’
GET /v2/property?$filter=contains(ListAgentFirstName, 'oh')
Matching on upper or lower case
GET /v2/property?$filter=toupper(ListAgentLastName) eq 'DOE' GET /v2/property?$filter=tolower(ListAgentLastName) eq 'doe'
Searching by numeric range
In addition to using eq
you can also use gt
(greater than), lt
(less than), ge
(greater than or equals) and le
(less than or equals) operators to perform searches on dates and number values.
Properties with a listing price less than $50K
GET /v2/property?$filter=ListPrice lt 50000
Properties with a listing price between $50K & $200K
GET /v2/property?$filter=ListPrice ge 50000 and ListPrice le 200000
Properties with a listing price greater than $200K
GET /v2/property?$filter=ListPrice gt 200000
Filtering by Date
You can also use the year
, month
, day
, date
, time
, hour
, minute
and second
functions to filter properties by date and time.
Properties listed in the year 2016
GET /v2/property?$filter=year(ListDate) eq 2016
Properties listed before 2016
GET /v2/property?$filter=year(ListDate) lt 2016
Properties listed in June 2016
GET /v2/property?$filter=year(ListDate) eq 2016 and month(ListDate) eq 6
Sorting
You can sort listings using the $orderby
option. Just specify the field and the direction of the sort.
Sorting by ListPrice
GET /v2/property?$orderby=ListPrice asc
Pagination
You can limit results and paginate through records from the API using the $top
and $skip
options.
If you want to limit results to 10 at a time set the $top
parameter to 10 and $skip
to 0.
GET /v2/property?$top=10&$skip=0
If you want to get the next set of results, change the $skip
parameter to 11.
You can use the @retsrabbit.total_results
and @odata.count
fields in the response to determine how many “pages” of results to show in your pagination control.
Notice: We no longer return total_results
by default in the api responses. To request the total results for a request you must pass one of the following two flags to the $select clause.
- total_results: returns the exact number of total results.
- estimated_results: returns an estimated number of results.
In most cases we suggest the use of the estimated_results
flag as it can dramatically decrease the round trip time of an API call sometimes by more than 50%.
Limiting results to specific field values
Occasionally you don’t want to return all of the data available for a resource. You can use the $select
option to limit the fields that are returned for a request. The Rets Rabbit specific object ‘listing’ will always be displayed (excluding photos
, if you want photos
to be displayed, pass photos in the $select
option).
Active listings in ‘Columbus’, show only the ListingKey, ListPrice, and StandardStatus fields
GET /v2/property?$select=ListingKey,ListPrice,StandardStatus&$filter=City eq 'Columbus' and StandardStatus eq 'Active'
Response
{ "@odata.context": "api/v2/$metadata#property", "@odata.count": 42, "@retsrabbit.total_results": 42, "value": [ { "ListingKey": "200", "ListPrice": "73414.55", "StandardStatus": "Active", "listing": { "server_hash": "86f93cfc06ceb49d6c837916857cef7d", "mls_id": "74958", "rets_class": "Listing", "active": true, "lat": null, "long": null, "geo_partial": false } }, ... ] }
Caching
We cache all api requests for faster response times. There are some cases where you may want to make sure you are not receiving stale data (although our caches have a fairly low ttl, 45 min). We now have a flag you can pass in the $select clause of a request called no_cache
. This basically tells the API to ignore looking up a cached version of this request ensuring you receive an up-to-date response.
Media
If you’d like to retrieve just the available photos for a property outside of a normal property lookup or search you can use the Media endpoint.
Getting the media for property ‘74958’
GET /v2/property(74958)/media
Example Response
{ "@odata.context": "api/v2/$metadata#property/$entity/$metadata#media", "@odata.count": 5, "value": [ { "id": 914, "mls_id": "74958", "filename": "74958_Photo_1.jpg", "url": "https://s3.amazonaws.com/rets-rabbit-bucket2/86f93cfc06ceb49d6c837916857cef7d/74958_Photo_1.jpg" }, ... ] }
Support
Send an email to support@apcdata.net for any questions or issues.
©2019 APC Data Analytics, LLC All rights reserved.