Page tree
Skip to end of metadata
Go to start of metadata


Introduction


DOTS Phone Exchange 2 is an XML/JSON web service that provides information about telephone numbers. With DOTS Phone Exchange 2 users can verify telephone numbers, receive geographic location and carrier information of any phone number in the U.S., In addition, it also provides Local Number Portability data in the event the phone number has been ported between Carriers and LineType.



NOTE: The DOTS Phone Exchange 2 web service has recently been updated, and as such some of the older operations have been deprecated.  If you are still currently using the older operations of the service, you can refer to the developer's guide below for information concerning integration, inputs and outputs for the deprecated operations.


If you are an existing client and are using the previous version of this service then please click on the following link.

DOTS Phone Exchange

Integration


Integration of DOTS Phone Exchange 2 into user applications is generally a straightforward process. For common programming platforms, such as ASP, ASP.NET, ColdFusion, PHP, etc., Service Objects will likely have sample code available online:
https://www.serviceobjects.com/developers/sample-code/phone-exchange

If the code you seek is not available online, you can ask Service Objects to build a custom example for you. Email support@serviceobjects.com for more details.

Web Service Structure

Web services provide a standard interface to encapsulate tricky business logic. They allow simple integration of applications via the web. Service Objects has followed web services best practices and come up with some of its own standards to ensure that its web services are as easy to integrate and as accessible as possible.

The host path or physical location of the web service is here:
https://trial.serviceobjects.com/pe2/web.svc

The location of the WSDL, or Web Service Definition Language document, is here (This is also accessible via the "Service Definition" link on the web service page.):
https://trial.serviceobjects.com/pe2/soap.svc?wsdl

Test Page
https://trial.serviceobjects.com/pe2/


Important Note!
SOAP is done via POST, only with special XML markup in the post-body


The WSDL is an XML document that defines the interaction web service, meaning its inputs, outputs, operations, and the like. Most likely, you will have another tool read this WSDL and make the operations available to you in your application via some type of proxy class. Whenever your utilities or IDE asks for a WSDL path, you can provide this one.

Every web service has operations that it offers to subscribers. These operations, also called methods, contain different functionality and return different outputs. DOTS Phone Exchange 2 has one operation, it will be described in detail later in this document.

Code Snippets




Phone Exchange C# Code Snippet
//Add a service to your application https://trial.serviceobjects.com/pe2/soap.svc
PE2Client = new PhoneExchange2Client("DOTSPE2Primary");
response = PE2Client.GetExchangeInfo(number, licenseKey);
		
if (response.Error != null)
{
	//Process Error
}
else
{
	//Process Response		
}


Phone Exchange Java Code Snippet
ExchangeInfoResponse resp = null;
ExchangeInfo result = null;
PE2Error error = null;
// Create soap request
PhoneExchange2Locator locator = new PhoneExchange2Locator();
// use ssl
locator.setsoapEndpointAddress("https://trial.serviceobjects.com/PE2/soap.svc/soap");
IPhoneExchange2 PE2 = locator.getsoap();
SoapStub soap = (SoapStub) pe;
soap.setTimeout(5000);// set timeout
resp = soap.getExchangeInfo(phoneNumbers, key);
result = resp.getPhoneExchangeInfo();
error = resp.getError();
if(resp == null || (error != null && error.getTypeCode() == "3"))
{
	throw new Exception();
}
 
//Process Results
if(error == null){
	//DOTS Phone Exchange Results	
}
//Process Errors
else{
	//DOTS Phone Exchange 2 Error Results	
}


Phone Exchange PHP Code Snippets
<?php
// Set these values per web service <as needed>
$wsdlUrl = "https://trial.serviceobjects.com/pe2/soap.svc?wsdl";

$params['phoneNumber'] = $PhoneNumber;
$params['LicenseKey'] = $LicenseKey;

$soapClient = new SoapClient($wsdlUrl, array( "trace" => 1 ));
$result = $soapClient->GetExchangeInfo($params);
if (!isset($result->GetExchangeInfoResult->Error)) 
{
    foreach($result->GetExchangeInfoResult->ExchangeInfoResults->ExchangeInfo as $k=>$v) 
	{
       if(is_a($v, "stdClass"))
       {
          foreach($v as $k2=>$v2) 
          {
             echo "$k2,$v2";
          }
          continue;
       }
       echo "$k,$v";
    }
} else {
    foreach($result->GetExchangeInfoResult->Error as $k=>$v) {
       echo "$k,$v";
       }
}
?>


Phone Exchange RoR Code Snippets
		#Formats inputs into a hash to pass to Soap Client
		#Hash Keys must be named as they are shown here.
		message = 	{
					"PhoneNumber" => @request.phonenumber,
					"LicenseKey" => @request.licensekey,
					}
		#Implemented to make the code more readable when accessing the hash			
		@pe2response = :get_exchange_info_response
		@pe2result = :get_exchange_info_result
		@pe2results = :exchange_info_results
		@pe2info = :exchange_info
		@pe2portedinfo = :ported_info
		@pe2error = :error
		#Set Primary and Backup URLs here as needed
		dotsPE2Primary = "https://trial.serviceobjects.com/pe2/soap.svc?wsdl"
		dotsPE2Backup = "https://trial.serviceobjects.com/pe2/soap.svc?wsdl"

		begin
			#initializes the soap client. The convert request keys global is necessary to receive a response from the service.
			client = Savon.client(	wsdl: dotsPE2Primary )
			#Calls the operation with given inptus and converts response to a hash.
			response = client.call(:get_exchange_info, message: message).to_hash
			#Checks to see what results came back from the service
			processresults(response)			
			
		#If an error occurs during the call, this will use backup url and attempt to retrieve data.
		rescue Savon::Error => e
			begin
			backupclient = Savon.client( wsdl: dotsPE2Backup )
			#Sets the response to the backclient call to the operation and converts response to a hash.
			response = backupclient.call(:get_exchange_info, message: message).to_hash
			processresults(response)
			#If backup url failed, this will display the error received from the server
			rescue Savon::Error =>error
			end
		end
	end
	private 
	def processresults(response)	
			#Processes Error Response from soap Client		
			#Processes Valid response from soap client	
	end


