IP Address Validation C# Rest Code Snippet

using System.Web;
using System.Threading.Tasks;

namespace ip_address_validation_dot_net.REST
{
    /// <summary>
    /// Provides functionality to call the ServiceObjects IP Address Validation REST API's GetGeoLocationByIP_V4 endpoint,
    /// retrieving geographic location, proxy, host name, and US region information for a given IP address with fallback to a backup endpoint
    /// for reliability in live mode.
    /// </summary>
    public class GetGeoLocationByIPV4Client
    {
        private const string LiveBaseUrl = "https://sws.serviceobjects.com/GPP/web.svc/";
        private const string BackupBaseUrl = "https://swsbackup.serviceobjects.com/GPP/web.svc/";
        private const string TrialBaseUrl = "https://trial.serviceobjects.com/GPP/web.svc/";

        /// <summary>
        /// Synchronously calls the GetGeoLocationByIP_V4 REST endpoint to retrieve geographic location information,
        /// attempting the primary endpoint first and falling back to the backup if the response is invalid
        /// (Error.Number == "4") in live mode.
        /// </summary>
        /// <param name="input">The input parameters including IP address and license key.</param>
        /// <returns>Deserialized <see cref="IPAVResponse"/>.</returns>
        public static IPAVResponse Invoke(GetGeoLocationByIPV4Input input)
        {
            // Use query string parameters so missing/optional fields don't break
            // the URL as path parameters would.
            string url = BuildUrl(input, input.IsLive ? LiveBaseUrl : TrialBaseUrl);
            IPAVResponse response = Helper.HttpGet<IPAVResponse>(url, input.TimeoutSeconds);

            // Fallback on error in live mode
            if (input.IsLive && !IsValid(response))
            {
                string fallbackUrl = BuildUrl(input, BackupBaseUrl);
                IPAVResponse fallbackResponse = Helper.HttpGet<IPAVResponse>(fallbackUrl, input.TimeoutSeconds);
                return fallbackResponse;
            }

            return response;
        }

        /// <summary>
        /// Asynchronously calls the GetGeoLocationByIP_V4 REST endpoint to retrieve geographic location information,
        /// attempting the primary endpoint first and falling back to the backup if the response is invalid
        /// (Error.Number == "4") in live mode.
        /// </summary>
        /// <param name="input">The input parameters including IP address and license key.</param>
        /// <returns>Deserialized <see cref="IPAVResponse"/>.</returns>
        public static async Task<IPAVResponse> InvokeAsync(GetGeoLocationByIPV4Input input)
        {
            // Use query string parameters so missing/optional fields don't break
            // the URL as path parameters would.
            string url = BuildUrl(input, input.IsLive ? LiveBaseUrl : TrialBaseUrl);
            IPAVResponse response = await Helper.HttpGetAsync<IPAVResponse>(url, input.TimeoutSeconds).ConfigureAwait(false);
            if (input.IsLive && !IsValid(response))
            {
                string fallbackUrl = BuildUrl(input, BackupBaseUrl);
                IPAVResponse fallbackResponse = await Helper.HttpGetAsync<IPAVResponse>(fallbackUrl, input.TimeoutSeconds).ConfigureAwait(false);
                return fallbackResponse;
            }

            return response;
        }

        // Build the full request URL, including URL-encoded query string
        public static string BuildUrl(GetGeoLocationByIPV4Input input, string baseUrl)
        {
            string qs = $"JSON/GetLocationByIP_V4?" +
                        $"IPAddress={HttpUtility.UrlEncode(input.IPAddress)}" +
                        $"&LicenseKey={HttpUtility.UrlEncode(input.LicenseKey)}";
            return baseUrl + qs;
        }

        // Check if the response is valid (no error or error code is not 4)
        private static bool IsValid(IPAVResponse response) =>
            response?.Error == null || response.Error.Number != "4";

