Web API Documentation

We are RESO Certified

Being RESO certified means, that we comply with real estate data standards. The certification ensures interoperability between technology systems that speak a common language. RESO provides that common language.

The Source of Real Estate Data in Oregon and SW Washington

RMLS is Pacific Northwest’s largest Multiple Listing Service and the number one source for real estate listing information in the state of Oregon and Southwest Washington. Our Data Services website is a resource for software developers who are looking to obtain access to MLS data in order to develop products for brokers, agents, and/or appraisers who are members of RMLS.

Licensed MLS data is made available via our application programming interface (“API”), which utilizes the best data distribution methods available. The MLS licenses data for our members for a wide array of products, some of which include:

Internet Data Exchange (“IDX”) listing search websites, mobile applications, and/or audio devices

Customer Relationship Management (“CRM”) products

Statistical and internal analytics tools

Virtual Office Websites (“VOWs”)

Comparative Market Analysis (“CMA”) products

Print and digital listing marketing materials

Listing syndication (i.e. third-party listing search websites)

We are committed to making the data license application process as efficient as possible, which in turn will allow you to assist your RMLS member clients quickly. Contact our Data Service department or read below to find our more about our process and getting started.

Getting Started

A step-by-step breakdown of the data license application process, what to expect, how long it will take, etc.

FAQs

If you have questions, we have answers.

API Specs and Documentation

Find out more information about our API by reviewing the applicable technical documentation and specifications.

Getting Started with an RMLS Data Feed

Here is a step-by-step breakdown of what to expect when you request a data feed from RMLS.

Partner with an RMLS subscriber

RMLS only provides data to service providers who are working with at least one of our subscribers. You initiate the process by contacting our Distribution Services team via email at ds@rmls.com.

We will ask you to provide basic information about your company. You will designate a technical and administrative contact that will be associated with your account.

The technical contact should be the individual or group (if using a shared group email) who is handling the data feed. The administrative contact should be the individual that is authorized to sign the licensing agreement on behalf of your company. Please make sure to include this individual’s title when entering the information.

Finally, provide us with a brief description of the product you are developing and how that product will use RMLS data.

Licensing Agreement

A licensing agreement signed by the RMLS subscriber, the Participant Broker for their firm, and a representative of your company is required to proceed. The documents are available directly from us or from the subscriber that you are working with.

Begin Building your Product

As soon as we have received the Listing Content License Agreement (LCLA), we will send credentials that will allow you limited access to the API so that you can start building the product our subscriber has requested.

RMLS Review

As soon as the product is ready for review, send an email to ds@rmls.com so that we can review the product. This offering does not have to be a public site; we can review test sites. Once we have completed our initial review, we will let you know if we have questions or concerns about the display and will work with you to make sure that it meets our requirements.

API Access

Once the site is approved, we will remove the limitations on the data feed and begin the billing cycle. If there are ever any questions about your data feed our Distribution Services team will be your point of contact to get them resolved.

Frequently Asked Questions

Current Data Recipients

Q. How do I change my company contact information?
Contact ds@rmls.com and we will update your information.

Q. What do I do if I am having issues with the API or with the data being pulled back?
  • Confirm that the Authorization Bearer Token is being sent in the headers.
  • Confirm that you are not trying to access a resource, field, property type, and/or status which you do not have access to.
  • When filtering, check the metadata document and confirm the field exists and the correct data type is being used for the filter.
Q. What if I am missing listings?
In most cases, if a listing(s) is missing it would be due to one of the following:

  • The status or property type has changed, and you do not have access to the listing.
  • The listing itself has not updated. Listing updates run every 15 minutes, so check again in 15 minutes.
  • There is an error in the API. If this is an issue, please contact us at ds@rmls.com. In your email include the query and the listing number(s) that is missing.
Q. As a vendor, who can I provide my product to?
Your use of MLS data must be exclusively for RMLS subscribers.
Q. Where do I find rules and policies related to my use of the data?
You will need to reference your Listing Content License Agreement (LCLA) and the RMLS Internet Policy, both of which are available by request to ds@rmls.com.

Q. How do I cancel my agreement?
In general, to terminate your agreement, please provide written notice of your intent to terminate the agreement via email to ds@rmls.com. Please refer to your Listing Content License Agreement (LCLA) for specific information on how you can terminate your agreement.

Q.How do I add an additional product to my agreement with RMLS?
If you are interested in updating your licensing agreement, please email us and provide a brief description of the products you would like added to your agreement.