Phone Exchange Python Code Snippet
    mPhoneNumber = PhoneNumber.get()
    if mPhoneNumber is None or mPhoneNumber == "":
        mPhoneNumber = " "
    mLicenseKey = LicenseKey.get()
    if mLicenseKey is None or mLicenseKey == "":
        mLicenseKey = " "

 #Set the primary and backup URLs as needed
    primaryURL = 'https://trial.serviceobjects.com/pe2/soap.svc?wsdl'
    backupURL = 'https://trial.serviceobjects.com/pe2/soap.svc?wsdl'

    #This block of code calls the web service and prints the resulting values to the screen
    try:
        client = Client(primaryURL)
        result = client.service.GetExchangeInfo(PhoneNumber= mPhoneNumber, LicenseKey=mLicenseKey)
        #Handel response and check for errors

    #Tries the backup URL if the primary URL failed
    except:
        try:
            client = Client(backupURL)
            result = client.service.GetExchangeInfo(PhoneNumber= mPhoneNumber, LicenseKey=mLicenseKey)
            #Handel response and check for errors

        #If the backup call failed then this will display an error to the screen
        except:
            Label(swin.window, text='Error').pack()
            print (result)


Phone Exchange 2 ColdFusion Code Snippet
<!--Makes Request to web service --->
<cfscript>
		try
		{
			if (isDefined("form.Action") AND Action neq "")
			{
				wsresponse = CreateObject("webservice", "https://trial.serviceobjects.com/pe2/soap.svc?wsdl");							  
				outputs = wsresponse.getExchangeInfo("#PhoneNumber#", "#LicenseKey#");
			}
		}
	catch(any Exception){
		try
			{
				if (isDefined("form.Action") AND Action neq "")
				{
					wsresponse = CreateObject("webservice", "https://trial.serviceobjects.com/pe2/soap.svc?wsdl");							  
					outputs = wsresponse.getExchangeInfo("#PhoneNumber#", "#LicenseKey#");
				}
			}
			catch(any Exception)	{
		  		 writeoutput("An Error Has Occured. Please Reload and try again");		  		 
		 		}
	    }
</cfscript>


Phone Exchange 2 VB Code Snippet
Try
    Dim ws As New PE2.PhoneExchange2Client
    Dim response As PE2.ExchangeInfoResponse
    response = ws.GetExchangeInfo(PhoneNumber.Text, LicenseKey.Text)
    If (response.Error Is Nothing) Then
        ProcessValidResponse(response)
    Else
        ProcessErrorResponse(response.Error)
    End If

Catch er As Exception
    Try
        ''Set the primary and backup service references as necessary
        Dim wsbackup As New PE2.PhoneExchange2Client
        Dim response As PE2.ExchangeInfoResponse
        response = wsbackup.GetExchangeInfo(PhoneNumber.Text, LicenseKey.Text)
        If (response.Error Is Nothing) Then
            ProcessValidResponse(response)
        Else
            ProcessErrorResponse(response.Error)
        End If
    Catch ex As Exception
        resultsLabel.Visible = True
        resultsLabel.Text = ex.Message
    End Try
End Try


Phone Exchange 2 Apex Code Snippet
wwwServiceobjectsCom.ExchangeInfoResponse result;
try{
wwwServiceobjectsCom.ServiceObjects_IPhoneExchange client = new wwwServiceobjectsCom.ServiceObjects_IPhoneExchange();
result = client.GetExchangeInfo([PhoneNumber], [LicenseKey]);
}
catch(Exception ex){
 //If the first request failed try the failover endpoint
wwwServiceobjectsCom.ServiceObjects_IPhoneExchange backupClient = new wwwServiceobjectsCom.ServiceObjects_IPhoneExchange();
//The backup environment will be provided to you upon purchasing a production license key
backupClient.endpoint_x = 'http://trial.serviceobjects.com/PE2/soap.svc/soap';
result = backupClient.GetExchangeInfo([PhoneNumber], [LicenseKey]);
}


Phone Exchange 2 TSQL Code Snippet
SET @requestBody = '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">' +
					'<s:Body>' +
					'<GetExchangeInfo xmlns="http://www.serviceobjects.com">' +
					'<PhoneNumber>' + @phonenumber  +  '</PhoneNumber>' +
					'<LicenseKey>' + @key  +  '</LicenseKey>' +
					'</GetExchangeInfo>' +
					'</s:Body>' +
					'</s:Envelope>'
SET @requestLength = LEN(@requestBody)
	--If a production key is purchased, this will execute the failover 
IF @isLiveKey = 1
BEGIN
	EXEC sp_OACreate 'MSXML2.ServerXMLHttp', @obj OUT
	EXEC sp_OAMethod @obj, 'Open', NULL, 'POST', 'http://ws.serviceobjects.com/PE2/api.svc/PhoneExchangeSoap', false
	EXEC sp_OAMethod @obj, 'setRequestHeader', NULL, 'HOST', 'ws.serviceobjects.com'
	EXEC sp_OAMethod @obj, 'setRequestHeader', NULL, 'Content-Type', 'text/xml; charset=UTF-8'
	EXEC sp_OAMethod @obj, 'setRequestHeader', NULL, 'SOAPAction', '"http://www.serviceobjects.com/IPhoneExchange2/GetExchangeInfo"'
	EXEC sp_OAMethod @obj, 'setRequestHeader', NULL, 'Content-Length', @requestLength 
	EXEC sp_OAMethod @obj, 'send', NULL, @requestBody
	EXEC sp_OAGetProperty @obj, 'Status', @responseCode OUTPUT
	EXEC sp_OAGetProperty @obj, 'StatusText', @statusText OUTPUT
	EXEC sp_OAGetProperty @obj, 'responseText', @response OUTPUT
			
	--Checks the Response for a fatal error or if null. 
	IF @response IS NULL
	BEGIN
		EXEC sp_OACreate 'MSXML2.ServerXMLHttp', @obj OUT
		EXEC sp_OAMethod @obj, 'Open', NULL, 'POST', 'http://wsbackup.serviceobjects.com/PE2/api.svc/PhoneExchangeSoap', false
		EXEC sp_OAMethod @obj, 'setRequestHeader', NULL, 'HOST', 'wsbackup.serviceobjects.com'
		EXEC sp_OAMethod @obj, 'setRequestHeader', NULL, 'Content-Type', 'text/xml; charset=UTF-8'
		EXEC sp_OAMethod @obj, 'setRequestHeader', NULL, 'SOAPAction', '"http://www.serviceobjects.com/IPhoneExchange2/GetExchangeInfo"'
		EXEC sp_OAMethod @obj, 'setRequestHeader', NULL, 'Content-Length', @requestLength 
		EXEC sp_OAMethod @obj, 'send', NULL, @requestBody
		EXEC sp_OAGetProperty @obj, 'Status', @responseCode OUTPUT
		EXEC sp_OAGetProperty @obj, 'StatusText', @statusText OUTPUT
		EXEC sp_OAGetProperty @obj, 'responseText', @response OUTPUT
	END