        /// <summary>
        /// This is the basic operation for retrieving geographic location, proxy, host name, and US region information
        /// for a given IP address. It consults IP address validation databases to provide details such as city, region,
        /// country, latitude, longitude, proxy status, ISP, and more. The operation returns a single response per IP address.
        /// </summary>
        /// <param name="IPAddress">The IP address to look up, e.g., "209.85.173.104".</param>
        /// <param name="LicenseKey">Your license key to use the service.</param>
        /// <param name="IsLive">Option to use live service or trial service.</param>
        /// <param name="TimeoutSeconds">Timeout, in seconds, for the call to the service.</param>
        public record GetGeoLocationByIPV4Input(
            string IPAddress = "",
            string LicenseKey = "",
            bool IsLive = true,
            int TimeoutSeconds = 15
        );
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace ip_address_validation_dot_net.REST
{
    public class IPAVResponse
    {

        public int Certainty { get; set; }
        public string City { get; set; }
        public string Region { get; set; }
        public string Country { get; set; }
        public string CountryISO3 { get; set; }
        public string CountryISO2 { get; set; }
        public string PostalCode { get; set; }
        public string MetroCode { get; set; }
        public string DMA { get; set; }
        public string StateFIPS { get; set; }
        public string CountyFIPS { get; set; }
        public double Latitude { get; set; }
        public double Longitude { get; set; }
        public string IsProxy { get; set; }
        public string ProxyType { get; set; }
        public string PossibleMobileDevice { get; set; }
        public string ISP { get; set; }
        public string NetblockOwner { get; set; }
        public string HostNames { get; set; }
        public string IPNoteCodes { get; set; }
        public string IPNotes { get; set; }
        public string Debug { get; set; }
        public Error Error { get; set; }

        public override string ToString()
        {
            return $"Certainty: {Certainty}\n" +
                   $"City: {City}\n" +
                   $"Region: {Region}\n" +
                   $"Country: {Country}\n" +
                   $"CountryISO3: {CountryISO3}\n" +
                   $"CountryISO2: {CountryISO2}\n" +
                   $"PostalCode: {PostalCode}\n" +
                   $"MetroCode: {MetroCode}\n" +
                   $"DMA: {DMA}\n" +
                   $"StateFIPS: {StateFIPS}\n" +
                   $"CountyFIPS: {CountyFIPS}\n" +
                   $"Latitude: {Latitude}\n" +
                   $"Longitude: {Longitude}\n" +
                   $"IsProxy: {IsProxy}\n" +
                   $"ProxyType: {ProxyType}\n" +
                   $"PossibleMobileDevice: {PossibleMobileDevice}\n" +
                   $"ISP: {ISP}\n" +
                   $"NetblockOwner: {NetblockOwner}\n" +
                   $"HostNames: {HostNames}\n" +
                   $"IPNoteCodes: {IPNoteCodes}\n" +
                   $"IPNotes: {IPNotes}\n" +
                   $"Debug: {Debug}\n" +
                   $"Error: {Error}\n";
        }

    }
    public class CountryLocation
    {
        public string Country { get; set; }
        public string Cntry { get; set; }
        public string Ctry { get; set; }
        public double Latitude { get; set; }
        public double Longitude { get; set; }
        public string IsPublicProxy { get; set; }
        public Error Error { get; set; }
        public override string ToString()
        {
            return $"Country: {Country}{Environment.NewLine}" +
                   $"Cntry: {Cntry}{Environment.NewLine}" +
                   $"Ctry: {Ctry}{Environment.NewLine}" +
                   $"Longitude: {Longitude}{Environment.NewLine}" +
                   $"Latitude: {Latitude}{Environment.NewLine}" +
                   $"IsPublicProxy: {IsPublicProxy}{Environment.NewLine}" +
                   $"Error: {Error}";
        }
    }
    public class Error
    {
        public string Desc { get; set; }
        public string Number { get; set; }
        public string Location { get; set; }
        public override string ToString()
        {
            return $"Desc: {Desc} " +
                $"Number: {Number} " +
                $"Location: {Location}";
        }
    }

}

using System.Text.Json;
using System.Web;

namespace ip_address_validation_dot_net.REST
{
    public class Helper
    {
        public static T HttpGet<T>(string url, int timeoutSeconds)
        {
            using var httpClient = new HttpClient
            {
                Timeout = TimeSpan.FromSeconds(timeoutSeconds)
            };
            using var request = new HttpRequestMessage(HttpMethod.Get, url);
            using HttpResponseMessage response = httpClient
                .SendAsync(request)
                .GetAwaiter()
                .GetResult();
            response.EnsureSuccessStatusCode();
            using Stream responseStream = response.Content
                .ReadAsStreamAsync()
                .GetAwaiter()
                .GetResult();
            var options = new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            };
            object? obj = JsonSerializer.Deserialize(responseStream, typeof(T), options);
            T result = (T)obj!;
            return result;
        }

