MLS IDX API Code Samples
C# Code Sample
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="url" value="https://sample.mlsidxapi.com"/>
<add key="username" value="dZlzUztJweRsgMUoltwbPxLT"/>
<add key="password" value="ijOJxuiNglwsoXWhJQXINesm"/>
<add key="lastupdated" value="2026-04-07T21:05:17Z"/>
<add key="ids" value="814721,969035"/>
<add key ="PropPhotoId" value="95750714:1"/>
<add key ="AgentPhotoId" value="65883836:1"/>
<add key ="OfficePhotoId" value="814721:1"/>
</appSettings>
</configuration>
IdxApiExample.cs
using System.Net;
using System.IO;
using System.Xml;
using System;
using System.Configuration;
namespace CSharp
{
class DataFeedExample
{
private static HttpWebRequest httpWebRequest;
private static CredentialCache requestCredentialCache = new CredentialCache();
private static string RetsUrl = ConfigurationManager.AppSettings["url"];
private static ICredentials requestCredentials = new NetworkCredential(ConfigurationManager.AppSettings["username"], ConfigurationManager.AppSettings["password"]);
private static CookieContainer cookieJar = new CookieContainer();
/// <summary>
/// 1. Login
/// 2. Search Properties by LastUpdated Query (This returns a list of properties that are new or updated)
/// 3. Search Properties by All to return a complete master list to validate against ex: (ID=*)
/// a. Delete Properties that are in your DB but not in the complete list
/// b. If the Property exists but the lastupdated is different call Search Property By ID ex: (ID=12039790,35227008)
/// 4. Logout
/// </summary>
public static void Main()
{
// STEP 1
LoginTransaction();
// STEP 2
Console.WriteLine("================================================================================");
Console.WriteLine("STEP 2: SEARCH LAST UPDATED STARTING");
SearchTransaction("Property", "Property", "DMQL2", "(LastUpdated=" + ConfigurationManager.AppSettings["lastupdated"] + ")");
Console.WriteLine("SEARCH LAST UPDATED COMPLETED");
Console.WriteLine(string.Empty);
// STEP 3
Console.WriteLine("================================================================================");
Console.WriteLine("STEP 3: SEARCH MASTER LIST STARTING");
SearchTransaction("Property", "Property", "DMQL2", "(ID=*)");
Console.WriteLine("SEARCH MASTER COMPLETED");
Console.WriteLine(string.Empty);
// STEP 3.a
Console.WriteLine("================================================================================");
Console.WriteLine("STEP 3.a: DELETE PROPERTIES THAT ARE IN YOUR DB, BUT NO LONGER IN THE MASTER LIST");
Console.WriteLine("================================================================================");
Console.WriteLine(string.Empty);
// STEP 3.b
Console.WriteLine("================================================================================");
Console.WriteLine("STEP 3.b: If the Property exists but the lastupdated is different call Search Property By ID ex: (ID=123456,789012)");
SearchTransaction("Property", "Property", "DMQL2", "(ID=" + ConfigurationManager.AppSettings["ids"] + ")");
Console.WriteLine("================================================================================");
Console.WriteLine(string.Empty);
// STEP 4
Console.WriteLine("================================================================================");
Console.WriteLine("STEP 4: GET OBJECT STARTING");
GetObject("Property", ConfigurationManager.AppSettings["PropPhotoId"], "Thumbnail");
GetObject("Agent", ConfigurationManager.AppSettings["AgentPhotoId"], "Large");
GetObject("Office", ConfigurationManager.AppSettings["OfficePhotoId"], "Thumbnail");
Console.WriteLine("GET OBJECT COMPLETED");
Console.WriteLine("================================================================================");
Console.WriteLine(String.Empty);
// STEP 5
LogoutTransaction();
Console.ReadLine();
}
/// <summary>
/// You must issue a login request prior to proceeding with any other request.
/// The Login transaction verifies all login information provided by the user and begins a RETS session.
/// Subsequent session control may be mediated by HTTP cookies or any other method, though clients are
/// required to support at least session control via HTTP cookies.
/// </summary>
/// <remarks>Service End Point - /Login.svc/Login</remarks>
public static void LoginTransaction()
{
string service = RetsUrl + "/Login.svc/Login";
CookieContainer loginCookie = new CookieContainer();
httpWebRequest = (HttpWebRequest)WebRequest.Create(service);
httpWebRequest.CookieContainer = loginCookie;
httpWebRequest.Credentials = requestCredentials;
try
{
using (HttpWebResponse httpResponse = httpWebRequest.GetResponse() as HttpWebResponse)
{
Stream stream = httpResponse.GetResponseStream();
// READ THE RESPONSE STREAM USING XMLTEXTREADER
XmlTextReader reader = new XmlTextReader(stream);
while (reader.Read())
{
if (reader.Name == "RETS")
{
if (reader.HasAttributes)
{
while (reader.MoveToNextAttribute())
{
if (reader.Name == "ReplyCode" & reader.Value == "0")
{
Console.WriteLine("================================================================================");
Console.WriteLine("STEP 1: VALID LOGIN REQUEST");
Console.WriteLine("================================================================================");
Console.WriteLine("{0}: {1}", reader.Name, reader.Value);
loginCookie.Add(httpResponse.Cookies);
cookieJar = loginCookie;
}
else
{
Console.WriteLine("{0}: {1}", reader.Name, reader.Value);
}
}
}
}
else if (reader.NodeType != XmlNodeType.XmlDeclaration & reader.HasValue)
{
Console.WriteLine("RETS-RESPONSE:");
Console.WriteLine("{0}", reader.Value);
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
/// <summary>
/// The Logout transaction terminates a session. Clients should send a Logout transaction at the end of every session.
/// </summary>
/// <remarks>Service End Point - /Logout.svc/Logout</remarks>
public static void LogoutTransaction()
{
string service = RetsUrl + "/Logout.svc/Logout";
httpWebRequest = (HttpWebRequest)WebRequest.Create(service);
httpWebRequest.CookieContainer = cookieJar;
httpWebRequest.Credentials = requestCredentials;
try
{
using (HttpWebResponse httpResponse = httpWebRequest.GetResponse() as HttpWebResponse)
{
Stream stream = httpResponse.GetResponseStream();
// READ THE RESPONSE STREAM USING XMLTEXTREADER
XmlTextReader reader = new XmlTextReader(stream);
while (reader.Read())
{
if (reader.Name == "RETS")
{
if (reader.HasAttributes)
{
while (reader.MoveToNextAttribute())
{
if (reader.Name == "ReplyCode" & reader.Value == "0")
{
Console.WriteLine("================================================================================");
Console.WriteLine("STEP 4: VALID LOGOUT REQUEST");
Console.WriteLine("================================================================================");
Console.WriteLine("{0}: {1}", reader.Name, reader.Value);
}
else
{
Console.WriteLine("{0}: {1}", reader.Name, reader.Value);
}
}
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
/// <summary>
/// Used to search Office, Agent or Property
/// </summary>
/// <param name="SearchType">Selects the Resource type to be returned</param>
/// <param name="Class">Represents the class of the data within the SearchType</param>
/// <param name="QueryType">An enumeration giving the language in which the query is presented</param>
/// <param name="Query">The query to be executed by the server</param>
/// <param name="Count">Controls whether the server response includes a record count</param>
/// <param name="Limit">Request the server to apply a limit on the number of records returned in the search.</param>
/// <param name="Offset">Request the server start at other than the first record in the set of matching records</param>
/// <param name="Culture">Results localization</param>
/// <param name="Format">Selects the supported data return format for the query response</param>
/// <remarks>Service End Point - /Search.svc/Search</remarks>
public static void SearchTransaction(string SearchType, string Class, string QueryType, string Query, int Count = 1, string Limit = "None", int Offset = 1, string Culture = "en-CA", string Format = "STANDARD-XML")
{
string requestArguments = "?Format=" + Format + "&SearchType=" + SearchType + "&Class=" + Class + "&QueryType=" + QueryType + "&Query=" + Query + "&Count=" + Count + "&Limit=" + Limit + "&Offset=" + Offset + "&Culture=" + Culture;
string searchService = RetsUrl + "/Search.svc/Search" + requestArguments;
httpWebRequest = (HttpWebRequest)WebRequest.Create(searchService);
httpWebRequest.CookieContainer = cookieJar;
httpWebRequest.Credentials = requestCredentials;
try
{
using (HttpWebResponse httpResponse = httpWebRequest.GetResponse() as HttpWebResponse)
{
Stream stream = httpResponse.GetResponseStream();
XmlTextReader reader = new XmlTextReader(stream);
while (reader.Read())
{
switch (reader.Name)
{
case "RETS":
if (reader.HasAttributes)
{
while (reader.MoveToNextAttribute())
{
if (reader.Name == "ReplyCode" & reader.Value == "0")
{
Console.WriteLine("================================================================================");
Console.WriteLine("VALID SEARCH REQUEST");
Console.WriteLine("================================================================================");
Console.WriteLine("{0}: {1}", reader.Name, reader.Value);
}
else
{
Console.WriteLine("{0}: {1}", reader.Name, reader.Value);
}
}
}
break;
case "TotalRecords":
ReadXMLElement(reader);
break;
case "Limit":
ReadXMLElement(reader);
break;
case "Offset":
ReadXMLElement(reader);
break;
case "TotalPages":
ReadXMLElement(reader);
break;
case "RecordsReturned":
ReadXMLElement(reader);
break;
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
public static void ReadXMLElement(XmlTextReader reader)
{
if (reader.NodeType != XmlNodeType.EndElement)
{
string name = reader.Name;
// RETRIEVE THE NEXT NESTED ELEMENT TEXT
while (reader.Read())
{
if (reader.HasValue)
{
Console.WriteLine("{0}: {1}", name, reader.Value);
break;
}
}
}
}
public static void GetObject(string strResource, string strID, string strType){
string requestArguments = "?Resource=" + strResource + "&ID=" + strID + "&Type=" + strType;
string searchService = RetsUrl + "/Object.svc/GetObject" + requestArguments;
httpWebRequest = (HttpWebRequest)WebRequest.Create(searchService);
httpWebRequest.CookieContainer = cookieJar;
httpWebRequest.Credentials = requestCredentials;
try
{
using (HttpWebResponse httpResponse = httpWebRequest.GetResponse() as HttpWebResponse)
{
// READ THE RESPONSE STREAM USING XMLTEXTREADER
if (httpResponse.StatusCode == HttpStatusCode.OK)
{
Stream stream = httpResponse.GetResponseStream();
StreamReader reader = new StreamReader(stream);
Console.WriteLine("Received photo -> resource:" + strResource + ", type: " + strType);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
}
PHP Code Sample
We recommending using the PHRETS library by troydavisson, found for free on GitHub here: https://github.com/troydavisson/PHRETS
Sample.php
<?php
// Using "PHRETS" by troydavisson: https://github.com/troydavisson/PHRETS
require_once('vendor/autoload.php');
// Login to MLS IDX API
$config = new \PHRETS\Configuration;
$config->setLoginUrl('https://sample.mlsidxapi.com/Login.svc/Login')
->setUsername('aQgXjDxarQcxFqqIrmfeTvuk')
->setPassword('JNTHKsuoXySgTZZWJGZkipSP')
->setHttpAuthenticationMethod('basic')
->setRetsVersion('1.7.2');
$rets = new \PHRETS\Session($config);
$rets->Login();
function getSearchResultsArray($dbml, $limit = 100, $offset = 0, $format = 'STANDARD-XML') {
global $rets;
if ($offset) $results = $rets->Search('Property', 'Property', $dbml, [ 'Count' => 1, 'Format' => $format, 'Limit' => $limit, 'Offset' => $offset ]);
else $results = $rets->Search('Property', 'Property', $dbml, [ 'Count' => 1, 'Format' => $format, 'Limit' => $limit ]);
$parser = new \PHRETS\Parsers\XML;
$xml = $parser->parse($rets->getLastResponse());
// Convert to PHP array
return json_decode(json_encode($xml, true), JSON_PRETTY_PRINT);
}
function addResultToDB($listing) {
// Save results to your database
//...
}
function addAllResultsToDB($results) {
$addedCount = 0;
$propertyDetails = $results['RETS-RESPONSE']['PropertyDetails'];
// NOTE: You must make your own "addResultToDB" function
// Only one result, so force into array
if (!$propertyDetails[0]) $addedCount += addResultToDB($propertyDetails);
// Add a bunch at once
else foreach($propertyDetails as $listing) $addedCount += addResultToDB($listing);
return $addedCount;
}
// Search the last 5 hours
$dbml = "(LastUpdated=" . date('Y-m-d\TH:i:sP', strtotime('-5 Hours')) . ")";
// Set to Zulu time
$dbml = str_replace('+00:00', 'Z', $dbml);
$limit = 100;
$offset = 0;
$totalRecords = 0;
$totalRecordsAdded = 0;
$totalRecordsReturned = 0;
do {
// Get results in simple PHP array
$results = getSearchResultsArray($dbml, $limit, $offset);
$totalRecords = $results['RETS-RESPONSE']['Pagination']['TotalRecords'];
// Discontinue now if no records found
if (!$totalRecords) break;
// Save results to your database
$totalRecordsAdded += addAllResultsToDB($results);
$recordsReturned = $results['RETS-RESPONSE']['Pagination']['RecordsReturned'];
$totalRecordsReturned += $recordsReturned;
$offset = $results['RETS-RESPONSE']['Pagination']['Offset'] + $recordsReturned;
} while ($totalRecords > $totalRecordsAdded);
CONTACT US
Get In Touch With Us
Ready to transform your real estate platform with the most comprehensive MLS data? Contact us today to get started with our API service and take your business to the next level!