{"id":2476,"date":"2022-11-09T07:10:33","date_gmt":"2022-11-09T07:10:33","guid":{"rendered":"https:\/\/serviceobjects.wpaladdin.com\/?post_type=serviceobjects&#038;p=2476"},"modified":"2025-09-27T11:14:59","modified_gmt":"2025-09-27T18:14:59","slug":"agus-rest","status":"publish","type":"page","link":"https:\/\/www.serviceobjects.com\/docs\/dots-address-geocode-us\/agus-code-snippets-and-sample-code\/agus-rest\/","title":{"rendered":"AGUS &#8211; REST"},"content":{"rendered":"\n<div class=\"wp-block-create-block-tabs\"><ul class=\"tab-labels\" role=\"tablist\" aria-label=\"tabbed content\"><li class=\"tab-label active\" role=\"tab\" aria-selected=\"true\" aria-controls=\"C#\" tabindex=\"0\">C#<\/li><li class=\"tab-label\" role=\"tab\" aria-selected=\"false\" aria-controls=\"Python\" tabindex=\"0\">Python<\/li><li class=\"tab-label\" role=\"tab\" aria-selected=\"false\" aria-controls=\"NodeJS\" tabindex=\"0\">NodeJS<\/li><\/ul><div class=\"tab-content\">\n<div class=\"wp-block-create-block-tab tab-panel\" role=\"tabpanel\" tabindex=\"0\">\n<p><strong>Address Geocode &#8211; US C# Code Snippet<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">using System.Web;\n\nnamespace address_geocode_us_dot_net.REST\n{\n    \/\/\/ &lt;summary>\n    \/\/\/ Provides functionality to call the ServiceObjects Address Geocode US (AGUS) REST API's GetBestMatch_V4 endpoint,\n    \/\/\/ retrieving geocoding info rmation (e.g., latitude, longitude, ZIP code) for a given US address with fallback to a backup endpoint\n    \/\/\/ for reliability in live mode.\n    \/\/\/ &lt;\/summary>\n    public static class GetBestMatchV4Client\n    {\n        \/\/ Base URL constants: production, backup, and trial\n        private const string LiveBaseUrl = \"https:\/\/sws.serviceobjects.com\/GCR\/api.svc\/json\/\";\n        private const string BackupBaseUrl = \"https:\/\/swsbackup.serviceobjects.com\/GCR\/api.svc\/json\/\";\n        private const string TrialBaseUrl = \"https:\/\/trial.serviceobjects.com\/GCR\/api.svc\/json\/\";\n\n        \/\/\/ &lt;summary>\n        \/\/\/ Synchronously calls the GetBestMatch_V4 REST endpoint to retrieve geocoding information,\n        \/\/\/ attempting the primary endpoint first and falling back to the backup if the response is invalid\n        \/\/\/ (Error.Number == \"4\") in live mode.\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;param name=\"input\">The input parameters including address, city, state, postal code, and license key.&lt;\/param>\n        \/\/\/ &lt;returns>Deserialized &lt;see cref=\"GetBestMatchV4Response\"\/> containing geocoding data or an error.&lt;\/returns>\n        public static GetBestMatchV4Response Invoke(GetBestMatchV4Input input)\n        {\n            \/\/Use query string parameters so missing\/options fields don't break\n            \/\/the URL as path parameters would.\n            string url = BuildUrl(input, input.IsLive ? LiveBaseUrl : TrialBaseUrl);\n            GetBestMatchV4Response response = Helper.HttpGet&lt;GetBestMatchV4Response>(url, input.TimeoutSeconds);\n\n            \/\/ Fallback on error in live mode\n            if (input.IsLive &amp;&amp; !IsValid(response))\n            {\n                string fallbackUrl = BuildUrl(input, BackupBaseUrl);\n                GetBestMatchV4Response fallbackResponse = Helper.HttpGet&lt;GetBestMatchV4Response>(fallbackUrl, input.TimeoutSeconds);\n                return fallbackResponse;\n            }\n\n            return response;\n        }\n\n        \/\/\/ &lt;summary>\n        \/\/\/ Asynchronously calls the GetBestMatch_V4 REST endpoint to retrieve geocoding information,\n        \/\/\/ attempting the primary endpoint first and falling back to the backup if the response is invalid\n        \/\/\/ (Error.Number == \"4\") in live mode.\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;param name=\"input\">The input parameters including address, city, state, postal code, and license key.&lt;\/param>\n        \/\/\/ &lt;returns>Deserialized &lt;see cref=\"GetBestMatchV4Response\"\/> containing geocoding data or an error.&lt;\/returns>\n        public static async Task&lt;GetBestMatchV4Response> InvokeAsync(GetBestMatchV4Input input)\n        {\n            \/\/Use query string parameters so missing\/options fields don't break\n            \/\/the URL as path parameters would.\n            string url = BuildUrl(input, input.IsLive ? LiveBaseUrl : TrialBaseUrl);\n            GetBestMatchV4Response response = await Helper.HttpGetAsync&lt;GetBestMatchV4Response>(url, input.TimeoutSeconds).ConfigureAwait(false);\n\n            \/\/ Fallback on error in live mode\n            if (input.IsLive &amp;&amp; !IsValid(response))\n            {\n                string fallbackUrl = BuildUrl(input, BackupBaseUrl);\n                GetBestMatchV4Response fallbackResponse = await Helper.HttpGetAsync&lt;GetBestMatchV4Response>(fallbackUrl, input.TimeoutSeconds).ConfigureAwait(false);\n                return fallbackResponse;\n            }\n\n            return response;\n        }\n\n        \/\/\/ &lt;summary>\n        \/\/\/ Builds the full request URL for the GetBestMatch_V4 endpoint, including URL-encoded query string parameters.\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;param name=\"input\">The input parameters for the API call.&lt;\/param>\n        \/\/\/ &lt;param name=\"baseUrl\">The base URL (live, backup, or trial).&lt;\/param>\n        \/\/\/ &lt;returns>The complete URL with query string.&lt;\/returns>\n        public static string BuildUrl(GetBestMatchV4Input input, string baseUrl)\n        {\n            \/\/ Construct query string with URL-encoded parameters\n            string qs = $\"GetBestMatch_V4?\" +\n                     $\"Address={HttpUtility.UrlEncode(input.Address)}\" +\n                     $\"&amp;City={HttpUtility.UrlEncode(input.City)}\" +\n                     $\"&amp;State={HttpUtility.UrlEncode(input.State)}\" +\n                     $\"&amp;PostalCode={HttpUtility.UrlEncode(input.PostalCode)}\" +\n                     $\"&amp;LicenseKey={HttpUtility.UrlEncode(input.LicenseKey)}\";\n            return baseUrl + qs;\n        }\n    \n        private static bool IsValid(GetBestMatchV4Response response) => response?.Error == null || response.Error.Number != \"4\";\n\n        \/\/\/ &lt;summary>\n        \/\/\/ Input parameters for the GetBestMatch_V4 API call. Represents a US address to geocode\n        \/\/\/ and returns latitude and longitude with cascading logic for partial matches.\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;param name=\"Address\">Address line of the address to geocode (e.g., \u201c123 Main Street\u201d).&lt;\/param>\n        \/\/\/ &lt;param name=\"City\">The city of the address to geocode (e.g., \u201cNew York\u201d). Optional if postal code is provided.&lt;\/param>\n        \/\/\/ &lt;param name=\"State\">The state of the address to geocode (e.g., \u201cNY\u201d). Optional if postal code is provided.&lt;\/param>\n        \/\/\/ &lt;param name=\"PostalCode\">The ZIP code of the address to geocode. Optional if city and state are provided.&lt;\/param>\n        \/\/\/ &lt;param name=\"LicenseKey\">The license key to authenticate the API request.&lt;\/param>\n        \/\/\/ &lt;param name=\"IsLive\">Indicates whether to use the live service (true) or trial service (false).&lt;\/param>\n        \/\/\/ &lt;param name=\"TimeoutSeconds\">Timeout duration for the API call, in seconds.&lt;\/param>\n        public record GetBestMatchV4Input(\n            string Address = \"\",\n            string City = \"\",\n            string State = \"\",\n            string PostalCode = \"\",\n            string LicenseKey = \"\",\n            bool IsLive = true,\n            int TimeoutSeconds = 15\n        );\n    }\n}\n\nusing System.Runtime.Serialization;\n\nnamespace address_geocode_us_dot_net.REST\n{\n\n    \/\/\/ &lt;summary>\n    \/\/\/ Response from GetBestMatch_V4 API\n    \/\/\/ &lt;\/summary>\n    [DataContract]\n\n    public class GetBestMatchV4Response\n    {\n        public string Level { get; set; }\n        public string LevelDescription { get; set; }\n        public string Latitude { get; set; }\n        public string Longitude { get; set; }\n        public string Zip { get; set; }\n        public InformationComponent[] InformationComponents { get; set; }\n        public Error Error { get; set; }\n        public override string ToString()\n        {\n            string infoComponentsString = InformationComponents != null\n                ? string.Join(\", \", InformationComponents.Select(ic => ic.ToString()))\n                : \"null\";\n\n            return $\"Level: {Level}\\n\" +\n                   $\"LevelDescription: {LevelDescription}\\n\" +\n                   $\"Latitude: {Latitude}\\n\" +\n                   $\"Longitude: {Longitude}\\n\" +\n                   $\"Zip: {Zip}\\n\" +\n                   $\"InformationComponents: [{infoComponentsString}]\\n\" +\n                   $\"Error: {(Error != null ? Error.ToString() : \"null\")}\";\n        }\n    }\n\n    \/\/\/ &lt;summary>\n    \/\/\/ Information Component for GetBestMatch_V4\n    \/\/\/ &lt;\/summary>\n    [DataContract]\n    public class InformationComponent\n    {\n        public string Name { get; set; }\n        public string Value { get; set; }\n        public override string ToString()\n        {\n            return $\"Name: {Name}, Value: {Value}\";\n        }\n    }\n\n\n    \/\/\/ &lt;summary>\n    \/\/\/ Response from GetDistanceToWater API, containing the estimated distance to the nearest saltwater\n    \/\/\/ and the coordinates of the closest saltwater location.\n    \/\/\/ &lt;\/summary>\n    [DataContract]\n    public class GetDistanceToWaterResponse\n    {\n        public string DistanceToWater { get; set; }\n        public string Latitude { get; set; }\n        public string Longitude { get; set; }\n        public string WaterLat { get; set; }\n        public string WaterLon { get; set; }\n        public Error Error { get; set; }\n\n        public override string ToString()\n        {\n            return $\"MilesToWater: {DistanceToWater}\\n\" +\n                   $\"Latitude: {Latitude}\\n\" +\n                   $\"Longitude: {Longitude}\\n\" +\n                   $\"ClosestWaterLatitude: {WaterLat}\\n\" +\n                   $\"ClosestWaterLongitude: {WaterLon}\\n\" +\n                   $\"Error: {(Error != null ? Error.ToString() : \"null\")}\";\n        }\n    }\n\n\n    \/\/\/ &lt;summary>\n    \/\/\/ Response from GetReverseLocation API, containing the estimated address, city, state, ZIP code,\n    \/\/\/ and county for the given coordinates.\n    \/\/\/ &lt;\/summary>\n    [DataContract]\n    public class GetReverseLocationResponse\n    {\n        public string Address { get; set; }\n        public string City { get; set; }\n        public string State { get; set; }\n        public string Zip { get; set; }\n        public string County { get; set; }\n        public Error Error { get; set; }\n        public override string ToString()\n        {\n            return $\"Address: {Address}\\n\" +\n                   $\"City: {City}\\n\" +\n                   $\"State: {State}\\n\" +\n                   $\"Zip: {Zip}\\n\" +\n                   $\"County: {County}\\n\" +\n                   $\"Error: {(Error != null ? Error.ToString() : \"null\")}\";\n        }\n    }\n    \/\/\/ &lt;summary>\n    \/\/\/ Error object for API responses\n    \/\/\/ &lt;\/summary>\n    [DataContract]\n    public class Error\n    {\n        public string Desc { get; set; }\n        public string Number { get; set; }\n        public string Location { get; set; }\n        public override string ToString()\n        {\n            return $\"Desc: {Desc}, TypeCode: {Number}, Location: {Location}\";\n        }\n    }\n}\n\n\ufeffusing System.Text.Json;\nusing System.Web;\n\nnamespace address_geocode_us_dot_net.REST\n{\n    public class Helper\n    {\n        public static T HttpGet&lt;T>(string url, int timeoutSeconds)\n        {\n            using var httpClient = new HttpClient\n            {\n                Timeout = TimeSpan.FromSeconds(timeoutSeconds)\n            };\n            using var request = new HttpRequestMessage(HttpMethod.Get, url);\n            using HttpResponseMessage response = httpClient\n                .SendAsync(request)\n                .GetAwaiter()\n                .GetResult();\n            response.EnsureSuccessStatusCode();\n            using Stream responseStream = response.Content\n                .ReadAsStreamAsync()\n                .GetAwaiter()\n                .GetResult();\n            var options = new JsonSerializerOptions\n            {\n                PropertyNameCaseInsensitive = true\n            };\n            object? obj = JsonSerializer.Deserialize(responseStream, typeof(T), options);\n            T result = (T)obj!;\n            return result;\n        }\n\n        \/\/ Asynchronous HTTP GET and JSON deserialize\n        public static async Task&lt;T> HttpGetAsync&lt;T>(string url, int timeoutSeconds)\n        {\n            HttpClient HttpClient = new HttpClient();\n            HttpClient.Timeout = TimeSpan.FromSeconds(timeoutSeconds);\n            using var httpResponse = await HttpClient.GetAsync(url).ConfigureAwait(false);\n            httpResponse.EnsureSuccessStatusCode();\n            var stream = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);\n            return JsonSerializer.Deserialize&lt;T>(stream)!;\n        }\n\n        public static string UrlEncode(string value) => HttpUtility.UrlEncode(value ?? string.Empty);\n    }\n}\n<\/pre>\n<\/div>\n\n\n\n<div class=\"wp-block-create-block-tab tab-panel\" role=\"tabpanel\" tabindex=\"0\">\n<p><strong>Address Geocode &#8211; US Python Code Snippet<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import requests\nfrom agus_response import GetBestMatchV4Response, Error, InformationComponent\n\n# Endpoint URLs for ServiceObjects Address Geocode US (AGUS) API\nprimary_url = \"https:\/\/sws.serviceobjects.com\/GCR\/api.svc\/json\/GetBestMatch_V4?\"\nbackup_url = \"https:\/\/swsbackup.serviceobjects.com\/GCR\/api.svc\/json\/GetBestMatch_V4?\"\ntrial_url = \"https:\/\/trial.serviceobjects.com\/GCR\/api.svc\/json\/GetBestMatch_V4?\"\n\ndef get_best_match_v4(\n    address: str,\n    city: str,\n    state: str,\n    postal_code: str,\n    license_key: str,\n    is_live: bool = True) -> GetBestMatchV4Response:\n    \"\"\"\n    Call ServiceObjects Address Geocode US (AGUS) API's GetBestMatch_V4 endpoint\n    to retrieve geocoding information (latitude, longitude, ZIP code, etc.).\n\n    Parameters:\n        address: Address line of the address to geocode (e.g., \"123 Main Street\").\n        city: The city of the address to geocode. For example, \"New York\".\n        state: The state of the address to geocode. For example, \"NY\".\n        postal_code: The postal code of the address to geocode. For example, \"10001\".\n        license_key: Your ServiceObjects license key.\n        is_live: Use live or trial servers.\n\n    Returns:\n        GetBestMatchV4Response: Parsed JSON response with geocoding results or error details.\n\n    Raises:\n        RuntimeError: If the API call fails on both primary and backup endpoints or if JSON parsing fails.\n    \"\"\"\n    params = {\n        \"Address\": address,\n        \"City\": city,\n        \"State\": state,\n        \"PostalCode\": postal_code,\n        \"LicenseKey\": license_key,\n    }\n    # Select the base URL: production vs trial\n    url = primary_url if is_live else trial_url\n\n    try:\n        # Attempt primary (or trial) endpoint\n        response = requests.get(url, params=params, timeout=10)\n        response.raise_for_status()\n        data = response.json()\n\n         # If API returned an error in JSON payload, trigger fallback\n        error = getattr(response, 'Error', None)\n        if not (error is None or getattr(error, 'Number', None) != \"4\"):\n            if is_live:\n                # Try backup URL\n                response = requests.get(backup_url, params=params, timeout=10)\n                data = response.json()\n\n                # If still error, propagate exception\n                if 'Error' in data:\n                    raise RuntimeError(f\"AGUS service error: {data['Error']}\")\n            else:\n                # Trial mode error is terminal\n                raise RuntimeError(f\"AGUS trial error: {data['Error']}\")\n\n        # Convert JSON response to GetBestMatchV4Response for structured access\n        error = Error(**data.get(\"Error\", {})) if data.get(\"Error\") else None\n\n        return GetBestMatchV4Response(\n          Level=data.get(\"Level\"),\n          LevelDescription=data.get(\"LevelDescription\"),\n          Latitude=data.get(\"Latitude\"),\n          Longitude=data.get(\"Longitude\"),\n          Zip=data.get(\"Zip\"),\n          InformationComponents=[\n              InformationComponent(Name=comp.get(\"Name\"), Value=comp.get(\"Value\"))\n              for comp in data.get(\"InformationComponents\", [])\n          ] if \"InformationComponents\" in data else [],\n            Error=error,\n          )\n\n    except requests.RequestException as req_exc:\n        # Network or HTTP-level error occurred\n        if is_live:\n            try:\n                # Fallback to backup URL\n                response = requests.get(backup_url, params=params, timeout=10)\n                response.raise_for_status()\n                data = response.json()\n                if \"Error\" in data:\n                    raise RuntimeError(f\"AGUS backup error: {data['Error']}\") from req_exc\n\n                error = Error(**data.get(\"Error\", {})) if data.get(\"Error\") else None\n\n                return GetBestMatchV4Response(\n                    Level=data.get(\"Level\"),\n                    LevelDescription=data.get(\"LevelDescription\"),\n                    Latitude=data.get(\"Latitude\"),\n                    Longitude=data.get(\"Longitude\"),\n                    Zip=data.get(\"Zip\"),\n                    InformationComponents=[\n                        InformationComponent(Name=comp.get(\"Name\"), Value=comp.get(\"Value\"))\n                        for comp in data.get(\"InformationComponents\", [])\n                    ] if \"InformationComponents\" in data else [],\n                    Error=error,\n                )\n            except Exception as backup_exc:\n                raise RuntimeError(\"AGUS service unreachable on both endpoints\") from backup_exc\n        else:\n            raise RuntimeError(f\"AGUS trial error: {str(req_exc)}\") from req_exc\n\nfrom dataclasses import dataclass\nfrom typing import Optional, List\n\n\n@dataclass\nclass GetDistanceToWaterInput:\n    Latitude: Optional[float] = None\n    Longitude: Optional[float] = None\n    LicenseKey: Optional[str] = None\n    IsLive: bool = True\n    TimeoutSeconds: int = 15\n\n    def __str__(self) -> str:\n        return (f\"GetDistanceToWaterInput: Latitude={self.Latitude}, Longitude={self.Longitude}, \"\n                f\"LicenseKey={self.LicenseKey}, IsLive={self.IsLive}, TimeoutSeconds={self.TimeoutSeconds}\")\n\n\n@dataclass\nclass InformationComponent:\n    Name: Optional[str] = None\n    Value: Optional[str] = None\n\n    def __str__(self) -> str:\n        return f\"InformationComponent: Name={self.Name}, Value={self.Value}\"\n\n\n@dataclass\nclass Error:\n    Desc: Optional[str] = None\n    Number: Optional[str] = None\n    Location: Optional[str] = None\n\n    def __str__(self) -> str:\n        return (f\"Error: Desc={self.Desc}, Number={self.Number}, Location={self.Location}\")\n\n\n@dataclass\nclass GetBestMatchV4Response:\n    Level: Optional[str] = None\n    LevelDescription: Optional[str] = None\n    Latitude: Optional[float] = None\n    Longitude: Optional[float] = None\n    Zip: Optional[str] = None\n    InformationComponents: Optional[List['InformationComponent']] = None\n    Error: Optional['Error'] = None\n\n    def __post_init__(self):\n        if self.InformationComponents is None:\n            self.InformationComponents = []\n\n    def __str__(self) -> str:\n        components_string = ', '.join(str(component) for component in self.InformationComponents) if self.InformationComponents else 'None'\n        error = str(self.Error) if self.Error else 'None'\n        return (f\"GetBestMatchV4Response: Level={self.Level}, LevelDescription={self.LevelDescription}, \"\n                f\"Latitude={self.Latitude}, Longitude={self.Longitude}, Zip={self.Zip}, \"\n                f\"InformationComponents=[{components_string}], Error={error}\")\n\n\n@dataclass\nclass GetDistanceToWaterResponse:\n    DistanceToWater: Optional[float] = None\n    Latitude: Optional[float] = None\n    Longitude: Optional[float] = None\n    WaterLat: Optional[float] = None\n    WaterLon: Optional[float] = None\n    Error: Optional['Error'] = None\n\n    def __str__(self) -> str:\n        error = str(self.Error) if self.Error else 'None'\n        return (f\"GetDistanceToWaterResponse: DistanceToWater={self.DistanceToWater}, Latitude={self.Latitude}, \"\n                f\"Longitude={self.Longitude}, WaterLat={self.WaterLat}, WaterLon={self.WaterLon}, Error={error}\")\n\n\n@dataclass\nclass GetReverseLocationResponse:\n    Address: Optional[str] = None\n    City: Optional[str] = None\n    State: Optional[str] = None\n    Zip: Optional[str] = None\n    County: Optional[str] = None\n    Error: Optional['Error'] = None\n\n    def __str__(self) -> str:\n        error = str(self.Error) if self.Error else 'None'\n        return (f\"GetReverseLocationResponse: Address={self.Address}, City={self.City}, State={self.State}, \"\n                f\"Zip={self.Zip}, County={self.County}, Error={error}\")<\/pre>\n<\/div>\n\n\n\n<div class=\"wp-block-create-block-tab tab-panel\" role=\"tabpanel\" tabindex=\"0\">\n<p><strong>Address GeoCoder NodeJS Code Snippet<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\nimport axios from 'axios';\nimport querystring from 'querystring';\nimport { GetBestMatchV4Response } from '.\/agus_response.js';\n\n\/**\n * @constant\n * @type {string}\n * @description The base URL for the live ServiceObjects Address Geocode US (AGUS) API service.\n *\/\nconst liveBaseUrl = 'https:\/\/sws.serviceobjects.com\/GCR\/api.svc\/json\/';\n\n\/**\n * @constant\n * @type {string}\n * @description The base URL for the backup ServiceObjects Address Geocode US (AGUS) API service.\n *\/\nconst backupBaseUrl = 'https:\/\/swsbackup.serviceobjects.com\/GCR\/api.svc\/json\/';\n\n\/**\n * @constant\n * @type {string}\n * @description The base URL for the trial ServiceObjects Address Geocode US (AGUS) API service.\n *\/\nconst trialBaseUrl = 'https:\/\/trial.serviceobjects.com\/GCR\/api.svc\/json\/';\n\n\/**\n * &lt;summary>\n * Checks if a response from the API is valid by verifying that it either has no Error object\n * or the Error.Number is not equal to '4'.\n * &lt;\/summary>\n * &lt;param name=\"response\" type=\"Object\">The API response object to validate.&lt;\/param>\n * &lt;returns type=\"boolean\">True if the response is valid, false otherwise.&lt;\/returns>\n *\/\nconst isValid = (response) => !response?.Error || response.Error.Number !== '4';\n\n\/**\n * &lt;summary>\n * Constructs a full URL for the GetBestMatch_V4 API endpoint by combining the base URL\n * with query parameters derived from the input parameters.\n * &lt;\/summary>\n * &lt;param name=\"params\" type=\"Object\">An object containing all the input parameters.&lt;\/param>\n * &lt;param name=\"baseUrl\" type=\"string\">The base URL for the API service (live, backup, or trial).&lt;\/param>\n * &lt;returns type=\"string\">The constructed URL with query parameters.&lt;\/returns>\n *\/\nconst buildUrl = (params, baseUrl) =>\n    `${baseUrl}GetBestMatch_V4?${querystring.stringify(params)}`;\n\n\/**\n * &lt;summary>\n * Performs an HTTP GET request to the specified URL with a given timeout.\n * &lt;\/summary>\n * &lt;param name=\"url\" type=\"string\">The URL to send the GET request to.&lt;\/param>\n * &lt;param name=\"timeoutSeconds\" type=\"number\">The timeout duration in seconds for the request.&lt;\/param>\n * &lt;returns type=\"Promise&lt;GetBestMatchV4Response>\">A promise that resolves to a GetBestMatchV4Response object containing the API response data.&lt;\/returns>\n * &lt;exception cref=\"Error\">Thrown if the HTTP request fails, with a message detailing the error.&lt;\/exception>\n *\/\nconst httpGet = async (url, timeoutSeconds) => {\n    try {\n        const response = await axios.get(url, { timeout: timeoutSeconds * 1000 });\n        return new GetBestMatchV4Response(response.data);\n    } catch (error) {\n        throw new Error(`HTTP request failed: ${error.message}`);\n    }\n};\n\n\/**\n * &lt;summary>\n * Provides functionality to call the ServiceObjects Address Geocode US (AGUS) API's GetBestMatch_V4 endpoint,\n * retrieving geocoding information (e.g., latitude, longitude, ZIP code) for a given US address with fallback to a backup endpoint for reliability in live mode.\n * &lt;\/summary>\n *\/\nconst GetBestMatchV4Client = {\n    \/**\n     * &lt;summary>\n     * Asynchronously invokes the GetBestMatch_V4 API endpoint, attempting the primary endpoint\n     * first and falling back to the backup if the response is invalid (Error.Number == '4') in live mode.\n     * &lt;\/summary>\n     * @param {string} Address - Address line of the address to geocode (e.g., \"123 Main Street\").\n     * @param {string} City - The city of the address to geocode. For example, \u201cNew York\u201d. The city isn\u2019t required, but if one is not provided, the Zip code is required..\n     * @param {string} State - The state of the address to geocode. For example, \u201cNY\u201d. This does not need to be contracted, full state names will work as well. The state isn\u2019t required, but if one is not provided, the Zip code is required..\n     * @param {string} PostalCode - The state of the address to geocode. For example, \u201cNY\u201d. This does not need to be contracted, full state names will work as well. The state isn\u2019t required, but if one is not provided, the Zip code is required..\n     * @param {string} LicenseKey - Your license key to use the service.\n     * @param {boolean} isLive - Value to determine whether to use the live or trial servers.\n     * @param {number} timeoutSeconds - Timeout, in seconds, for the call to the service.\n     * @returns {Promise&lt;GetBestMatchV4Response>} - A promise that resolves to a GetBestMatchV4Response object.\n     *\/\n    async invokeAsync(Address, City, State, PostalCode, LicenseKey, isLive = true, timeoutSeconds = 15) {\n        const params = {\n            Address,\n            City,\n            State,\n            PostalCode,\n            LicenseKey\n        };\n\n        const url = buildUrl(params, isLive ? liveBaseUrl : trialBaseUrl);\n        let response = await httpGet(url, timeoutSeconds);\n\n        if (isLive &amp;&amp; !isValid(response)) {\n            const fallbackUrl = buildUrl(params, backupBaseUrl);\n            const fallbackResponse = await httpGet(fallbackUrl, timeoutSeconds);\n            return fallbackResponse;\n        }\n        return response;\n    },\n\n    \/**\n     * &lt;summary>\n     * Synchronously invokes the GetBestMatch_V4 API endpoint by wrapping the async call\n     * and awaiting its result immediately.\n     * &lt;\/summary>\n     * @param {string} Address - Address line of the address to geocode (e.g., \"123 Main Street\").\n     * @param {string} City - The city of the address to geocode. For example, \u201cNew York\u201d. The city isn\u2019t required, but if one is not provided, the Zip code is required..\n     * @param {string} State - The state of the address to geocode. For example, \u201cNY\u201d. This does not need to be contracted, full state names will work as well. The state isn\u2019t required, but if one is not provided, the Zip code is required..\n     * @param {string} PostalCode - The state of the address to geocode. For example, \u201cNY\u201d. This does not need to be contracted, full state names will work as well. The state isn\u2019t required, but if one is not provided, the Zip code is required..\n     * @param {string} LicenseKey - Your license key to use the service.\n     * @param {boolean} isLive - Value to determine whether to use the live or trial servers.\n     * @param {number} timeoutSeconds - Timeout, in seconds, for the call to the service.\n     * @returns {GetBestMatchV4Response} - A GetBestMatchV4Response object with geocoding details or an error.\n     *\/\n    invoke(Address, City, State, PostalCode, LicenseKey, isLive = true, timeoutSeconds = 15) {\n        return (async () => await this.invokeAsync(\n            Address, City, State, PostalCode, LicenseKey, isLive, timeoutSeconds\n        ))();\n    }\n};\n\nexport { GetBestMatchV4Client, GetBestMatchV4Response };\n\n\n\nexport class GetDistanceToWaterInput {\n    constructor(data = {}) {\n        this.Latitude = data.Latitude;\n        this.Longitude = data.Longitude;\n        this.LicenseKey = data.LicenseKey;\n        this.IsLive = data.IsLive !== undefined ? data.IsLive : true;\n        this.TimeoutSeconds = data.TimeoutSeconds !== undefined ? data.TimeoutSeconds : 15;\n    }\n\n    toString() {\n        return `GetDistanceToWaterInput: Latitude = ${this.Latitude}, Longitude = ${this.Longitude}, LicenseKey = ${this.LicenseKey}, IsLive = ${this.IsLive}, TimeoutSeconds = ${this.TimeoutSeconds}`;\n    }\n}\n\n\/**\n * Information Component for API responses.\n *\/\nexport class InformationComponent {\n    constructor(data = {}) {\n        this.Name = data.Name;\n        this.Value = data.Value;\n    }\n\n    toString() {\n        return `Name = ${this.Name}, Value = ${this.Value}`;\n    }\n}\n\n\/**\n * Error object for API responses.\n *\/\nexport class Error {\n    constructor(data = {}) {\n        this.Desc = data.Desc;\n        this.Number = data.Number;\n        this.Location = data.Location;\n    }\n\n    toString() {\n        return `Error: Desc = ${this.Desc}, Number = ${this.Number}, Location = ${this.Location}`;\n    }\n}\n\n\/**\n * Response from GetBestMatch_V4 API.\n *\/\nexport class GetBestMatchV4Response {\n    constructor(data = {}) {\n        this.Level = data.Level;\n        this.LevelDescription = data.LevelDescription;\n        this.Latitude = data.Latitude;\n        this.Longitude = data.Longitude;\n        this.Zip = data.Zip;\n        this.InformationComponents = (data.InformationComponents || []).map(component => new InformationComponent(component));\n        this.Error = data.Error ? new Error(data.Error) : null;\n    }\n\n    toString() {\n        const componentsString = this.InformationComponents.length\n            ? this.InformationComponents.map(component => component.toString()).join(', ')\n            : 'null';\n        return `GetBestMatchV4Response: Level = ${this.Level}, LevelDescription = ${this.LevelDescription}, Latitude = ${this.Latitude}, Longitude = ${this.Longitude}, Zip = ${this.Zip}, InformationComponents = [${componentsString}], Error = ${this.Error ? this.Error.toString() : 'null'}`;\n    }\n}\n\n\/**\n * Response from GetDistanceToWater API, containing the estimated distance to the nearest saltwater\n * and the coordinates of the closest saltwater location.\n *\/\nexport class GetDistanceToWaterResponse {\n    constructor(data = {}) {\n        this.DistanceToWater = data.DistanceToWater;\n        this.Latitude = data.Latitude;\n        this.Longitude = data.Longitude;\n        this.WaterLat = data.WaterLat;\n        this.WaterLon = data.WaterLon;\n        this.Error = data.Error ? new Error(data.Error) : null;\n    }\n\n    toString() {\n        return `GetDistanceToWaterResponse: MilesToWater = ${this.DistanceToWater}, Latitude = ${this.Latitude}, Longitude = ${this.Longitude}, ClosestWaterLatitude = ${this.WaterLat}, ClosestWaterLongitude = ${this.WaterLon}, Error = ${this.Error ? this.Error.toString() : 'null'}`;\n    }\n}\n\n\/**\n * Response from GetReverseLocation API, containing the estimated address, city, state, ZIP code,\n * and county for the given coordinates.\n *\/\nexport class GetReverseLocationResponse {\n    constructor(data = {}) {\n        this.Address = data.Address;\n        this.City = data.City;\n        this.State = data.State;\n        this.Zip = data.Zip;\n        this.County = data.County;\n        this.Error = data.Error ? new Error(data.Error) : null;\n    }\n\n    toString() {\n        return `GetReverseLocationResponse: Address = ${this.Address}, City = ${this.City}, State = ${this.State}, Zip = ${this.Zip}, County = ${this.County}, Error = ${this.Error ? this.Error.toString() : 'null'}`;\n    }\n}\n\nexport default GetDistanceToWaterResponse;<\/pre>\n<\/div>\n<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":2,"featured_media":0,"parent":2461,"menu_order":1,"comment_status":"open","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-2476","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.2 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>AGUS - REST<\/title>\n<meta name=\"description\" content=\"C#PythonNodeJS Address Geocode - US C# Code Snippet using System.Web; namespace address_geocode_us_dot_net.REST { \/\/\/ &lt;summary&gt; \/\/\/ Provides\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.serviceobjects.com\/docs\/dots-address-geocode-us\/agus-code-snippets-and-sample-code\/agus-rest\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"AGUS - REST\" \/>\n<meta property=\"og:description\" content=\"C#PythonNodeJS Address Geocode - US C# Code Snippet using System.Web; namespace address_geocode_us_dot_net.REST { \/\/\/ &lt;summary&gt; \/\/\/ Provides\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.serviceobjects.com\/docs\/dots-address-geocode-us\/agus-code-snippets-and-sample-code\/agus-rest\/\" \/>\n<meta property=\"og:site_name\" content=\"Service Objects | Contact, Phone, Email Verification | Data Quality Services\" \/>\n<meta property=\"article:modified_time\" content=\"2025-09-27T18:14:59+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.serviceobjects.com\/docs\/dots-address-geocode-us\/agus-code-snippets-and-sample-code\/agus-rest\/\",\"url\":\"https:\/\/www.serviceobjects.com\/docs\/dots-address-geocode-us\/agus-code-snippets-and-sample-code\/agus-rest\/\",\"name\":\"AGUS - REST\",\"isPartOf\":{\"@id\":\"https:\/\/www.serviceobjects.com\/docs\/#website\"},\"datePublished\":\"2022-11-09T07:10:33+00:00\",\"dateModified\":\"2025-09-27T18:14:59+00:00\",\"description\":\"C#PythonNodeJS Address Geocode - US C# Code Snippet using System.Web; namespace address_geocode_us_dot_net.REST { \/\/\/ &lt;summary> \/\/\/ Provides\",\"breadcrumb\":{\"@id\":\"https:\/\/www.serviceobjects.com\/docs\/dots-address-geocode-us\/agus-code-snippets-and-sample-code\/agus-rest\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.serviceobjects.com\/docs\/dots-address-geocode-us\/agus-code-snippets-and-sample-code\/agus-rest\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.serviceobjects.com\/docs\/dots-address-geocode-us\/agus-code-snippets-and-sample-code\/agus-rest\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.serviceobjects.com\/docs\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"DOTS Address Geocode \u2013 US\",\"item\":\"https:\/\/www.serviceobjects.com\/docs\/dots-address-geocode-us\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"AGUS &#8211; Code Snippets and Sample Code\",\"item\":\"https:\/\/www.serviceobjects.com\/docs\/dots-address-geocode-us\/agus-code-snippets-and-sample-code\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"AGUS &#8211; REST\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.serviceobjects.com\/docs\/#website\",\"url\":\"https:\/\/www.serviceobjects.com\/docs\/\",\"name\":\"Service Objects | Contact, Phone, Email Verification | Data Quality Services\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/www.serviceobjects.com\/docs\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.serviceobjects.com\/docs\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.serviceobjects.com\/docs\/#organization\",\"name\":\"Service Objects | Contact, Phone, Email Verification | Data Quality Services\",\"url\":\"https:\/\/www.serviceobjects.com\/docs\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.serviceobjects.com\/docs\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.serviceobjects.com\/docs\/wp-content\/uploads\/2022\/08\/SO-logo-2560px-transparent.png\",\"contentUrl\":\"https:\/\/www.serviceobjects.com\/docs\/wp-content\/uploads\/2022\/08\/SO-logo-2560px-transparent.png\",\"width\":2560,\"height\":1440,\"caption\":\"Service Objects | Contact, Phone, Email Verification | Data Quality Services\"},\"image\":{\"@id\":\"https:\/\/www.serviceobjects.com\/docs\/#\/schema\/logo\/image\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"AGUS - REST","description":"C#PythonNodeJS Address Geocode - US C# Code Snippet using System.Web; namespace address_geocode_us_dot_net.REST { \/\/\/ &lt;summary> \/\/\/ Provides","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.serviceobjects.com\/docs\/dots-address-geocode-us\/agus-code-snippets-and-sample-code\/agus-rest\/","og_locale":"en_US","og_type":"article","og_title":"AGUS - REST","og_description":"C#PythonNodeJS Address Geocode - US C# Code Snippet using System.Web; namespace address_geocode_us_dot_net.REST { \/\/\/ &lt;summary> \/\/\/ Provides","og_url":"https:\/\/www.serviceobjects.com\/docs\/dots-address-geocode-us\/agus-code-snippets-and-sample-code\/agus-rest\/","og_site_name":"Service Objects | Contact, Phone, Email Verification | Data Quality Services","article_modified_time":"2025-09-27T18:14:59+00:00","twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.serviceobjects.com\/docs\/dots-address-geocode-us\/agus-code-snippets-and-sample-code\/agus-rest\/","url":"https:\/\/www.serviceobjects.com\/docs\/dots-address-geocode-us\/agus-code-snippets-and-sample-code\/agus-rest\/","name":"AGUS - REST","isPartOf":{"@id":"https:\/\/www.serviceobjects.com\/docs\/#website"},"datePublished":"2022-11-09T07:10:33+00:00","dateModified":"2025-09-27T18:14:59+00:00","description":"C#PythonNodeJS Address Geocode - US C# Code Snippet using System.Web; namespace address_geocode_us_dot_net.REST { \/\/\/ &lt;summary> \/\/\/ Provides","breadcrumb":{"@id":"https:\/\/www.serviceobjects.com\/docs\/dots-address-geocode-us\/agus-code-snippets-and-sample-code\/agus-rest\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.serviceobjects.com\/docs\/dots-address-geocode-us\/agus-code-snippets-and-sample-code\/agus-rest\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.serviceobjects.com\/docs\/dots-address-geocode-us\/agus-code-snippets-and-sample-code\/agus-rest\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.serviceobjects.com\/docs\/"},{"@type":"ListItem","position":2,"name":"DOTS Address Geocode \u2013 US","item":"https:\/\/www.serviceobjects.com\/docs\/dots-address-geocode-us\/"},{"@type":"ListItem","position":3,"name":"AGUS &#8211; Code Snippets and Sample Code","item":"https:\/\/www.serviceobjects.com\/docs\/dots-address-geocode-us\/agus-code-snippets-and-sample-code\/"},{"@type":"ListItem","position":4,"name":"AGUS &#8211; REST"}]},{"@type":"WebSite","@id":"https:\/\/www.serviceobjects.com\/docs\/#website","url":"https:\/\/www.serviceobjects.com\/docs\/","name":"Service Objects | Contact, Phone, Email Verification | Data Quality Services","description":"","publisher":{"@id":"https:\/\/www.serviceobjects.com\/docs\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.serviceobjects.com\/docs\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.serviceobjects.com\/docs\/#organization","name":"Service Objects | Contact, Phone, Email Verification | Data Quality Services","url":"https:\/\/www.serviceobjects.com\/docs\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.serviceobjects.com\/docs\/#\/schema\/logo\/image\/","url":"https:\/\/www.serviceobjects.com\/docs\/wp-content\/uploads\/2022\/08\/SO-logo-2560px-transparent.png","contentUrl":"https:\/\/www.serviceobjects.com\/docs\/wp-content\/uploads\/2022\/08\/SO-logo-2560px-transparent.png","width":2560,"height":1440,"caption":"Service Objects | Contact, Phone, Email Verification | Data Quality Services"},"image":{"@id":"https:\/\/www.serviceobjects.com\/docs\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/www.serviceobjects.com\/docs\/wp-json\/wp\/v2\/pages\/2476","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.serviceobjects.com\/docs\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.serviceobjects.com\/docs\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.serviceobjects.com\/docs\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.serviceobjects.com\/docs\/wp-json\/wp\/v2\/comments?post=2476"}],"version-history":[{"count":11,"href":"https:\/\/www.serviceobjects.com\/docs\/wp-json\/wp\/v2\/pages\/2476\/revisions"}],"predecessor-version":[{"id":12360,"href":"https:\/\/www.serviceobjects.com\/docs\/wp-json\/wp\/v2\/pages\/2476\/revisions\/12360"}],"up":[{"embeddable":true,"href":"https:\/\/www.serviceobjects.com\/docs\/wp-json\/wp\/v2\/pages\/2461"}],"wp:attachment":[{"href":"https:\/\/www.serviceobjects.com\/docs\/wp-json\/wp\/v2\/media?parent=2476"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}