        // Asynchronous HTTP GET and JSON deserialize
        public static async Task<T> HttpGetAsync<T>(string url, int timeoutSeconds)
        {
            HttpClient HttpClient = new HttpClient();
            HttpClient.Timeout = TimeSpan.FromSeconds(timeoutSeconds);
            using var httpResponse = await HttpClient.GetAsync(url).ConfigureAwait(false);
            httpResponse.EnsureSuccessStatusCode();
            var stream = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
            return JsonSerializer.Deserialize<T>(stream)!;
        }

        public static string UrlEncode(string value) => HttpUtility.UrlEncode(value ?? string.Empty);
    }
}

IP Address Validation Python Rest Code Snippet

from dataclasses import dataclass
from typing import Optional
import requests
from ipav_response import IPAVResponse, Error

# Endpoint URLs for IP Address Validation GetGeoLocationByIP_V4 REST API
primary_url = 'https://sws.serviceobjects.com/GPP/web.svc/JSON/GetLocationByIP_V4?'
backup_url = 'https://swsbackup.serviceobjects.com/GPP/web.svc/JSON/GetLocationByIP_V4?'
trial_url = 'https://trial.serviceobjects.com/GPP/web.svc/JSON/GetLocationByIP_V4?'

def get_geo_location_by_ipv4(
    ip_address: str,
    license_key: str,
    is_live: bool = True,
    timeout_seconds: int = 15
) -> IPAVResponse:
    """
    Call IP Address Validation GetGeoLocationByIP_V4 API to retrieve geographic location, proxy, host name, and US region information.

    Parameters:
        ip_address: The IP address to look up, e.g., "209.85.173.104".
        license_key: Your license key to use the service.
        is_live: Value to determine whether to use the live or trial servers (default: True).
        timeout_seconds: Timeout, in seconds, for the call to the service (default: 15).

    Returns:
        IPAVResponse: Parsed JSON response with geolocation information or error details.
    """
    params = {
        'IPAddress': ip_address,
        'LicenseKey': license_key
    }

    # Select the base URL: production vs trial
    url = primary_url if is_live else trial_url
    
    try:
        # Attempt primary (or trial) endpoint
        response = requests.get(url, params=params, timeout=timeout_seconds)
        response.raise_for_status()
        data = response.json()

        # If API returned an error in JSON payload, trigger fallback
        error = data.get('Error')
        if not (error is None or error.get('Number') != "4"):
          if is_live:
            # Try backup URL
            response = requests.get(backup_url, params=params, timeout=timeout_seconds)
            response.raise_for_status()
            data = response.json()

            # If still error, propagate exception
            if 'Error' in data:
                raise RuntimeError(f"IPAV service error: {data['Error']}")
          else:
              # Trial mode error is terminal
              raise RuntimeError(f"IPAV trial error: {data['Error']}")

        # Convert JSON response to IPAVResponse for structured access
        error = Error(**data.get('Error', {})) if data.get('Error') else None
        return IPAVResponse(
            IPAddress=data.get('IPAddress'),
            LicenseKey=data.get('LicenseKey'),
            Certainty=data.get('Certainty'),
            City=data.get('City'),
            Region=data.get('Region'),
            Country=data.get('Country'),
            CountryISO3=data.get('CountryISO3'),
            CountryISO2=data.get('CountryISO2'),
            PostalCode=data.get('PostalCode'),
            MetroCode=data.get('MetroCode'),
            DMA=data.get('DMA'),
            StateFIPS=data.get('StateFIPS'),
            CountyFIPS=data.get('CountyFIPS'),
            Latitude=data.get('Latitude'),
            Longitude=data.get('Longitude'),
            IsProxy=data.get('IsProxy'),
            ProxyType=data.get('ProxyType'),
            PossibleMobileDevice=data.get('PossibleMobileDevice'),
            ISP=data.get('ISP'),
            NetblockOwner=data.get('NetblockOwner'),
            HostNames=data.get('HostNames'),
            IPNoteCodes=data.get('IPNoteCodes'),
            IPNotes=data.get('IPNotes'),
            Debug=data.get('Debug'),
            Error=error
        )