Q. How to I obtain access to a different data feed?
We have “standard” data feeds that we provide for common products, such as an IDX feed, VOW feed, and a full feed. However, we also tailor data feeds to specific products as needed. Please contact us if you want to discuss changing your level of data access.

Q. Where are invoices sent?
Email reminders regarding upcoming payment due dates are sent to both the administrative and technical contacts associated with your Data Services account. Paper invoices are not sent and it the responsibility of the vendor to make the online payment by the due date referenced in the email reminder.
Q. How do I make a payment?
Login to your Data Services account and select the Make Payment option. You can submit your payment online (preferred) or print instructions on how to send us a check.
Q. Where can I find a receipt for a payment?
Login to your Data Services account and select the Payment History option. You can generate receipts for all prior payments made from this page.

Q. Do you have autopay?
We do not currently have autopay for our Data Services accounts. However, while most Data Services accounts are billing monthly by default, we can adjust your payment frequency (i.e. to annual payments, semi-annual, quarterly, etc.) associated with your account.

If you would like to change your payment frequency, please contact us and let us know.

Q. How do I check the status of an IDX request?
Contact us at ds@rmls.com and we will inform you on how the approval process is proceeding.

Prospective Data Recipients

Q. How do I obtain access to MLS data?
You must be working with a current RMLS subscriber. You will be required to sign a Listing Content Licensing Agreement (LCLA). Once the LCLA is complete, you will be provided with information to access our API. Click here for a step-by-step overview of the data license application process.

Q. How do you provide data?
We provide access to MLS data via our application programming interface (“API”).

Q. Who can access the API?
Third-party companies/vendors who are currently working with an RMLS subscriber. Brokers and agents (under the supervision of their broker) who have the technical capability to access data via our API.
Q. What types of data feeds do you provide?
We have “standard” data feeds that we can provide for common products, such as an IDX feed, VOW feed, and a full feed. However, we also tailor data feeds to specific products as needed.
Q. How can I use the MLS data?

Your use of MLS data must be exclusively for developing and providing a product[s] to a broker, agent, and/or appraiser that is a member of RMLS.

To avoid any confusion, your licensing agreement will contain a Product Description section, which serves as our mutual understanding of how you are authorized to use the MLS data.

Unless explicitly stated in your license agreement, you cannot use MLS data for your own internal business purposes or for any other purposes except as provided for in the Product Description section of your licensing agreement.Unless explicitly stated in your license agreement, you cannot use MLS data for your own internal business purposes or for any other purposes except as provided for in the Product Description section of your licensing agreement.

Q. What types of products do you license data for?

We license data for a variety of real estate products. Uncommon or unique data access requests are considered on a request-by-request basis.

Some examples of products for which we license data include, but are not limited to:

  • Internet Data Exchange (IDX) listing search websites, mobile applications, and/or audio devices
    Customer Relationship Management (CRM) products
    Statistical and internal analytics tools
    Virtual Office Websites (VOWs)
    Comparative Market Analysis (CMA) products
    Print and digital listing marketing materials
    Listing syndication (i.e., third-party listing search websites)
Q. What is IDX?
The Internet Data Exchange, more commonly referred to as “IDX,” is a National Association of REALTORS® (NAR) approved program or policy in which brokers and agents (with permission from their brokers) are permitted to display limited information about other brokers’ listings on their business websites, mobile applications, or audio devices. IDX websites, mobile applications, or audio devices are commonly referred to collectively as “IDX Products.”

In common terms, IDX essentially allows brokers and agents to have search features on their business websites, mobile apps, or audio devices that allow consumers to search for on-market MLS listings which are listed with that broker or agent’s brokerage, as well as on-market MLS listings that are listed with other brokerages that participate in the same MLS.

