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);
}
}
}
}