END



Phone Exchange C# Rest Code Snippet
PE2Response result = null;
string mainURL = "https://trial.serviceobjects.com/pe2/web.svc/xml/GetExchangeInfo?PhoneNumber="+ phoneNumber + "&LicenseKey=" + licenseKey;
string backupURL = "https://trial.serviceobjects.com/pe2/web.svc/xml/GetExchangeInfo?PhoneNumber=" + phoneNumber + "&LicenseKey=" + licenseKey;;
try
{
    result = HttpGet(mainURL);
    //NULL ERROR || FATAL ERROR RETURNED -- TRY BACKUP 
    if (result == null || (result.Error != null && result.Error.TypeCode == "3"))
    {
        return HttpGet(backupURL);
    }
    else
    {
        return result;
    }
}


Phone Exchange Java Rest Code Snippet
String MainURL = "https://trial.serviceobjects.com/pe2/web.svc/xml/GetExchangeInfo?PhoneNumber="+ phoneNumber + "&LicenseKey=" + licenseKey;
String BackupURL = "https://trial.serviceobjects.com/pe2/web.svc/xml/GetExchangeInfo?PhoneNumber="+ phoneNumber + "&LicenseKey=" + licenseKey;
ExchangeInfoResponse result = GetExchangeInfoResponse(MainURL);
//NULL ERROR || FATAL ERROR RETURNED -- TRY BACKUP 
if(ErrorMessages!=null || (result.Error != null && result.Error.TypeCode == "3" ))
{	//BACKUP URL
	result = GetExchangeInfoResponse(BackupURL);
}
return result;


Phone Exchange PHP Rest Code Snippets
$URL = "https://trial.serviceobjects.com/pe2/web.svc/xml/GetExchangeInfo?PhoneNumber=".urlencode($PhoneNumber)."&LicenseKey=".urlencode($LicenseKey);
//use backup url once given purchased license key
$backupURL = "https://trial.serviceobjects.com/pe2/web.svc/xml/GetExchangeInfo?PhoneNumber=".urlencode($PhoneNumber)."&LicenseKey=".urlencode($LicenseKey);

	// Get cURL resource
	$curl = curl_init();
	curl_setopt_array($curl, array(CURLOPT_RETURNTRANSFER => 1, CURLOPT_URL => $URL, CURLOPT_USERAGENT => 'Service Objects Phone Exchange 2'));
	curl_setopt($curl, CURLOPT_TIMEOUT, 5); //timeout in seconds
	// Send the request & save response to $resp
	$resp = curl_exec($curl);
	// Close request to clear up some resources
	if($resp == false)
	{
		curl_setopt_array($curl, array(CURLOPT_RETURNTRANSFER => 1, CURLOPT_URL => $backupURL, CURLOPT_USERAGENT => 'Service Objects Phone Exchange 2'));
		curl_setopt($curl, CURLOPT_TIMEOUT, 5); //timeout in seconds
		// Send the request & save response to $resp
		$resp = curl_exec($curl);
		if($resp == false)
		{
			echo "<b> Both rest calls failed </b>";
			curl_close($curl);
			return;
		}
	
	
	}
curl_close($curl);


Phone Exchange RoR Rest Code Snippets
#Set Primary and Backup URLs as needed. This method encodes and standardizes the URI to pass to the REST service.
primaryURL = URI.encode("http://trial.serviceobjects.com/PE2/web.svc/xml/GetExchangeInfo?PhoneNumber=" + phonenumber + "&LicenseKey=" + licensekey)
backupURL = URI.encode("http://trial.serviceobjects.com/PE2/web.svc/xml/GetExchangeInfo?PhoneNumber=" + phonenumber + "&LicenseKey=" + licensekey)
#These are set to access the hash that is returned
@pe2response ="ExchangeInfoResponse"
@pe2results = "ExchangeInfoResults"
@pe2info = "ExchangeInfo"
@pe2portedinfo = "PortedInfo"
@pe2error = "Error"
  #Begins the call the RESTful web service
begin
  response = HTTParty.get(primaryURL, timeout: default_timeout)
  
  #Passes the response returned from HTTParty and processes them depending on the results
 processresults(response)
  
 rescue StandardError => e
 		begin
 		#uses the backupURl in the event that the service encountered an error
 		response = HTTParty.get(backupURL, timeout: default_timeout)
    
    #processes the response returned from using the backupURL
 		processresults(response)
    #If the backup url railed this will raise an error and display the 
    #error message returned from the HTTParty gem.
 		rescue StandardError => error
 			@status = response
 			@displaydata = {"Error" => "A Big Error Occured"}
 		end
end


Phone Exchange Python Rest Code Snippet
primaryURL = 'http://trial.serviceobjects.com/PE2/web.svc/xml/GetExchangeInfo?'
backupURL = 'http://trial.serviceobjects.com/PE2/web.svc/xml/GetExchangeInfo?'
#The Requests package allows the user to format the path parameters like so instead of having to manually insert them into the URL
inputs = {'PhoneNumber': mPhoneNumber, 'LicenseKey': mLicenseKey}
try:
    result = requests.get(primaryURL, params=inputs)
    #Parses the XML response from the service into a python dictionary type
    outputs = xmltodict.parse(result.content)
    #checks the output for Errors and displays the info accordingly
    if 'Error' in outputs['ExchangeInfoResponse']:
        #loops through the response from the service and prints the values to the screen.
        for key, value in outputs['ExchangeInfoResponse']['Error'].iteritems():
            Label(swin.window, text=str(key) + " : " + str(value)).pack()
    #Loops through and prints Valid results from the service
    else:
        for key, value in outputs['ExchangeInfoResponse']['ExchangeInfoResults']['ExchangeInfo'].iteritems():
            if key != 'PortedInfo':
                Label(swin.window, text=str(key) + " : " + str(value)).pack()
        #If Ported info is available this will print the results under a heading.
        if 'PortedInfo' in outputs['ExchangeInfoResponse']['ExchangeInfoResults']['ExchangeInfo']:
            Label(swin.window, font="bold", text="Ported Info").pack()
            for key, value in outputs['ExchangeInfoResponse']['ExchangeInfoResults']['ExchangeInfo']['PortedInfo'].iteritems():
                Label(swin.window, text=str(key) + " : " + str(value)).pack()
