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.

  1. total_results: returns the exact number of total results.
  2. 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.