    except requests.RequestException as req_exc:
        # Network or HTTP-level error occurred
        if is_live:
            try:
                # Fallback to backup URL on network failure
                response = requests.get(backup_url, params=params, timeout=timeout_seconds)
                response.raise_for_status()
                data = response.json()
                if 'Error' in data:
                    raise RuntimeError(f"IPAV backup error: {data['Error']}") from req_exc

                # Convert JSON response to IPAVResponse for structured access
                error = Error(**data.get('Error', {})) if data.get('Error') else None
                return IPAVResponse(
                    IPAddress=data.get('IPAddress'),
                    LicenseKey=data.get('LicenseKey'),
                    Certainty=data.get('Certainty'),
                    City=data.get('City'),
                    Region=data.get('Region'),
                    Country=data.get('Country'),
                    CountryISO3=data.get('CountryISO3'),
                    CountryISO2=data.get('CountryISO2'),
                    PostalCode=data.get('PostalCode'),
                    MetroCode=data.get('MetroCode'),
                    DMA=data.get('DMA'),
                    StateFIPS=data.get('StateFIPS'),
                    CountyFIPS=data.get('CountyFIPS'),
                    Latitude=data.get('Latitude'),
                    Longitude=data.get('Longitude'),
                    IsProxy=data.get('IsProxy'),
                    ProxyType=data.get('ProxyType'),
                    PossibleMobileDevice=data.get('PossibleMobileDevice'),
                    ISP=data.get('ISP'),
                    NetblockOwner=data.get('NetblockOwner'),
                    HostNames=data.get('HostNames'),
                    IPNoteCodes=data.get('IPNoteCodes'),
                    IPNotes=data.get('IPNotes'),
                    Debug=data.get('Debug'),
                    Error=error
                )
            except Exception as backup_exc:
                raise RuntimeError("IPAV service unreachable on both endpoints") from backup_exc
        else:
            raise RuntimeError(f"IPAV trial error: {str(req_exc)}") from req_exc


from dataclasses import dataclass
from typing import Optional

@dataclass
class Error:
    Desc: Optional[str] = None
    Number: Optional[str] = None
    Location: Optional[str] = None

    def __str__(self) -> str:
        return (f"Error: Desc={self.Desc}, Number={self.Number}, Location={self.Location}")

@dataclass
class IPAVResponse:
    IPAddress: Optional[str] = None
    LicenseKey: Optional[str] = None
    Certainty: Optional[int] = None
    City: Optional[str] = None
    Region: Optional[str] = None
    Country: Optional[str] = None
    CountryISO3: Optional[str] = None
    CountryISO2: Optional[str] = None
    PostalCode: Optional[str] = None
    MetroCode: Optional[str] = None
    DMA: Optional[str] = None
    StateFIPS: Optional[str] = None
    CountyFIPS: Optional[str] = None
    Latitude: Optional[float] = None
    Longitude: Optional[float] = None
    IsProxy: Optional[str] = None
    ProxyType: Optional[str] = None
    PossibleMobileDevice: Optional[str] = None
    ISP: Optional[str] = None
    NetblockOwner: Optional[str] = None
    HostNames: Optional[str] = None
    IPNoteCodes: Optional[str] = None
    IPNotes: Optional[str] = None
    Debug: Optional[str] = None
    Error: Optional[Error] = None