Q. What are IDX Products?
IDX Products refers to broker and agent business websites, mobile applications, and/or audio devices that have search features which enable consumers to search for on-market MLS listings.
Q. What is an IDX feed?
There are many different types or permission levels of API data access, which are enabled/disabled based on the product for which a data license is granted. An IDX feed is simply a reference to one specific type of API data access that is issued in cases where a vendor or broker is developing an IDX product (i.e., a business website, mobile app, or audio device tool which allows consumers to search for listings).
Q. What type of listings are included in an IDX feed?
IDX feeds typically include on-market status listings, as well as sold status listings in some states. Our IDX feed includes listings in the ACT, BMP, and SLD statuses.
Q. What is an approved IDX vendor?
An “approved IDX vendor” refers to a third-party company/vendor that has a licensing agreement with RMLS that allows the vendor to provide IDX Products to brokers and agents who are members of RMLS.
Q. What is a VOW?
A Virtual Office Website, more commonly referred to as a “VOW” is a broker’s business website or a feature of a brokers’ business website through which the broker can provide real estate brokerages services to consumers with whom the broker has first established a broker-consumer relationship (as defined by state law). The VOW program or policy is also approved and governed by the National Association of REALTORS® (“NAR”) policies.
Q. What is the difference between IDX and VOW?
One of the main differences is that IDX websites do not require a consumer to first establish a broker-consumer relationship before the consumer can search for listings on the website. Consumers do not typically have to register to search for listings on IDX websites. On the other hand, consumers using VOW websites are required to register with the broker, establish a broker-consumer relationship (as defined by state law), agree to the brokers’ VOW terms of use, etc., before they can search for listings on a VOW website.
Q. Do you charge fees for data access?
Yes, in most cases your access to a data license from RMLS will require you to pay a monthly recurring licensing fee, as stated in your licensing agreement.
Q. Are you RESO certified?
Yes, RMLS is RESO Data Dictionary 1.7 and Web API Server Core 2.0.0 certified.
Q. Is your API RESO certified?
Yes, RMLS Data Dictionary 1.7 and Web API Server Core 2.0.0 certified.
Q. Is there a long-term commitment when signing a licensing agreement?
No, our standard licensing agreement allows you to terminate the agreement for any reason by providing 30 days’ notice.
Q. Where can I obtain a licensing agreement or a sample licensing agreement?

You will be sent a licensing agreement after you register for an account and provide all the information we need for the agreement. We do not provide a sample licensing agreement online. Click here for a step-by-step overview of the data license application process.

Q. If I'm an agent working with a software company or an independent developer, does that company or does my developer need to sign a licensing agreement?
Yes, the company or individual who will be accessing the API is required to sign a licensing agreement with RMLS. We require the company or individual who is actually accessing the data to obtain a licensing agreement with RMLS because that agreement governs access to the data and makes the company or individual responsible for abiding by the licensing agreement terms and MLS rules when accessing the data.

API Specs and Documentation

Overview

Introduction

RMLS web API (Application Programming Interface) is a RESO certified RESTful API built on OData v4.0. The API is both RESO web API Certified and RESO Data Dictionary Certified.

What is a REST API?

REST stand for Representational State Transfer. This is an architectural pattern describing how distributed systems can expose a consistent interface. When the term is used, it generally refers to an API accessed via HTTP protocol at a predefined set of URLs.

These URLs represent various resources – any information or content accessed at that location, which can be returned as JSON, HTML, audio files, or images. Often, resources have one or more methods that can be performed on them over HTTP, like GET, POST, PUT and DELETE.

Authentication

RMLS web API supports OpenID and OAuth2 authorization/authentication protocols, and as part of previous web API certifications, is OpenID certified. Our API supports several grant types, however, we simplify the authentication process by providing a Bearer Token to our vendors.

To access the API, simply pass your bearer token under the Authorization header:

https://resoapi.rmlsweb.com/reso/odata

GET /reso/odata/$metadata HTTP/1.1
Host: https://resoapi.rmlsweb.com
Authorization: YourBearerToken

Response:
{

“@odata.context”: “https://resoapi.resoapi.rmlsweb.com/reso/odata/$metadata”,
“value”: [

{

“name”: “Property”,
“url”: https://resoapi.rmlsweb.com/reso/odata/Property”

},
{

“name”: “Member”,
“url”: “https://resoapi.rmlsweb.com/reso/odata/Member”

},
{

“name”: “Office”,
“url”: https://resoapi.rmlsweb.com/reso/odata/Office”

},
{

“name”: “OpenHouse”,
“url”: “https://resoapi.rmlsweb.com /reso/odata/OpenHouse”

},
{

“name”: “Media”,
“url”: “https://resoapi.rmlsweb.com /reso/odata/Media”

},
{

“name”: “DataSystem”,
“url”: “https://resoapi.rmlsweb.com /reso/odata/DataSystem”

},
{

“name”: “Resource”,
“url”: “https://resoapi.rmlsweb.com /reso/odata/Resource”

},
{

“name”: “PropertyGreenVerification”,
“url”: “https://resoapi.rmlsweb.com /reso/odata/PropertyGreenVerification”

},
{

“name”: “PropertyUnitTypes”,
“url”: “https://resoapi.rmlsweb.com /reso/odata/PropertyUnitTypes”

},
{

“name”: “HistoryTransactional”,
“url”: https://resoapi.rmlsweb.com /reso/odata/HistoryTransactional”

}

]

}

