SourceRE RESO Web API
Overview
SourceRE is a platform designed for real estate software vendors to access standardized data feeds. It enables vendors to purchase access to MLS data based on Plans defined by the MLS, which are provisioned for the vendor's specific Products. When a vendor purchases a Plan for one of their Products, they receive an API feed. Feeds are accessed via feed-specific JWT bearer tokens. Each token is active for 1 year, and a new token can be retrieved at any time by pressing "Copy Bearer Token" on the feed within the Data Marketplace.
Data access, structure, and enumerations are tailored per Plan. Every Feed reflects its Plan's specific metadata, field-level permissions, and record-level access rules, ensuring the MLS retains granular control over how its data is consumed.
MLS Data is available via the SourceRE RESO Web API, and it is standardized according to the RESO Data Dictionary. For more information about the RESO Web API specification, please visit the RESO Website. A guide to authenicating, querying, and replicating data from the SourceRE RESO Web API is provided below.
Authentication
The JWT bearer token must be included in the
Authorization header for all API requests.
These tokens are long-lived and should be stored securely. Tokens are scoped to a specific Feed and can only access data from that feed.
Metadata & Lookups
SourceRE provides metadata discovery in accordance with the RESO Web API standard:
Service Endpoint
Describes the available entity types (resources) for the given feed.
Metadata Endpoint
Describes the available fields for each entity type, including navigation properties.
Enumeration fields in the metadata are typed as
Edm.String or Collection(Edm.String) and
include a RESO.OData.Metadata.LookupName annotation
identifying the Lookup name. For example, the
PropertyType field has the following annotation:
Lookup Endpoint
Returns enumeration values for fields annotated with
RESO.OData.Metadata.LookupName, according to the RESO
Web API specification.
Data Access and Structure
Endpoints
All entity types are exposed as OData resources at their corresponding endpoint:
These endpoints support OData query options as defined in the RESO Web API specification. Here is a brief overview of the available query options:
-
$expand- Expand related entities from another resource $filter- Filter records based on field values-
$orderby- Sort results by field values, ascending or descending -
$top- Limit results to a specific number of records -
$skip- Skip a specific number of records in the resulting set $count- Include count of resulting records-
$select- Select specific fields to include in the response
For example, here is a query to the Property resource which makes use of each query option:
This query will return 100 residential properties, sorting by the
APIModificationTimestamp field in descending order and skipping the
first 100 properties. The response will include an
@odata.count of resulting records, and each record will
include the APIModificationTimestamp and
PropertyType fields, as well as the
ListAgent navigation property.
Sub-Resources
Certain entity types are scoped to a single parent resource, and are
exposed as top-level resources with a prefix of the parent, in
addition to being available as navigation properties. For example,
individual rooms associated with a property are exposed as the
PropertyRooms resource, in addition to being available
as the Rooms navigation on the
Property resource:
Field & Record-Level Restrictions
Permissions are defined per Plan by the MLS and enforced automatically. This may include:
- Which fields are included
- Which records are visible
The MLS may also define display and usage restrictions for specific fields and entities. Clients must consult the MLS for display and usage guidelines.
Pagination & Filtering
Pagination
All endpoints support pagination via
@odata.nextLink. This is a URL returned in the response
that can be used to retrieve the next page of results. If any query
options are passed, such as $top or
$filter, they will be accounted for in the nextLink
URL.
If no $top value is passed, the default page size will be 10 records. The maximum value for $top is 1000, unless only the primary key of the resource is selected, in which case the maximum value is 100,000. For example:
Filtering
OData filters are supported on all fields. The operators available may differ based on the field type. Here are some examples:
With bounds:
Updated Records
The ModificationTimestamp indicates the time in UTC at which the record was last updated in the MLS source system. The APIModificationTimestamp indicates the time in UTC at which the record was last updated in SourceRE.
Deleted Records
Deleted records appear for 48 hours after deletion with:
Updates to the DeletionTimestamp will also coincide with updates to the APIModificationTimestamp field. If a client stops pulling records for 48 hours or longer, they must reconcile deletions for a resource using the following process:
- Pull all primary keys for the resource
- Compare against the primary keys in their local system
- Purge records from their local system whose keys are no longer found in SourceRE
Replication
Initial Bulk Load
Clients must replicate feed data locally. SourceRE recommends the following strategy for each parent resource you wish to replicate:
- Request data using the resource endpoint, including any $filter and $select options you wish to use, as well as $expand for any sub-resources you wish to replicate (e.g. $expand=Rooms).
-
Follow
@odata.nextLinkuntil it no longer appears in the response. - If interrupted, restart replication from the beginning.
Ongoing Updates
After replicating the entire dataset as required, poll for
new/updated records using
APIModificationTimestamp filters. Start with the newest
APIModificationTimestamp value you have in your local system, and
continue pulling until you have caught up to the current
APIModificationTimestamp value in SourceRE. We recommend a filter
window of no larger than 1 hour. For example:
Pull metadata and lookup updates no more than once per day. We recommend refreshing other data at least once per hour. Within SourceRE, data updates will occur in 10-minute intervals.
Media
The Media resource contains a MediaURL pointing to
hosted images and documents. Media can be replicated as a top level
resource and as a navigation property on several resources,
including: Property, Office, Member, Team, and OpenHouse.
Important: For photos and documents, do not hotlink MediaURLs in production. Always replicate these media types to your own servers.
Rate Limits
Unless otherwise noted, the following rate limits apply per Feed:
- No concurrent requests
- Max 3 requests per second
- Max 5,000 requests per hour
Violations result in HTTP 429 responses.
Postman Library
A Postman library is available at this link: SourceRE Postman Library
It contains examples of how to retrieve metadata, lookup values, and data from the SourceRE RESO Web API.
For questions pertaining to the API, contact: support@sourceredb.com. For any other inquiries, please reach out to the MLS.
ARELLO API via SourceRE
Last Revision: 10/26/2025
Table of Contents
- Introduction
- Quick Start Instructions
- Search API Details
- Interface
- Formatting the Request
- How Searches Are Performed
- Search Signals
- Search Parameters
- Reading the Response
- Warnings and Errors
- Rate Limits
- Testing Environment
- Jurisdiction Participation and License Format Information
- Contact Us
Introduction
The ARELLO API (formerly known as the Licensee Verification Web Service) allows clients to obtain real estate licensee information in an automated fashion via a single HTTP request. When supplied with a practitioner's jurisdiction, license number, last name and first name in an HTTP POST request, the service returns matching records with a score indicating the degree to which each result matched the parameters.
As of October 27, 2025, this service is provided via SourceRE, and is available upon purchasing any ARELLO API data Feed within the SourceRE Data Marketplace. Users of the previous version of the service, provided by ARELLO, will need to update their implementation to use the new service.
SourceRE offers two different Plans for ARELLO data Feeds:
- Search - This Plan provides access to the standard "Search" API, which functions virtually identically to the previous service, with the exception of the endpoint URL and the authentication method. Whereas the previous service required a username and password, the new service requires a JWT bearer token. More information about the authentication method and Search functionality is provided below.
- Enhanced (Coming Soon) - This plan allows for RESTful access to License, Jurisdiction, and Disciplinary Action data, via the SourceRE RESO Web API. Purchasers of this Plan have full access to the Search API as well. Full information about the Enhanced Plan will be provided upon release.
Both of these Plans are priced on a per-jurisdication model, meaning that the cost of the Feed is based on the number of jurisdictions you wish to access data for. You may add/remove jurisdictions to your Feed at any time. At least one jurisdiction is required for an Active Feed.
Quick Start Instructions for the Search API
- Step 1: Read and become familiar with this documentation.
- Step 2: Purchase an ARELLO data Feed within the SourceRE Data Marketplace.
- Step 3: Connect to the testing API, and use it to develop your application and ensure it's functioning as intended.
- Step 4: Once you've developed and tested your application and you're ready to go live, update your implementation to use the live API, and you're off!
Note: The RESO Web API, which is available for purchasers of the "Enhanced" Plan, does NOT have a testing environment.
Search API Details
Interface
The ARELLO Search API expects an HTTP POST request with URL-encoded form parameters. The service returns results in JSON format. TLS encryption is required.
The web service endpoint URL is:
https://api.sourceredb.com/Search. The same URL is used
for live and testing environments; use the "searchMode" parameter to
switch.
Formatting the Request
The web service expects to receive an HTTP POST request with URL-encoded form parameters. This is a standard POST request just like you'd make through a web browser. This type of request is supported by HTTP libraries in all major programming languages.
The JWT Bearer Token for your ARELLO data Feed must be included in the Authorization header. This token may be copied from your Feed card within the Data Marketplace. The token replaces the username and password which were used in the previous version of the service and are no longer required.
Example request:
Host: api.sourceredb.com
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer <your_token>
jurisdiction=AL&licenseNumber=12345&lastName=doe&firstName=johnny
The following parameters are accepted in the request body as URL-encoded form fields:
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
| jurisdiction | String | Yes | Two-letter postal abbreviation of the jurisdiction in which to search. | |
| licenseNumber | String | No* | License number to search for. | |
| lastName | String | No* | Last name to search for. | |
| firstName | String | No | First name to search for. | |
| minScore | Numeric (0-100) | No | 0 | Lowest acceptable score for results (inclusive). Results with a score less than this value will not be returned. |
| maxResults | Numeric (1-100) | No | 10 | Maximum number of results to return. |
| searchMode | String | No | live | Whether to conduct the search in the live or test environment. (Valid values are "live" or "test".) |
* one of licenseNumber OR lastName is required
How Searches Are Performed
In order to get the best and most reliable results from the Licensee Verification Web Service, it is important to understand how the web service searches the database. Understanding the search routine will help you to know what data to provide, what is most important and what is least important in getting meaningful results.
Search Signals
In order to provide the best matches possible, we calculate and compare a variety of search signals in addition to searching for exact matches. This means that an exact match to licensee data is not required to get meaningful results.
- License number numeric reduction – we maintain license number formatting information for all participating jurisdictions, and we use that information to calculate a numeric reduction of the license number for comparison. For example, some jurisdictions use character prefixes (REB. 12345) and some use leading zeroes (0012345). The numeric reduction of both examples is 12345. When you search and provide a license number parameter, the value you provide is numerically reduced and compared to this signal.
- Soundex pattern matching – names are often misspelled, or spelling is inferred from phonetics. Soundex is a method of encoding the phonetic form of a name for comparison. For example, while McAlister and McCallister are spelled differently, their Soundex encoding is identical.
- Alternate names – often, people choose to be called by less formal versions of their first name, but on official records the more formal version is used. We maintain a database of alternate names which are used in the search. For example, if you search for Bill Jones, we also search for alternate first names like Will and William.
Search Parameters
Searches can only be performed on data that you provide. If you omit any of the search parameters, the likelihood of erroneous results increases. It is to your advantage to provide all the search parameters. For each parameter you provide, one of the signals must match in order for a result to be returned.
- For License Number, there must be an exact match or numeric reduction match
- For Last Name, there must be an exact match or Soundex match
- For First Name, there must be an exact match, alternate name match, or Soundex match
If you provide multiple parameters, all parameters must return a match for a result to be included. Think "AND" logic as opposed to "OR."
After the search results are selected from the database, they are assigned a score based on the quality of the match. The maximum possible score is 100, if all 3 search parameters return an exact match. White space is ignored for exact matches ("Aaron" is an exact match of "Aaron ").
| Parameter | Match Type | Score |
|---|---|---|
| License Number | Exact | 40 |
| Numeric Reduction | 30 | |
| Last Name | Exact | 40 |
| Soundex | 20 | |
| First Name | Exact | 20 |
| Alternate Name | 15 | |
| Soundex | 10 |
Note that it is to your advantage to provide all the search parameters when searching. If a parameter is not included in the request, the score for the parameter is automatically 0. For example, if you don't include a first name, the maximum possible score you can get is 80 (License Number exact + Last Name exact).
Reading the Response
The response from the web service is a JSON structure with 4 top-level keys:
- "request" (struct) - The request information that produced the response.
- "results" (array of struct) - The results of the search.
- "warnings" (array of string) - Any warnings that may have occurred.
- "errors" (array of struct) - Any errors that may have occurred.
The response is formatted as follows:
"request": {
...Request parameters...
},
"warnings": [ ...Warning messages... ],
"errors": [ ...Error messages... ],
"results": [
{
...License record data...
}
}
In the payload of the response, "results" is an array of structs with the following keys:
| Property | Type | Description |
|---|---|---|
| addrLine1 | String | Licensee's Office address - line 1. |
| addrLine2 | String | Licensee's Office address - line 2. |
| city | String | Licensee's Office address - city. |
| country | String | Licensee's Office address - 3-letter country code |
| String | Licensee's email address. | |
| fax | String | Licensee's fax number. |
| firstName | String | First name of the licensee. |
| jurisdiction | String | Two-letter postal abbreviation of the jurisdiction in which the licensee is registered. |
| lastName | String | Last name of the licensee. |
| licenseExpirationDate | Date | Expiration date of the license, formatted as yyyy-mm-dd. |
| licenseIssueDate | Date | Issue date of the license, formatted as yyyy-mm-dd. |
| licenseNumber | String | License number of the licensee. |
| licenseStatus | String | License status of the licensee. Values differ among jurisdictions. |
| licenseType | String | Licensee's license type. Values differ among jurisdictions. |
| middleName | String | Middle name of the licensee. |
| officeName | String | Licensee's office name. |
| postalCode | String | Office address - postal code. |
| score | Numeric | The result's score (see Search Parameters for possible scores). |
| stateProv | String | Office address - state/province. |
| suffix | String | Suffix of the licensee (such as "Jr" or "Sr") |
| telephone | String | Licensee's telephone number. |
Warnings and Errors
The web service may produce warnings and errors if it encounters a problem with a request.
In cases where the issue is minor, the web service may be able to recover and still produce a usable result. These are called "warnings." A warning indicates that something went wrong while processing the request, but the service was able to correct the problem and still produce results. Examples of events that produce warnings include:
- Failure to provide optional parameters (the warning indicates the default value used).
- Providing a minScore or maxResults value that is out of range.
In the case of warnings, the service simply corrects the erroneous value to an acceptable value, and continues to perform the search. Searches that produce warnings will still return results, and therefore they are logged to the database, just like a normal search.
The "warnings" key in the response is an array of strings. Each string is a human-readable warning message.
In other cases, the service may be unable to process a request and produce usable results. These are called errors. An error indicates that the service could not continue executing. Examples of events that produce errors include:
- Failing to provide required search parameters, like "jurisdiction" and "lastName"
- Providing an incorrect jurisdiction abbreviation
- Searching within a jurisdiction that does not participate in the program
- Searching in "live" mode when your account is only enabled for "test" mode
- Performing too many requests in a short amount of time (see "Rate Limits" for more information)
- Searching using a disabled or expired account.
The "errors" key in the response is an array of structs:
| Property | Type | Description |
|---|---|---|
| error | String | The error code generated by the web service. |
| message | String | A human-readable message with information about what caused the error (and possibly how to fix it). |
| type | String | Always "Fatal" |
Multiple warnings may be present in the response. No more than one "Fatal" error will exist.
Testing Environment
When developing your application to interface with the Search API, we provide a testing API with some known records to search for.
The testing database is comprised of a random 1% of the records from the live database. There are also several records of bogus data that can be used for assuring that the web service returns expected results.
| First | MI | Last | Lic. # | City | Juris. | Type | Status |
|---|---|---|---|---|---|---|---|
| JOHN | Q | DOE | 000012345 | Montgomery | AL | T | A |
| WILLIAM | R | JONES | 0099487 | Anchorage | AK | BROKER | ACTIVE |
| MARY | V | RICHARDSON | 0089487 | Juneau | AK | BROKER | ACTIVE |
Users can enter any of the above as is and get a score of 100. One can also obtain different confidences by using specifically formatted requests.
- Searching for license number "12345" in AL gives one result with a score of 30 (license number numeric reduction).
- Searching for license number "000012345" and last name "doe" in AL gives a score of 80 (exact license number and last name).
- Searching for first name = "bill" and last name = "jones" in AK gives one result with a score of 55 (exact last name and alternate first name).
- Searching for first name = "marie" and last name = "richardson" in AK gives one result with a score of 50 (exact last name and Soundex first name).
Rate Limits & Tokens
Unless otherwise noted, the following rate limits apply per Feed:
- No concurrent requests
- Max 3 requests per second
- Max 5,000 requests per hour
Violations result in HTTP 429 responses.
The Rate Limits do not apply to the JWT Bearer Token, but to your Feed. Every time you press "Copy Bearer Token" on the Feed within the Data Marketplace, a new token is generated. This does not invalidate previous tokens. Every token is valid for 1 year.
Jurisdiction Participation and License Format Information
ARELLO is constantly working with its jurisdictions to get the latest information as frequently as possible, but unfortunately, there still is not 100% participation. Some jurisdictions are unable to participate for legal reasons, and some are simply not ARELLO members.
Additionally, jurisdictions which do participate have varying license number formats, and it can be difficult to get an exact match without knowing something about the format before conducting a search. To help you perform better searches, ARELLO provides information about jurisdiction participation, update frequency and license number format in several formats which you can access and use in your client application.
Endpoints and available formats:
-
JSON:
https://www.arello.com/api/participants.cfm?format=json -
XML:
https://www.arello.com/api/participants.cfm?format=xml -
CSV:
https://www.arello.com/api/participants.cfm?format=csv
These resources include the following information for each jurisdiction:
| Property | Type | Description |
|---|---|---|
| JurisdictName | String | The full name of the jurisdiction. |
| Country | String | Country abbreviation. |
| IsParticipant | Boolean | Whether the jurisdiction participates in the program. This field is manually set by ARELLO staff. |
| Status | String | "Active" or "Inactive". Jurisdictions become Inactive if no data is received from them in over 6 months. |
| SubmissionInterval | String | "Daily", "Weekly", "Monthly", or "Intermittent". Value is set manually and may be approximate. |
| dtLastProcAction | Datetime | Timestamp of last processing action (last attempted data import). |
| CurrentProcStatus | String | "Success" or "Error" depending on the result of the last data processing action. |
| NumRecords | Integer | Total number of licensee records in the database for this jurisdiction. |
| LicNumFormat_Regex | String | A regular expression describing the expected license number format for this jurisdiction. Regular expressions can be used by software applications to validate user input. |
| LicNumFormat_Desc | String | A "human readable" description of the jurisdiction's license number format, which you may display to assist with data entry |
| LicNumFormat_PercentMatch | Float | A numeric value (0-100) indicating what percentage of license records for this jurisdiction matched the regular expression on file during the most recent data import. |
Contact Us
For any questions or assistance, please contact us at: support@sourceredb.com.
API DOCUMENTATION