    def __str__(self) -> str:
        error = str(self.Error) if self.Error else "None"
        return (f"IPAVResponse: IPAddress={self.IPAddress}, LicenseKey={self.LicenseKey}, "
                f"Certainty={self.Certainty}, City={self.City}, Region={self.Region}, "
                f"Country={self.Country}, CountryISO3={self.CountryISO3}, CountryISO2={self.CountryISO2}, "
                f"PostalCode={self.PostalCode}, MetroCode={self.MetroCode}, DMA={self.DMA}, "
                f"StateFIPS={self.StateFIPS}, CountyFIPS={self.CountyFIPS}, Latitude={self.Latitude}, "
                f"Longitude={self.Longitude}, IsProxy={self.IsProxy}, ProxyType={self.ProxyType}, "
                f"PossibleMobileDevice={self.PossibleMobileDevice}, ISP={self.ISP}, "
                f"NetblockOwner={self.NetblockOwner}, HostNames={self.HostNames}, "
                f"IPNoteCodes={self.IPNoteCodes}, IPNotes={self.IPNotes}, Debug={self.Debug}, "
                f"Error={error}")

IP Address Validation NodeJS Rest Code Snippet

import axios from 'axios';
import querystring from 'querystring';
import { IPAVResponse } from './ipav_response.js';

/**
 * @constant
 * @type {string}
 * @description The base URL for the live ServiceObjects IP Address Validation API service.
 */
const LiveBaseUrl = 'https://sws.serviceobjects.com/GPP/web.svc/';

/**
 * @constant
 * @type {string}
 * @description The base URL for the backup ServiceObjects IP Address Validation API service.
 */
const BackupBaseUrl = 'https://swsbackup.serviceobjects.com/GPP/web.svc/';

/**
 * @constant
 * @type {string}
 * @description The base URL for the trial ServiceObjects IP Address Validation API service.
 */
const TrialBaseUrl = 'https://trial.serviceobjects.com/GPP/web.svc/';

/**
 * <summary>
 * Checks if a response from the API is valid by verifying that it either has no Error object
 * or the Error.Number is not equal to '4'.
 * </summary>
 * <param name="response" type="Object">The API response object to validate.</param>
 * <returns type="boolean">True if the response is valid, false otherwise.</returns>
 */
const isValid = (response) => !response?.Error || response.Error.Number !== '4';

/**
 * <summary>
 * Constructs a full URL for the GetGeoLocationByIP_V4 API endpoint by combining the base URL
 * with query parameters derived from the input parameters.
 * </summary>
 * <param name="params" type="Object">An object containing all the input parameters.</param>
 * <param name="baseUrl" type="string">The base URL for the API service (live, backup, or trial).</param>
 * <returns type="string">The constructed URL with query parameters.</returns>
 */
const buildUrl = (params, baseUrl) =>
    `${baseUrl}JSON/GetLocationByIP_V4?${querystring.stringify(params)}`;

/**
 * <summary>
 * Performs an HTTP GET request to the specified URL with a given timeout.
 * </summary>
 * <param name="url" type="string">The URL to send the GET request to.</param>
 * <param name="timeoutSeconds" type="number">The timeout duration in seconds for the request.</param>
 * <returns type="Promise<IPAVResponse>">A promise that resolves to an IPAVResponse object containing the API response data.</returns>
 * <exception cref="Error">Thrown if the HTTP request fails, with a message detailing the error.</exception>
 */
const httpGet = async (url, timeoutSeconds) => {
  try {
    const response = await axios.get(url, { timeout: timeoutSeconds * 1000 });
    return new IPAVResponse(response.data);
  } catch (error) {
    throw new Error(`HTTP request failed: ${error.message}`);
  }
};

/**
 * <summary>
 * Provides functionality to call the ServiceObjects IP Address Validation API's GetGeoLocationByIP_V4 endpoint,
 * retrieving geographic location, proxy, host name, and US region information with fallback to a backup endpoint for reliability in live mode.
 * </summary>
 */
const GetGeoLocationByIPV4Client = {
    /**
     * <summary>
     * Asynchronously invokes the GetGeoLocationByIP_V4 API endpoint, attempting the primary endpoint
     * first and falling back to the backup if the response is invalid (Error.Number == '4') in live mode.
     * </summary>
     * @param {string} IPAddress - The IP address to look up, e.g., "209.85.173.104".
     * @param {string} LicenseKey - Your license key to use the service.
     * @param {boolean} isLive - Value to determine whether to use the live or trial servers.
     * @param {number} timeoutSeconds - Timeout, in seconds, for the call to the service.
     * @returns {Promise<IPAVResponse>} - A promise that resolves to an IPAVResponse object.
     */
    async invokeAsync(IPAddress, LicenseKey, isLive = true, timeoutSeconds = 15) {
        const params = {
            IPAddress,
            LicenseKey
        };

        const url = buildUrl(params, isLive ? LiveBaseUrl : TrialBaseUrl);
        let response = await httpGet(url, timeoutSeconds);

        if (isLive && !isValid(response)) {
            const fallbackUrl = buildUrl(params, BackupBaseUrl);
            const fallbackResponse = await httpGet(fallbackUrl, timeoutSeconds);
            return isValid(fallbackResponse) ? fallbackResponse : response;
        }

        return response;
    },

    /**
     * <summary>
     * Synchronously invokes the GetGeoLocationByIP_V4 API endpoint by wrapping the async call
     * and awaiting its result immediately.
     * </summary>
     * @returns {IPAVResponse} - An IPAVResponse object with geographic location details or an error.
     */
    invoke(IPAddress, LicenseKey, isLive = true, timeoutSeconds = 15) {
        return (async () => await this.invokeAsync(
            IPAddress, LicenseKey, isLive, timeoutSeconds
        ))();
    }
};

export { GetGeoLocationByIPV4Client, IPAVResponse };


export class Error {
    constructor(data = {}) {
        this.Desc = data.Desc;
        this.Number = data.Number;
        this.Location = data.Location;
    }