https://resoapi.rmlsweb.com/reso/odata is the Web API’s Odata endpoint. See the next section, Odata Endpoints for more information on pulling data through resource endpoints.

Web API Odata Endpoints

Odata Endpoints

RMLSweb API is built on OData v4.0. Web API resources can be queried through the Odata endpoints accessible to the vendor.

Service Document

The web API exposes two endpoints that a vendor can use to get information about the resources and fields available to them.

The Odata Service Document endpoint shows all resources that are available to the vendor.

https://resoapi.rmlsweb.com/reso/odata

GET /reso/odata HTTP/1.1
Host: https://resoapi.rmlsweb.com
Authorization: YourBearerToken

Response:

{

"@odata.context": "https://resoapi.rmlsweb.com/reso/odata/$metadata",
"value": [

{

"name": "Property",
"url": "https://resoapi.rmlsweb.com/reso/odata/Property"

},
{

"name": "Member",
"url": "https://resoapi.rmlsweb.com/reso/odata/Member"

},
{

"name": "Office",
"url": "https://resoapi.rmlsweb.com/reso/odata/Office"

},
{

"name": "OpenHouse",
"url": "https://resoapi.rmlsweb.com /reso/odata/OpenHouse"

},
{

"name": “Media”,
"url": "https://resoapi.rmlsweb.com /reso/odata/Media"

},
{

"name": “DataSystem”,
"url": "https://resoapi.rmlsweb.com /reso/odata/DataSystem"

},
{

"name": “Resource”,
"url": "https://resoapi.rmlsweb.com /reso/odata/Resource"

},
{

"name": "PropertyGreenVerification",
"url": "https://resoapi.rmlsweb.com /reso/odata/PropertyGreenVerification"

}

]

}

Metadata

The Odata Metadata endpoint shows all resources, fields, enumerations and entity relationships available to the vendor.

https://resoapi.rmlsweb.com/reso/odata/$metadata

GET /reso/odata/$metadata HTTP/1.1
Host: https://resoapi.rmlsweb.com
Authorization: YourBearerToken

Response:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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="Default">
            <EntityContainer Name="Container">
                <EntitySet EntityType="Odata.Models.Property" Name="Property">
                    <NavigationPropertyBinding Path="Media" Target="Media"/>
                    <NavigationPropertyBinding Path="Member" Target="Member"/>
                    <NavigationPropertyBinding Path="Office" Target="Office"/>
                    <NavigationPropertyBinding Path="OpenHouse" Target="OpenHouse"/>
                    <NavigationPropertyBinding Path="PropertyGreenVerification" Target="PropertyGreenVerification"/>
                    <NavigationPropertyBinding Path="PropertyUnitTypes" Target="PropertyUnitTypes"/>
                </EntitySet>
                <EntitySet EntityType="Odata.Models.Member" Name="Member">
                    <NavigationPropertyBinding Path="Property" Target="Property"/>
                    <NavigationPropertyBinding Path="Office" Target="Office"/>
                </EntitySet>
                <EntitySet EntityType="Odata.Models.Office" Name="Office">
                    <NavigationPropertyBinding Path="Property" Target="Property"/>
                    <NavigationPropertyBinding Path="Member" Target="Member"/>
                </EntitySet>
                <EntitySet EntityType="Odata.Models.OpenHouse" Name="OpenHouse">
                    <NavigationPropertyBinding Path="Property" Target="Property"/>
                </EntitySet>
                <EntitySet EntityType="Odata.Models.Media" Name="Media">
                    <NavigationPropertyBinding Path="Property" Target="Property"/>
                </EntitySet>
                <EntitySet EntityType="Odata.Models.DataSystem" Name="DataSystem"/>
                <EntitySet EntityType="Odata.Models.Resource" Name="Resource"/>
                <EntitySet EntityType="Odata.Models.PropertyGreenVerification" Name="PropertyGreenVerification"/>
                <EntitySet EntityType="Odata.Models.PropertyUnitTypes" Name="PropertyUnitTypes"/>
            </EntityContainer>
        </Schema>

        ..........

        <EnumType IsFlags="false" Name="StandardStatus" UnderlyingType="Edm.Int32">
            <Member Name="Active" Value="1"/>
            <Member Name="ActiveUnderContract" Value="2"/>
                <Annotation String="Active Under Contract" Term="RESO.OData.Metadata.StandardName"/>
            </Member>
            <Member Name="Canceled" Value="3"/>
            <Member Name="Closed" Value="4"/>
            <Member Name="ComingSoon" Value="5"/>
                <Annotation String="Coming Soon" Term="RESO.OData.Metadata.StandardName"/>
            </Member>
            <Member Name="Expired" Value="6"/>
            <Member Name="Pending" Value="7"/>
            <Member Name="Withdrawn" Value="8">
        </EnumType>

        ..........

        <EntityType Name="Property">
            <Key>
                <PropertyRef Name="ListingKey"/>
            </Key>
            <Property Name="AccessibilityFeatures"Type="OdataModels.AccessibilityFeatures"/>
            <Property MaxLength="1" Name="AccessibilityYN" Type="Edm.Boolean"/>
            <Property MaxLength="255" Name="AdditionalParcelsDescription" Type="Edm.String"/>
            <Property MaxLength="1" Name="AdditionalParcelsYN" Type="Edm.Boolean"/>
            <Property MaxLength="4" Name="Amps" Type="Edm.String"/>
            <Property Name="Appliance" Type="Odata.Models.Appliances"/>

        ..........