#Attempts to use the backup URL if the call to the primary URL failed.
except:
    try:
        result = requests.get(backupURL, params=inputs)
        #Parses the XML response from the service into a python dictionary type
        outputs = xmltodict.parse(result.content)
        #checks the output for Errors and displays the info accordingly
        if 'Error' in outputs['ValidateEmailResponse']:
            #loops through the response from the service and prints the values to the screen.
            for key, value in outputs['ValidateEmailResponse']['Error'].iteritems():
                Label(swin.window, text=str(key) + " : " + str(value)).pack()
        else:
            for key, value in outputs['ValidateEmailResponse']['ValidateEmailInfo'].iteritems():
                Label(swin.window, text=str(key) + " : " + str(value)).pack()


Phone Exchange 2 ColdFusion Rest Code Snippet
<!--Makes Request to web service --->
<cfIf isDefined("form.Action") AND Action neq ""  >
	<cftry>
		<cfset primaryURL = "http://trial.serviceobjects.com/PE2/web.svc/xml/GetExchangeInfo?PhoneNumber=#PhoneNumber#&LicenseKey=#LicenseKey#">
		<cfhttp url="#primaryURL#" method="get" result="response">
		<cfset outputs = XmlParse(response.FileContent)>
	<cfcatch >
		<cftry>
			<cfset backupURL = "http://trial.serviceobjects.com/PE2/web.svc/xml/GetExchangeInfo?PhoneNumber=#PhoneNumber#&LicenseKey=#LicenseKey#">
			<cfhttp url="#backupURL#" method="get" result="response">
			<cfset outputs = XmlParse(response.FileContent)>				
			<cfcatch type="any" name="error">
				<cfoutput>
					The Following Error Occured: "#error.Message#"
				</cfoutput>
			</cfcatch>
		</cftry>
	</cfcatch>
	</cftry>
</cfif>	


Phone Exchange 2 VB Rest Code Snippet
'encodes the URLs for the get Call. Set the primary and back urls as necessary
Dim primaryurl As String = "http://trial.serviceobjects.com/PE2/web.svc/xml/GetExchangeInfo?PhoneNumber=" & phonenumber + "&LicenseKey=" & licensekey
Dim backupurl As String = "http://trial.serviceobjects.com/PE2/web.svc/xml/GetExchangeInfo?PhoneNumber=" & phonenumber + "&LicenseKey=" & licensekey
Dim wsresponse As PE2Response.ExchangeInfoResponse = httpGet(primaryurl)

'checks if a response was returned from the service, uses the backup url if response is null or a fatal error occured.
If wsresponse Is Nothing OrElse (wsresponse.[Error] IsNot Nothing AndAlso wsresponse.[Error].TypeCode = "3") Then
    wsresponse = httpGet(backupurl)
End If
If wsresponse.[Error] IsNot Nothing Then
    ProcessErrorResponse(wsresponse.[Error])
Else
    ProcessSuccessfulResponse(wsresponse)

End If


Phone Exchange 2 TSQL Rest Code Snippet
BEGIN
	SET @sUrl = 'http://ws.serviceobjects.com/pe2/web.svc/xml/GetExchangeInfo?PhoneNumber=' + @phonenumber + '&LicenseKey=' + @key
	EXEC sp_OACreate 'MSXML2.ServerXMLHttp', @obj OUT
	EXEC sp_OAMethod @obj, 'Open', NULL, 'Get', @sUrl, false
	EXEC sp_OAMethod @obj, 'send'
	EXEC sp_OAGetProperty @obj, 'responseText', @response OUT
			
	--Checks the Response for a fatal error or if null. 
	IF @response IS NULL
	BEGIN
		SET @sBackupUrl = 'http://wsbackup.serviceobjects.com/pe2/web.svc/xml/GetExchangeInfo?PhoneNumber=' + @phonenumber + '&LicenseKey=' + @key
		EXEC sp_OACreate 'MSXML2.ServerXMLHttp', @obj OUT
		EXEC sp_OAMethod @obj, 'Open', NULL, 'Get', @sBackupUrl, false
		EXEC sp_OAMethod @obj, 'send'
		EXEC sp_OAGetProperty @obj, 'responseText', @response OUT
	END
END