    toString() {
        return `Error: Desc = ${this.Desc}, Number = ${this.Number}, Location = ${this.Location}`;
    }
}

export class IPAVResponse {
    constructor(data = {}) {
        this.IPAddress = data.IPAddress;
        this.LicenseKey = data.LicenseKey;
        this.Certainty = data.Certainty || 0;
        this.City = data.City;
        this.Region = data.Region;
        this.Country = data.Country;
        this.CountryISO3 = data.CountryISO3;
        this.CountryISO2 = data.CountryISO2;
        this.PostalCode = data.PostalCode;
        this.MetroCode = data.MetroCode;
        this.DMA = data.DMA;
        this.StateFIPS = data.StateFIPS;
        this.CountyFIPS = data.CountyFIPS;
        this.Latitude = data.Latitude;
        this.Longitude = data.Longitude;
        this.IsProxy = data.IsProxy;
        this.ProxyType = data.ProxyType;
        this.PossibleMobileDevice = data.PossibleMobileDevice;
        this.ISP = data.ISP;
        this.NetblockOwner = data.NetblockOwner;
        this.HostNames = data.HostNames;
        this.IPNoteCodes = data.IPNoteCodes;
        this.IPNotes = data.IPNotes;
        this.Debug = data.Debug;
        this.Error = data.Error ? new Error(data.Error) : null;
    }

    toString() {
        return `IPAVResponse: IPAddress = ${this.IPAddress ?? 'null'}, LicenseKey = ${this.LicenseKey ?? 'null'}, ` +
               `Certainty = ${this.Certainty}, City = ${this.City ?? 'null'}, Region = ${this.Region ?? 'null'}, ` +
               `Country = ${this.Country ?? 'null'}, CountryISO3 = ${this.CountryISO3 ?? 'null'}, ` +
               `CountryISO2 = ${this.CountryISO2 ?? 'null'}, PostalCode = ${this.PostalCode ?? 'null'}, ` +
               `MetroCode = ${this.MetroCode ?? 'null'}, DMA = ${this.DMA ?? 'null'}, ` +
               `StateFIPS = ${this.StateFIPS ?? 'null'}, CountyFIPS = ${this.CountyFIPS ?? 'null'}, ` +
               `Latitude = ${this.Latitude ?? 'null'}, Longitude = ${this.Longitude ?? 'null'}, ` +
               `IsProxy = ${this.IsProxy ?? 'null'}, ProxyType = ${this.ProxyType ?? 'null'}, ` +
               `PossibleMobileDevice = ${this.PossibleMobileDevice ?? 'null'}, ISP = ${this.ISP ?? 'null'}, ` +
               `NetblockOwner = ${this.NetblockOwner ?? 'null'}, HostNames = ${this.HostNames ?? 'null'}, ` +
               `IPNoteCodes = ${this.IPNoteCodes ?? 'null'}, IPNotes = ${this.IPNotes ?? 'null'}, ` +
               `Debug = ${this.Debug ?? 'null'}, Error = ${this.Error ? this.Error.toString() : 'null'}`;
    }
}

export default IPAVResponse;