Resource Endpoints

The web API will expose an endpoint for each resource available to the vendor. Each of these endpoints can be searched, filtered and sorted using Odata’s system query options.

  • https://resoapi.rmlsweb.com/reso/odata/Property
  • https://resoapi.rmlsweb.com/reso/odata/Member
  • https://resoapi.rmlsweb.com/reso/odata/Office
  • https://resoapi.rmlsweb.com/reso/odata/OpenHouse
  • https://resoapi.rmlsweb.com/reso/odata/Media
  • https://resoapi.rmlsweb.com/reso/odata/PropertyGreenVerification”>https://resoapi.rmlsweb.com/reso/odata/PropertyGreenVerificatio
  • https://resoapi.rmlsweb.com/reso/odata/Deleted”>https://resoapi.rmlsweb.com/reso/odata/Deleted
  • https://resoapi.rmlsweb.com/reso/odata/Resource”>https://resoapi.rmlsweb.com/reso/odata/Resource
  • https://resoapi.rmlsweb.com/reso/odata/DataSystem

To get the most recent data from an endpoint, use the query option $orderby and the ModificationTimestamp field in descending order.

For example, to get the most recent listings query the Property resource.

https://resoapi.rmlsweb.com/reso/odata/Property?$orderby=ModificationTimestamp desc