You can find and download full sample code to our services in various languages (PHP, JAVA and C#) by clicking here. Below is a C# version.

If you are looking for a particular integration not listed in our documentation please contact us at support@serviceobjects.com.

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Data;
namespace ServiceObjects
{
    public partial class PE2_REST : System.Web.UI.Page
    {
        #region STATICS
        static string WEB_SERVICE_PRIMARY_URL; //Included in email from Service Objects
        static string WEB_SERVICE_BACKUP_URL; //Included in email from Service Objects (LIVE customers only)
        static int WEB_SERVICE_REQUEST_TIMEOUT; //In milliseconds
        #endregion
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                ErrorLabel.Visible = false;
                ErrorGrid.Visible = false;
                ResultGrid.Visible = false;
                WEB_SERVICE_REQUEST_TIMEOUT = Convert.ToInt32(ConfigurationManager.AppSettings["WebServiceRequestTimeout"]);
                WEB_SERVICE_PRIMARY_URL = ConfigurationManager.AppSettings["PE2_PRIMARY"];
                if (string.IsNullOrWhiteSpace(WEB_SERVICE_PRIMARY_URL))
                    throw new System.Exception("Primary URL not set. Check your Web.config file.");
                WEB_SERVICE_BACKUP_URL = ConfigurationManager.AppSettings["PE2_BACKUP"];
                if (string.IsNullOrWhiteSpace(WEB_SERVICE_BACKUP_URL))
                    throw new System.Exception("Backup URL not set. Check your Web.config file.");
            }
            catch (Exception ex)
            {
                ErrorLabel.Visible = true;
                ErrorLabel.Text = "Page load Error: "+ ex.Message;
            }
        }
        protected void btn_GO_Click(object sender, EventArgs e)
        {
            string phoneNumber, licenseKey;
            phoneNumber = inputPhoneNumber.Text; licenseKey = inputLicenseKey.Text;
            try
            {
                //NOTE: A missing parameter is not allowed
                if (phoneNumber == "")
                    phoneNumber = " ";
                if (String.IsNullOrWhiteSpace(licenseKey))
                    licenseKey = "yourDevKey";
                PE2Response response = MakeRequest(phoneNumber, licenseKey);
                ProcessResponse(response);
            }
            catch (Exception ex)
            {
                ErrorLabel.Text = ex.Message;
                ErrorLabel.Visible = true;
            }
        }
        //Creates URL and requests response from service 
        private static PE2Response MakeRequest(string phoneNumber, string licenseKey)
        {
            /* 
            * Due to RFC compliance, the use of URL Paths has character limitations.  
            * Certain characters are invalid and cause HTTP Errors; these characters  
            * include #, /, ?,\ as well as some high bit characters.  
            * 
            * If you suspect that this may be an issue for you then it is recommended to change your 
            * request from the URL path parameter format to the query string parameter format.  
            * Example:  
            *     FROM {data}/{data2}/{key}?format=json  
            *     TO parameter1={data1}&parameter2={data2}&licensekey={key} 
            * Another alternative is to use HTTP Post instead of HTTP Get. 
            */
            PE2Response result = null;
            string mainURL = WEB_SERVICE_PRIMARY_URL + "PhoneNumber=" + phoneNumber + "&LicenseKey=" + licenseKey;
            string backupURL = WEB_SERVICE_BACKUP_URL + "PhoneNumber=" + phoneNumber + "&LicenseKey=" + licenseKey;
            try
            {
                result = HttpGet(mainURL);
                //NULL ERROR || FATAL ERROR RETURNED -- TRY BACKUP 
                if (result == null || (result.Error != null && result.Error.TypeCode == "3"))
                {
                    return HttpGet(backupURL);
                }
                else
                {
                    return result;
                }
            }
            catch (Exception e)
            {   //ERROR IN MAIN URL - USING BACKUP
                return HttpGet(backupURL);
            }
        }
        //HTTP Get Method and parse into user-defined object
        private static PE2Response HttpGet(string requestUrl)
        {
            try
            {
                //NOTE: URL encoding occurs automatically when creating the web request
                HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;
                request.Timeout = WEB_SERVICE_REQUEST_TIMEOUT;//timeout for get operation
                using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
                {
                    if (response.StatusCode != HttpStatusCode.OK)
                        throw new Exception(String.Format(
                        "Server error (HTTP {0}: {1}).",
                        response.StatusCode,
                        response.StatusDescription));
                    //parse response
                    DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(PE2Response));
                    object objResponse = jsonSerializer.ReadObject(response.GetResponseStream());
                    PE2Response jsonResponse = objResponse as PE2Response;
                    return jsonResponse;
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }
        //Process the returned user-defined object
        private void ProcessResponse(PE2Response response)
        {
            try
            {
                //processing result
                if (response.Error == null)
                {
                    ProcessResult(response.ExchangeInfoResults);
                }
                //processing error
                else
                {
                    ProcessError(response.Error);
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }
        //Process and display the result values
        private void ProcessResult(ExchangeInfoResults[] results)
        {
            try
            {
                DataTable dtProvider = new DataTable();
                dtProvider.Columns.Add(new DataColumn("Output", typeof(string)));
                dtProvider.Columns.Add(new DataColumn("Values", typeof(string)));
                int i = 0;
                foreach (ExchangeInfoResults result in results)
                {
                    i++;
                    dtProvider.Rows.Add("Result #" + i, "");
                    dtProvider.Rows.Add("PhoneNumber", result.PhoneNumber);
                    dtProvider.Rows.Add("Name", result.Name);
                    dtProvider.Rows.Add("City", result.City);
                    dtProvider.Rows.Add("State", result.State);
                    dtProvider.Rows.Add("Country", result.Country);
                    dtProvider.Rows.Add("LineType", result.LineType);
                    dtProvider.Rows.Add("TimeZone", result.TimeZone);
                    dtProvider.Rows.Add("Latitude", result.Latitude);
                    dtProvider.Rows.Add("Longitude", result.Longitude);
                    dtProvider.Rows.Add("SMSAddress", result.SMSAddress);
                    dtProvider.Rows.Add("MMSAddress", result.MMSAddress);
                    dtProvider.Rows.Add("OriginalName", result.PortedInfo.OriginalName);
                    dtProvider.Rows.Add("OriginalLineType", result.PortedInfo.OriginalLineType);
                    dtProvider.Rows.Add("PortedDate", result.PortedInfo.PortedDate);
                    dtProvider.Rows.Add("LATA", result.PortedInfo.LATA);
                    dtProvider.Rows.Add("NoteCodes", result.NoteCodes);
                    dtProvider.Rows.Add("NoteDescriptions", result.NoteDescriptions);
                }
                ResultGrid.Visible = true;
                ErrorGrid.Visible = false;
                ResultGrid.DataSource = new DataView(dtProvider);
                ResultGrid.DataBind();
            }
            catch (Exception e)
            {
                throw e;
            }
        }
        //Process and display the error values
        private void ProcessError(Error error)
        {
            try
            {
                DataTable dtError = new DataTable();
                //A case statement is used here because it is often useful to do different
                //things depeneding on which general type of error occurs.
                //Handle the errors according to your production needs.
                switch (System.Convert.ToInt32(error.TypeCode))
                {
                    case 1:
                        //Authorization Error
                        break;
                    case 2:
                        //User Input Error
                        break;
                    case 4:
                        //Domain Specific Error
                        break;
                    default:
                        //default (error code 3) Service Objects Fatal Error Error
                        break;
                }
                dtError.Columns.Add(new DataColumn("Output", typeof(string)));
                dtError.Columns.Add(new DataColumn("Values", typeof(string)));
                dtError.Rows.Add("Type", error.Type);
                dtError.Rows.Add("TypeCode", error.TypeCode);
                dtError.Rows.Add("Desc", error.Desc);
                dtError.Rows.Add("DescCode", error.DescCode);
                //
                ResultGrid.Visible = false;
                ErrorGrid.Visible = true;
                ErrorGrid.DataSource = new DataView(dtError);
                ErrorGrid.DataBind();
            }
            catch (Exception e)
            {
                throw e;
            }
        }
    }
}
               


GetExchangeInfo Example Request and Response

XML Request: 
https://trial.serviceobjects.com/pe2/web.svc/xml/GetExchangeInfo?PhoneNumber=8059612034+ext.+4321&LicenseKey=licenseKey


XML Response
<ExchangeInfoResponse xmlns="http://www.serviceobjects.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<ExchangeInfoResults>
<ExchangeInfo>
<PhoneNumber>8059612034</PhoneNumber>
<Name>LEVEL3 TELECOM OF CA</Name>
<City>SANTA BARBARA</City>
<State>CALIFORNIA</State>
<Country>US</Country>
<LineType>LANDLINE</LineType>
<TimeZone>PST</TimeZone>
<Latitude>34.43</Latitude>
<Longitude>-119.74</Longitude>
<SMSAddress/>
<MMSAddress/>
<PortedInfo>
<OriginalName>FRONTIER CALIFORNIA INC.</OriginalName>
<OriginalLineType>LANDLINE</OriginalLineType>
<PortedDate>1999-06-28</PortedDate>
<LATA>740</LATA>
</PortedInfo>
<NoteCodes>3,4</NoteCodes>
<NoteDescriptions>IsPorted,IsLandline</NoteDescriptions>
</ExchangeInfo>
</ExchangeInfoResults>
</ExchangeInfoResponse>

GetExchangeInfo Example Request and Response

XML Request: 
https://trial.serviceobjects.com/pe2/web.svc/json/GetExchangeInfo?PhoneNumber=8059612034+ext.+4321&LicenseKey=licenseKey


Json Response
{"ExchangeInfoResults":[{"PhoneNumber":"8059612034","Name":"LEVEL3 TELECOM OF CA","City":"SANTA BARBARA","State":"CALIFORNIA","Country":"US","LineType":"LANDLINE","TimeZone":"PST","Latitude":"34.43","Longitude":"-119.74","SMSAddress":"","MMSAddress":"","PortedInfo":{"OriginalName":"FRONTIER CALIFORNIA INC.","OriginalLineType":"LANDLINE","PortedDate":"1999-06-28","LATA":"740"},"NoteCodes":"3,4","NoteDescriptions":"IsPorted,IsLandline"}]}

GetInternationalExchangeInfo Example Request and Response

XML Request: 
https://trial.serviceobjects.com/pe2/web.svc/xml/GetInternationalExchangeInfo?PhoneNumber=8059631700&Country=United+States&LicenseKey=licensekey


XML Response
<InternationalExchangeInfoResponse xmlns="http://www.serviceobjects.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<InternationalExchangeInfo>
<NumberIn>8059631700</NumberIn>
<CountryCode>1</CountryCode>
<FormatNational>(805) 963-1700</FormatNational>
<Extension/>
<Locality>SAN LUIS OBISPO, CA</Locality>
<LocalityMatchLevel>LocalityAdminArea</LocalityMatchLevel>
<TimeZone>AMERICA/LOS ANGELES</TimeZone>
<Latitude>35.2579</Latitude>
<Longitude>-120.665</Longitude>
<Country>United States</Country>
<CountryISO2>US</CountryISO2>
<CountryISO3>USA</CountryISO3>
<FormatInternational>+1 805-963-1700</FormatInternational>
<FormatE164>+18059631700</FormatE164>
<Carrier>FRONTIER CALIFORNIA INC.</Carrier>
<LineType>FIXED_LINE_OR_MOBILE</LineType>
<SMSAddress/>
<MMSAddress/>
<IsValid>true</IsValid>
<IsValidForRegion>true</IsValidForRegion>
<NoteCodes/>
<NoteDescriptions/>
</InternationalExchangeInfo>
</InternationalExchangeInfoResponse>

GetInternationalExchangeInfo Example Request and Response

Json Request: 
https://trial.serviceobjects.com/pe2/web.svc/json/GetInternationalExchangeInfo?PhoneNumber=8059631700&Country=United+States&LicenseKey=licensekey


Json Response
{"InternationalExchangeInfo":{"NumberIn":"8059631700","CountryCode":"1","FormatNational":"(805) 963-1700","Extension":"","Locality":"SAN LUIS OBISPO, CA","LocalityMatchLevel":"LocalityAdminArea","TimeZone":"AMERICA\/LOS ANGELES","Latitude":"35.2579","Longitude":"-120.665","Country":"United States","CountryISO2":"US","CountryISO3":"USA","FormatInternational":"+1 805-963-1700","FormatE164":"+18059631700","Carrier":"FRONTIER CALIFORNIA INC.","LineType":"FIXED_LINE_OR_MOBILE","SMSAddress":"","MMSAddress":"","IsValid":true,"IsValidForRegion":true,"NoteCodes":"","NoteDescriptions":""}}

List of Operations

GetExchangeInfo (Recommended Operation) - Uses the provided phone number to return geographic location and carrier information including porting information of any phone number in the U.S and Canada. 

GetInternationalExchangeInfo - Parses, validates and formats any phone number worldwide to return geographic location and carrier information where available.

Operation Definitions

GetExchangeInfo (Recommended Operation)

Returns the geographic location and carrier of the US and Canadian phone number.

URL Format Examples:

JSON: https://trial.serviceobjects.com/pe2/web.svc/json/GetExchangeInfo?PhoneNumber=PhoneNumber&LicenseKey=LicenseKey

XML: https://trial.serviceobjects.com/pe2/web.svc/xml/GetExchangeInfo?PhoneNumber=PhoneNumber&LicenseKey=LicenseKey


GetExchangeInfo Inputs

Name

Type

Description

PhoneNumber

String

The ten-digit phone number to validate. Also accepts a 6 digit (area code + suffix) number to return multiple providers.

LicenseKey

String

Your license key to use the service.
Sign up for a free trial key at
https://www.serviceobjects.com/products/phone/phone-exchange

GetExchangeInfo Outputs

All responses from GetExchangeInfo will be returned within an ExchangeInfoResponse object. If no errors are found while performing the validation an Array of ExchangeInfo element will be returned with the following information in an ExchangeInfoResults element. If a 6 digit (area code + suffix) number match is found then multiple provider elements within the ExchangeInfoResults element will be returned. If there is an error, an Error object will be returned (explained in next section).


ExchangeInfoResponse

Name

Type

Description

ExchangeInfoResultsExchangeInfo[]Array of ExchangeInfo results. See ExchangeInfo description below.
ErrorErrorSee Error Type Description below
DebugString[]Array of String type. Used for internal service diagnostics.
ExchangeInfo

Name

Type

Description

PhoneNumber

String

The verified phone number.

Name

String

The name of the phone carrier associated with the phone number.

City

String

The city in which the validated phone number is registered. (Ported Numbers will show original location here.)

State

String

The state in which the validated phone number is registered. (Ported Numbers will show original location here.)

CountryStringThe country in which the validated phone number is registered. (Ported Numbers will show original location here.)

LineType

String

The line type of the validated phone number. (Possible values are Wireless, Landline and VOIP).

TimeZoneStringThe Time Zone of the validated phone number

Latitude

String

The latitude of the registered carrier location. (Ported Numbers will show original location here.)

Longitude

String

The longitude of the registered carrier location. (Ported Numbers will show original location here.)

SMSAddressStringThe SMS gateway address for the provided mobile number
MMSAddressStringThe MMS gateway address for the provided mobile number
PortedInfoPortedInfoSee PortedInfo Description. This object will be populated if the phone number has been ported
NoteCodesStringThe corresponding codes which match NoteDescriptions. These values vary from 1 to 6 based on test results. See NoteCode table below.
NoteDescriptionsStringThe corresponding descriptions which match NoteCodes. These values vary based on NoteCodes. See NoteCode table below.
PortedInfo

Name

Type

Description

OriginalNameStringThe original carrier name that the provided phone number was ported from.
OriginalLineTypeStringThe original line type that the provided phone number was ported from.
PortedDateStringThe date the provided phone number was ported to current carrier.
LATAStringThe provided 3 digit Local Access and Transport Area code for the ported phone number.

GetInternationalExchangeInfo

Parses, validates and formats any phone number worldwide to return geographic location and carrier information where available


URL Format Examples:

JSON: https://trial.serviceobjects.com/pe2/web.svc/json/GetInternationalExchangeInfo?PhoneNumber=PhoneNumber&Country=Country&LicenseKey=LicenseKey

XML:  https://trial.serviceobjects.com/pe2/web.svc/xml/GetInternationalExchangeInfo?PhoneNumber=PhoneNumber&Country=Country&LicenseKey=LicenseKey

GetInternationalExchangeInfo Inputs

Name

Type

Description

PhoneNumber

String

The phone number to be parsed, validated and formatted. The phone number may include extension as well. If no country is provided, the country code should be provided in the phone number.
CountryStringThe Country to be validated using provided phone number. Acceptable Country formats are: ISO2 (Preferred), ISO3, Full Country Name, Variant of Full Country Name, I.P. of region where phone number was collected.

LicenseKey

String

Your license key to use the service.
Sign up for a free trial key at
 https://www.serviceobjects.com/products/phone/phone-exchange

GetInternationalExchangeInfo Outputs

InternationalExchangeInfo

Name

Type

Description

PhoneNumberIn

String

The phone number that was provided as input.

CountryCode

String

The country code of the provided phone number.

FormatNational

String

The provided phone number in a national format.

Extension

String

The parsed extension from the provided phone number.
LocalityStringThe locality from where the phone number belongs. The locality format is generally Locale/Region, Region or Country.
LocalityMatchLevelStringThe match level that was determined from the locality that was found. Possible values include (Locale/Region, Region, Country) match.
TimeZoneStringThe Time Zone of the validated phone number

Latitude

String

The latitude of the locality determined from the phone number.

Longitude

String

The longitude of the locality determined from the phone number.

CountryStringThe country to which the validated phone number belongs.
CountryISO2StringThe ISO 2 character country designation for a validated phone number.
CountryISO3StringThe ISO 3 character country designation for a validated phone number.
FormatInternationalStringThe provided phone number in international format.
FormatE164StringThe provided phone number in E.164 format.
LineTypeStringThe linetype determined for the phone number. See InternationalExchangeInfo LineType table below.
SMSAddressStringThe SMS gateway address for the provided mobile number
MMSAddressStringThe MMS gateway address for the provided mobile number
IsValidBooleanA boolean response type determining whether the phone number is a valid phone number.
IsValidForRegionBooleanA boolean response type determining whether the phone number is a valid phone number for the provided Country.
NoteCodesStringThe corresponding codes which match NoteDescriptions. These values vary from 1 to 6 based on test results. See NoteCode table below.
NoteDescriptionsStringThe corresponding descriptions which match NoteCodes. These values vary based on NoteCodes. See NoteCode table below.

InternationalExchangeInfo LineTypes

NameDescription
UNKNOWNThe line type could not be determined for the given phone number.
PREMIUM_RATEThe phone number is assigned at a premium rate. Typically goods or services are charged to the phone number.
TOLL_FREEThe phone number is assigned as a toll-free number
SHARED_COSTThe phone number is assigned as shared cost. A call to this number is shared by the recipient.
VOIPThe phone number is registered to a VOIP provider.
PERSONAL_NUMBERThe phone number is registered as a personal number.
PAGERThe phone number is registered to a pager device.
UANThe phone number is registered as a Universal Access Number.
VOICEMAILThe phone number is registered to a voicemail service.
FIXED_LINEThe phone number is registered to a fixed line provider (POTS).
FIXED_LINE_OR_MOBILEThe phone number is registered to a carrier that offers Fixed and Mobile services.
MOBILEThe phone number is registered to a carrier that offers Mobile services.

Error

The response object returned if an error occurred while processing the transaction. See error descriptions below.

NameTypeValueDescription
TypeStringVariesThe type of error that was thrown from the service. Example: Authorization, User Input and Domain Specific
TypeCodeStringVariesThe type code of the error.  Example: 1,2,3,4,5
DescStringVariesThe description of the error that was thrown
DescCodeStringVariesThe description code of the error that was thrown.

NoteCodes and Descriptions

The NoteCode table contains a list of current and upcoming note flags that the service can report on when processing a request.
Notice: New NoteCodes and NoteDescription values may be added to the service at any time. 

NoteCodeNoteDescriptionSummary
1IsUnknownProviderIsUnknownProvider indicates provider information was unavailable for the provided phone number.
2IsInvalidNumberIsInvalidNumber indicates that the provided number is invalid.
3IsPortedIsPorted indicates the provided phone number has been ported to a new or existing carrier. This is common among wireless subscribers, and users who wish to retain their phone number when switching phone device (e.g. Landline to Wireless).
4IsLandlineIsLandline indicates the provided phone number is registered as a Landline.
5IsWirelessIsWireless indicates the phone number is assigned to a wireless device.
6IsVOIPIsVOIP indicates the phone number is assigned to a VOIP provider.
7IsUnknownLineTypeIsUnknownLineType indicates the line type could not be determined from the carrier.
8IsTollFreeNumberIsTollFreeNumber indicates the provided number is a Toll Free Access number.
9IsGoogleVoiceNumberIsGoogleVoiceNumber indicates the provided number is a registered Google Voice number. There is increased risk for fraud with Google Voice numbers from operators overseas.
10IsSkypeNumberIsSkypeNumber indicates the provided number is a registered Skype number. There is increased risk for fraud with Skype numbers from operators overseas.
11IsPortableVOIPIsPortableVOIP indicates the registered phone carrier provides local phone number registration without physical address. There is increased risk of fraud with portable voip numbers from operators overseas.
12IsPossiblePortableVOIPIsPossiblePortableVOIP indicates the registered phone number is likely assigned to a carrier which provides local phone number registration without physical address. There is increased risk of fraud with portable voip numbers from operators overseas.
13IsPrepayPhoneIsPrepayPhone indicates the phone number is assigned to a phone carrier offering prepay services. There is increased risk of fraud with phone numbers identified as prepay.
14IsIncompleteNumberIsIncompleteNumber indicates that even though a phone provider match was found for the first 6 digits, the number is incomplete and ultimately an invalid phone number.
900INAFor internal use by Service Objects.
901INBFor internal use by Service Objects.
902INCFor internal use by Service Objects.

Errors

There are four error types described below. 

Error Types

Type

TypeCode

Billable

Standard for all Gen2 Web Services

Authorization

1

No

Yes

User Input

2

No

No

Service Objects Fatal

3

No

Yes

Domain Specific

4

Yes

No

Error type 1: Authorization

These are standard to all Generation 2 DOTS Web Services.

DescCode

Description

0

Unknown authorization error.

1

Please provide a valid license key for this web service.

2

The daily allowable number of transactions for this license key has been exceeded.

3

The monthly allowable number of transactions for this license key has been exceeded.

4

The total allowable number of transactions for this license key has been exceeded.

5

There are not enough transactions available.  Check your daily/monthly transaction limits.

6

This license key has not yet been activated.

7

This license key has expired.

8

Your license key does not work on this service.

Error type 2: User Input

These errors occur as a result of bad input.  DOTS PE2 requires all both inputs to be present in order for a proper validation to take place.

DescCode

Description

1

Please provide a valid 6 or 10 digit phone number.

2

Please provide a LicenseKey in the LicenseKey field.

Error type 3: Service Objects Fatal

The Desc will always be the same and the DescCode has no meaning.  This is standard to all Generation 2 DOTS Web Services.  This signals an issue within the application, or a Network/Connectivity issue.

DescCode

Description

1

Unhandled error.  Please contact Service Objects.

Error type 4: Domain Specific

GetExchangeInfo Errors

DescCode

Description

1

No result found.
2Country Calling Code not supported.
GetInternationalExchangeInfo Errors

DescCode

Description

1

Invalid Country Code
2The string supplied did not seem to be a phone number.

Frequently Asked Questions

The Sample Code is Giving Strange Errors or is Crashing!

Most likely, the sample code cannot connect to Service Objects. Many environments will not allow you to connect out on port 80 or will clip out XML data from these requests/responses.

The easiest way to check for this is to open a browser on the machine running the sample code. In your browser, navigate to: 
https://trial.serviceobjects.com/pe2/

Then try to run one of the operations with your trial key. If you get a browser error, or get no data back, then the sample code isn't able to connect, either. Contact your systems administrator to resolve why you are not able to connect to Service Objects.

Can Phone Exchange 2 give me information for Canadian phone numbers?

Yes. Phone Exchange can verify the telco exchange of any telephone number combination in the North American Numbering Plan.

Phone Exchange 2 doesn't find any data for my phone number!

You may have mistyped your phone number. A valid phone number will always return exchange information, whether it is wireless or landline, connected or disconnected. If you are certain that the number is valid and that it is part of the North American Numbering Plan, then please let us know at support@serviceobjects.com.

Why does Phone Exchange 2 accept a 6 digit number?

When a single provider match is not enough, providing a 6 digit (area code + suffix) number will return a list of known providers that can be used for custom logic. If multiple provider matches for a 6 digit number are potentially problematic for your use case, then a simple solution is to check the length of the number before calling the Phone Exchange service and rejecting any numbers that are not 10 digits in length.

A test number is Ported but shows original location?

If a number has been ported, PE2 currently does not attempt to identify the new terminating provider location info. This may change in the future.


Conclusion

Service Objects is proud to offer you a free trial of DOTS Phone Exchange 2 



Other technical questions or concerns can be directed to support@serviceobjects.com.

If you are interested in purchasing DOTS GeoPhone Plus, please contact sales@serviceobjects.com.

  
We want to hear from you! We're always looking to improve our developer guides. 
Please email your suggestions to devguidefeedback@serviceobjects.com.

  • No labels