GET /reso/odata/Property?$orderby=ModificationTimestamp%20desc HTTP/1.1
Host: https://resoapi.rmlsweb.com
Authorization: YourBearerToken
{
    "@odata.context": "$metadata#Property",
    "value": [
        {
            "@odata.id": "Property(1611952)",
            "ListingKeyNumeric": 1611952,
            "RoomsTotal": 17,
            "ListPrice": 2950000.0,
            "ModificationTimestamp": "2019-10-03T03:04:24-07:00"
            .........
Note: White spaces need to be encoded as ‘%20’ or ‘+’ if the client application (e.g. Postman) you use to call the API does not do it for you.

So,

‘$orderby=ModificationTimestamp desc’

becomes

‘$orderby=ModificationTimestamp%20desc’

See the next section, Odata Query Options for examples of pulling, filtering, and sorting data.

Query Options

$select

The $select query option can be used to request specific fields in the results set.

https://dev-resoapi.rmlsweb.com/reso/odata/Property?$select=ListingKey,ListPrice,YearBuilt

GET /reso/odata/Property?$select=ListingKey,ListPrice,YearBuilt HTTP/1.1
Host: https://resoapi.rmlsweb.com
Authorization: YourBearerToken

Response:
{
    "@odata.context": "$metadata#Property(ListPrice,YearBuilt,ListingKey)",
    "value": [
        {
            "ListPrice": 320000.0,
            "ListingKey": "10",
            "YearBuilt": 1999
        },
        {
             "ListPrice": 425000.,
            "ListingKey": "100",
            "YearBuilt": 1910
        },
        {
            "ListPrice": 65000.0,
            "ListingKey": "1000",
            "YearBuilt": 1946"
        },
        ..........

Note: When specifying a value for an enumerated type, you must include the fully qualified name of the enumerated value.

Example:
The entry $filter=StandardStatus+eq+’Active’ will fail with a 400 status code.

{

  “error”: {

    “code”: 400,

    “message”: “Expected token ‘EnumValue’ not found.”

  }

}

It must be entered as, $filter=StandardStatus+eq+Odata.Models.StandardStatus’Active’
to succeed.

$filter

Each resource can be filtered on various fields and data types using the $filter query option.

Properties with more than 3 bedrooms (Number):
https://resoapi.rmlsweb.com/reso/odata/Property?$filter=BedroomsTotal gt 3

Properties in the price range 300,000 – 500,000 (Decimal):

https://resoapi.rmlsweb.com/reso/odata/Property?$filter=ListPrice ge 300000 and ListPrice le 500000

GET /reso/odata/Property?$filter=ListPrice%20ge%20300000%20and%20ListPrice%20le%20500000 HTTP/1.1
Host: https://resoapi.rmlsweb.com
Authorization: YourBearerToken
Properties listed since a given date (Date):

https://resoapi.rmlsweb.com/reso/odata/Property?$filter=ListingContractDate gt 2018-01-01

GET /reso/odata/Property?$filter=ListingContractDate%20gt%202018-01-01 HTTP/1.1
Host: https://resoapi.rmlsweb.com
Authorization: YourBearerToken
Properties updated since a given date (Timestamp):

https://resoapi.rmlsweb.com/reso/odata/Property?$filter=ModificationTimestamp gt 2019-09-01T01:00:00-07:00

GET /reso/odata/Property?$filter=ModificationTimestamp%20gt% 2019-10-03T03:04:24-07:00 HTTP/1.1
Host: https://resoapi.rmlsweb.com
Authorization: YourBearerToken
Properties with Active status (Single Lookup):

https://resoapi.rmlsweb.com/reso/odata/Property?$filter=StandardStatus has Odata.Models.StandardStatus’Active’

GET /reso/odata/Property?$filter=StandardStatus%20has%20Odata.Models.StandardStatus’Active’ HTTP/1.1
Host: https://resoapi.rmlsweb.com
Authorization: YourBearerToken
Properties with certain exterior features ExteriorFeatures (Multi Lookup):

https://resoapi.rmlsweb.com/reso/odata/Property?$filter=ExteriorFeatures has Odata.Models.ExteriorFeatures’Patio’

GET /reso/odata/Property?$filter=ExteriorFeatures%20has%20Odata.Models.ExteriorFeatures’Patio’
Host: https://resoapi.rmlsweb.com
Authorization: YourBearerToken

$top, $skip and $orderby

The web API has a limit on how many records can be pulled at once. Currently, the limit is set to 250 records per request.

The $top, $skip, and $orderby query options can be used to offset the result set.

For example, to get the 600 most recent listings, make 3 requests using $top, $skip, and $order:

https://resoapi.rmlsweb.com/reso/odata/Property?$orderby=ModificationTimestamp desc&$top=200

https://resoapi.rmlsweb.com/reso/odata/Property?$orderby=ModificationTimestamp desc&$top=200&$skip=200

https://resoapi.rmlsweb.com/reso/odata/Property?$orderby=ModificationTimestamp desc&$top=200&$skip=400

GET /reso/odata/Property?$orderby=ModificationTimestamp%20desc&$top=200 HTTP/1.1
GET /reso/odata/Property?$orderby=ModificationTimestamp%20desc&$top=200&$skip=200 HTTP/1.1
GET /reso/odata/Property?$orderby=ModificationTimestamp%20desc&$top=200&$skip=400 HTTP/1.1
Host: https://resoapi.rmlsweb.com
Authorization: YourBearerToken

Using the $skip option to paginate over large data sets can be time consuming. Especially when ordering by a non numeric, or non indexed field. As the $skip value gets larger, query response time may slow down. If paginating through a large data set, it is advised to &orderby the primary key, or an indexed field. For example, if replicating the entire Property resource, ordering by ListingKeyNumeric would be the fastest. See the Replication section for more information.

$count

The total number of records for a given resource can be included in the result set by using the $count option.

https://resoapi.rmlsweb.com/reso/odata/Property?$count=true

GET /reso/odata/Property?$count=true HTTP/1.1
Host: https://resoapi.rmlsweb.com
Authorization: YourBearerToken
Response:

Response:

{
    "@odata.context": "$metadata#Property",
    "@odata.count": 1731072,
    "value": [
        {
        ..........

$expand

The web API can return related resources with each record using the $expand query option.

For example, to get all images for each property in addition to the data:

https://resoapi.rmlsweb.com/reso/odata/Property?$expand=Media

GET /reso/odata/Property?$expand=Media HTTP/1.1
Host: https://resoapi.rmlsweb.com
Authorization: YourBearerToken
Response:
"{
    "@odata.context": "$metadata#Property",
    value": [
        {
            "AccessibilityFeatures": null,
            "AccessibilityYN": null,
            ..........
            "Media": [
                {
                    "Classname": "Property",
                    "ImageOf": null                
                    "ListOfficeMlsld": "5PRU01",
                    "LongDescription": null,
                    "MainOfficeKeyNumeric": 101911,
                    "MediaCatagory": "Photo",
                    ..........

Additionally, you can specify a $select as a parameter to the Resource you are expanding to specify exactly what fields you need.

Example:

…/reso/odata/Property $expand=Media($select=MediaModificationTimestamp,MediaKeyNumeric,Order)&$top=1&$filter=PhotosExistYN+eq+true

 

The should only be on specified Media fields. See below for an example:

    ListAgentKeyNumeric: 41977,

      AttributionContact: null,

      Media: [

        {

          MediaKeyNumeric: 2,

          MediaModificationTimestamp: 2005-10-23T12:10:03-07:00,

          Order: 1

        }

      ]

    }

  ],

Replication

Pulling Data

To get started you will want to pull all records in the system. This can be done three different ways.

The easiest way to replicate would be to follow the ‘nextLink’ at the bottom of each result set. This link can be followed to get the next page of results. Continue following the ‘nextLink’ until it no longer appears, or the API no longer returns a result set.

For example, to replicate all Property records, make the initial request to the Property endoint.

https://resoapi.rmlsweb.com/reso/odata/Property

Next, save the results to your database and look for the ‘nextLink’

{
    "@odata.context": "$metadata#Property",
    "value": [ .... ],
    "@odata.nextLink": "https://resoapi.rmlsweb.com/reso/odata/Property?$skip=200"
}

Below is more technical information on replication of historical data.

The primary key for the Property resource is the ListingKeyNumeric attribute.

This happens to be a good key to construct queries that match smaller numbers of records which you can then iteratively call to download in 250 record “pages”.

Programmatically, this will look like a loop in a loop, where you match records by queries asking for listings in ranges based on ListingKeyNumeric, and then loop through the resulting set of listings using the @odata.nextLink attribute to download the pages.

Response:
{
   // Psuedo code to fetch all listings, first two digits in ListingKeyNumeric represent year of listing
//
// Adapt to programming language of your choice. This is expressed as a synchronous methodology.
//
LKNBlockSize = 10000;

for (LKNIndex = 0; LKNIndex < 23000000; LKNIndex += LKNBlockSize)
    fetchDataBlock(LKNIndex,LKNIndex+LKNBlockSize)
endfor

proc fetchDataBlock(beginRange, endRange)

    //odata query attributes, such as, $top – I would suggest not sorting or counting in this query
    queryOptions = ‘&$top=250’; 
    query = ‘https://resoapi.rmlsweb.com/reso/odata/Property?$filter=ListingKeyNumeric ge ‘+beginRange+’ and ListingKeyNumeric lt ‘endRange+’ ‘+queryOptions
    results = callAPI(query)
    storeData(results)
    while results.nextLink exists
        results = callAPI(results.nextLink)
        storeData(results)
    end
endproc

Photos

Getting photos with $expand

The easiest way to get the photos for each listing is to use the $expand query option to append all Media resources that match with each property.

For example, to get all images for each returned property.

https://resoapi.rmlsweb.com/reso/odata/Property?$expand=Media

GET /reso/odata/Property?$expand=Media HTTP/1.1
Host: https://resoapi.rmlsweb.com
Authorization: YourBearerToken

Open House Information

Getting open houses with $expand

The following example demonstrates how to query for listings with open houses. While illustrating the use of $expand to retrieve Open House information, it also demonstrates construction of a more complex query from available options. The query calls the Property resource. It requests the following actions:

  • Find listings within 3/4 mile of Gabriel Park (Ptld) that have an open house ($filter by Geolocation and OpenhouseYN)
  • Expand the OpenHouse resource per listing, returning only the OpenHouse fields OpenHouseDate, OpenHouseStartTime, OpenHouseEndTime and OpenHouseContact ($expand + $select)
  • Only return the Property resource fields ListingKeyNumeric and UnparsedAddress ($select)
  • Limit the number of records returned in the response to 10 ($top)
  • Report the total number of records that matched the search criteria, even though we only asked for the first 10 ($count)

https://resoapi.rmlsweb.com/reso/odata/Property?$expand=OpenHouse

GET /reso/odata/Property$filter=geo.distance(Geolocation,geography%27SRID=3956;POINT(-122.71980293614476+45.4729475266557)%27)+lt+3.0+and+OpenhouseYN+eq+true&$expand=OpenHouse($select=OpenHouseDate,OpenHouseStartTime,OpenHouseEndTime,OpenHouseContact)&$select=ListingKeyNumeric,UnparsedAddress&$top=10&$count=true
Host: https://resoapi.rmlsweb.com
Authorization: YourBearerToken
Response:
{
    "@odata.context": "$metadata#Property(ListingKeyNumeric,UnparsedAddress,OpenHouse(Directions,OpenHouseContact,OpenHouseContactPhone,OpenHouseDate,OpenHouseEndTime,OpenHouseStartTime))",
    "@odata.count": 2,
    "value": [
        {
            "@odata.id": "Property(22251752)",
            "ListingKeyNumeric": 22251752,
            "UnparsedAddress": "8121 SW 47TH AVE, Portland, OR 97219",
            "OpenHouse": [
                {
                    "@odata.id": "OpenHouse(1299951)",
                    "Directions": "SW Garden Home & 47th Ave",
                    "OpenHouseContact": "Susan Suzuki",
                    "OpenHouseContactPhone": "971-645-1505",
                    "OpenHouseDate": "2022-04-09",
                    "OpenHouseEndTime": "2022-04-09T14:00:00-07:00",
                    "OpenHouseStartTime": "2022-04-09T12:00:00-07:00"
                }
            ]
        },
        {
            "@odata.id": "Property(22289049)",
            "ListingKeyNumeric": 22289049,
            "UnparsedAddress": "3738 SW CULLEN BLVD, Portland, OR 97221",
            "OpenHouse": [
                {
                    "@odata.id": "OpenHouse(1299624)",
                    "Directions": "From Hwy 10 turn S on SW 42nd Ave. then E on SW Kanan Dr. then N on SW 39th Ave & E on SW Cullen.",
                    "OpenHouseContact": "Kathleen MacNaughton",
                    "OpenHouseContactPhone": "503-781-1492",
                    "OpenHouseDate": "2022-04-09",
                    "OpenHouseEndTime": "2022-04-09T15:00:00-07:00",
                    "OpenHouseStartTime": "2022-04-09T13:00:00-07:00"
                }
            ]
        }
    ]
}
GET https://resoapi.rmlsweb.com/reso/odata/Property?$top=10&$select=ListingKey,ModificationTimestamp,Latitude,Longitude&$count=true&$orderby=ModificationTimestamp%20desc&$filter=StandardStatus+eq+Odata.Models.StandardStatus%27Active%27+and+geo.distance(Geolocation,geography%27SRID=3956;POINT(-122.71980293614476%2045.4729475266557)%27)+lt+5

The example below is filtering on “StandardStatus” of ‘Active’ and Geolocation a polygon that is defined with longitude and latitude.

Note that this must be a closed polygon shape or you will get a 400 response error.

GET https://resoapi.rmlsweb.com/reso/odata/Property?$filter=StandardStatus+eq+Odata.Models.StandardStatus%27Active%27+and+geo.intersects(Geolocation,geography%27SRID=3956;POLYGON((-122.68989155694867%2045.52299854067543,-122.69827814363333%2045.523425010935206,-122.69638439825292%2045.51598501048422,-122.70429754859246%2045.50802264651724,-122.68204604037268%2045.502618972276196,-122.67568846659563%2045.51205136431443,-122.67257731347068%2045.51868627089389,-122.68705093887804%2045.52304592641949,-122.68989155694867%2045.52299854067543))%27)&$count=true

Proper URL Construction

Below are examples of proper URL construction.

Query by StandardStatus and ModificationTimestamp:

https://resoapi.rmlsweb.com/reso/odata/Property?$select=StandardStatus,ModificationTimestamp&$count=true&$filter=StandardStatus%20eq%20Odata.Models.StandardStatus%27Active%27%20and%20ModificationTimestamp%20ge%202021-08-30T07:17:45-07:00
https://resoapi.rmlsweb.com/reso/odata/Property?$select=StandardStatus,ModificationTimestamp&$count=true&$filter=(StandardStatus+eq+Odata.Models.StandardStatus%27Active%27+or+StandardStatus+eq+Odata.Models.StandardStatus%27Pending%27+or+StandardStatus+eq+Odata.Models.StandardStatus%27ActiveUnderContract%27)&$top=100
https://resoapi.rmlsweb.com/reso/odata/Property?$filter=PhotosChangeTimestamp+gt+2022-04-01T00:00:00.000-07:00&$expand=Media&$select=Media,PhotosChangeTimestamp&$top=100&$orderby=PhotosChangeTimestamp+desc
https://resoapi.rmlsweb.com/reso/odata/Property?$filter=PhotosChangeTimestamp%20gt%2022-04-01T00:00:00-07:00&$expand=Media($select=MediaURL,MediaKey)&$select=Media,PhotosChangeTimestamp&$top=100&$orderby=PhotosChangeTimestamp%20desc