- C#
- Python
- NodeJS
Address Validation 3 C# Rest Code Snippet
static void Main(string[] args) { //Usage example GetBestMatchesInput In = new("", "26 S Chestnut", "", "Ventura", "CA", "93033", "XXXXXXXXXXXXXX", true); GBMResponse Response = GetBestMatchesClient.InvokeAsync(In).Result; } public static class GetBestMatchesClient { // Base URL constants: production, backup, and trial private const string LiveBaseUrl = "https://sws.serviceobjects.com/AV3/api.svc/"; private const string BackupBaseUrl = "https://swsbackup.serviceobjects.com/AV3/api.svc/"; private const string TrialBaseUrl = "https://trial.serviceobjects.com/AV3/api.svc/"; /// <summary> /// Synchronously invoke the GetBestMatchesJson endpoint. /// </summary> /// <param name="input">Data for the request (address components, license key, isLive).</param> /// <returns>Deserialized <see cref="GBMResponse"/>.</returns> public static GBMResponse Invoke(GetBestMatchesInput input) { var url = BuildUrl(input, input.IsLive ? LiveBaseUrl : TrialBaseUrl); var response = Helper.HttpGet<GBMResponse>(url, input.TimeoutSeconds); // Fallback on error payload in live mode if (input.IsLive && !IsValid(response)) { var fallbackUrl = BuildUrl(input, BackupBaseUrl); var fallbackResponse = Helper.HttpGet<GBMResponse>(fallbackUrl, input.TimeoutSeconds); return IsValid(fallbackResponse) ? fallbackResponse : response; } return response; } /// <summary> /// Asynchronously invoke the GetBestMatchesJson endpoint. /// </summary> /// <param name="input">Data for the request (address components, license key, isLive).</param> /// <returns>Deserialized <see cref="GBMResponse"/>.</returns> public static async Task<GBMResponse> InvokeAsync(GetBestMatchesInput input) { var url = BuildUrl(input, input.IsLive ? LiveBaseUrl : TrialBaseUrl); var response = await Helper.HttpGetAsync<GBMResponse>(url, input.TimeoutSeconds).ConfigureAwait(false); if (input.IsLive && !IsValid(response)) { var fallbackUrl = BuildUrl(input, BackupBaseUrl); var fallbackResponse = await Helper.HttpGetAsync<GBMResponse>(fallbackUrl, input.TimeoutSeconds).ConfigureAwait(false); return IsValid(fallbackResponse) ? fallbackResponse : response; } return response; } /// <summary> /// Input container for the AV3 GetBestMatches operation. /// Encapsulates all required address fields, license key, and execution options. /// </summary> /// <param name="BusinessName">Company name to assist suite parsing (e.g., "Acme Corp").</param> /// <param name="Address">Primary street address (e.g., "123 Main St").</param> /// <param name="Address2">Secondary address information (e.g., "C/O John Smith").</param> /// <param name="City">City name; required if PostalCode is omitted.</param> /// <param name="State">State code or full name; required if PostalCode is omitted.</param> /// <param name="PostalCode">5- or 9-digit ZIP; required if City/State are omitted.</param> /// <param name="LicenseKey">Service Objects AV3 license key.</param> /// <param name="IsLive">True to use production endpoints (with fallback); false for trial endpoint only.</param> /// <param name="TimeoutSeconds">Timeout for HTTP requests in seconds (default: 15).</param> public record GetBestMatchesInput( string BusinessName, string Address, string Address2, string City, string State, string PostalCode, string LicenseKey, bool IsLive, int TimeoutSeconds = 15 ); // Build the full request URL, including URL-encoded query string private static string BuildUrl(GetBestMatchesInput input, string baseUrl) { var qs = $"GetBestMatchesJson?BusinessName={Helper.UrlEncode(input.BusinessName)}" + $"&Address={Helper.UrlEncode(input.Address)}" + $"&Address2={Helper.UrlEncode(input.Address2)}" + $"&City={Helper.UrlEncode(input.City)}" + $"&State={Helper.UrlEncode(input.State)}" + $"&PostalCode={Helper.UrlEncode(input.PostalCode)}" + $"&LicenseKey={Helper.UrlEncode(input.LicenseKey)}"; return baseUrl + qs; } private static bool IsValid(GBMResponse response) => response?.Error == null || response.Error.TypeCode != "3"; } /// <summary> /// Represents the response from the GetBestMatches operation, /// including a list of validated addresses, CASS status, and any error information. /// </summary> public class GBMResponse { [DataMember(Name = "Addresses")] public Address[] Addresses { get; set; } [DataMember(Name = "IsCASS")] public bool IsCASS { get; set; } [DataMember(Name = "Error")] public Error Error { get; set; } public override string ToString() { string Output = ""; Output += $"GBM Response:\n"; Output += $"List of all Addresses: ["; if (Addresses != null && Addresses.Length > 0) { foreach (Address A in Addresses) { Output += A.ToString() + "\n"; } } Output += "]\n"; Output += $"IsCASS: {IsCASS}\n"; Output += $"Error: {{{Error}}}\n"; return Output; } } /// <summary> /// Represents a single address candidate returned by the AV3 service, /// including parsed components, delivery indicators, and postal fragments. /// </summary> public class Address { [DataMember(Name = "Address1")] public string Address1 { get; set; } [DataMember(Name = "Address2")] public string Address2 { get; set; } [DataMember(Name = "City")] public string City { get; set; } [DataMember(Name = "State")] public string State { get; set; } [DataMember(Name = "Zip")] public string Zip { get; set; } [DataMember(Name = "IsResidential")] public string IsResidential { get; set; } [DataMember(Name = "DPV")] public string DPV { get; set; } [DataMember(Name = "DPVDesc")] public string DPVDesc { get; set; } [DataMember(Name = "DPVNotes")] public string DPVNotes { get; set; } [DataMember(Name = "DPVNotesDesc")] public string DPVNotesDesc { get; set; } [DataMember(Name = "Corrections")] public string Corrections { get; set; } [DataMember(Name = "CorrectionsDesc")] public string CorrectionsDesc { get; set; } [DataMember(Name = "BarcodeDigits")] public string BarcodeDigits { get; set; } [DataMember(Name = "CarrierRoute")] public string CarrierRoute { get; set; } [DataMember(Name = "CongressCode")] public string CongressCode { get; set; } [DataMember(Name = "CountyCode")] public string CountyCode { get; set; } [DataMember(Name = "CountyName")] public string CountyName { get; set; } [DataMember(Name = "FragmentHouse")] public string FragmentHouse { get; set; } [DataMember(Name = "FragmentPreDir")] public string FragmentPreDir { get; set; } [DataMember(Name = "FragmentStreet")] public string FragmentStreet { get; set; } [DataMember(Name = "FragmentSuffix")] public string FragmentSuffix { get; set; } [DataMember(Name = "FragmentPostDir")] public string FragmentPostDir { get; set; } [DataMember(Name = "FragmentUnit")] public string FragmentUnit { get; set; } [DataMember(Name = "Fragment")] public string Fragment { get; set; } [DataMember(Name = "FragmentPMBPrefix")] public string FragmentPMBPrefix { get; set; } [DataMember(Name = "FragmentPMBNumber")] public string FragmentPMBNumber { get; set; } public override string ToString() { return $"\n{{Address1: {Address1}\n" + $"\tAddress2: {Address2}\n" + $"\tCity: {City}\n" + $"\tState: {State}\n" + $"\tZip: {Zip}\n" + $"\tIsResidential: {IsResidential}\n" + $"\tDPV: {DPV}\n" + $"\tDPVDesc: {DPVDesc}\n" + $"\tDPVNotes: {DPVNotes}\n" + $"\tDPVNotesDesc: {DPVNotesDesc}\n" + $"\tCorrections: {Corrections}\n" + $"\tCorrectionsDesc: {CorrectionsDesc}\n" + $"\tBarcodeDigits: {BarcodeDigits}\n" + $"\tCarrierRoute: {CarrierRoute}\n" + $"\tCongressCode: {CongressCode}\n" + $"\tCountyCode: {CountyCode}\n" + $"\tCountyName: {CountyName}\n" + $"\tFragmentHouse: {FragmentHouse}\n" + $"\tFragmentPreDir: {FragmentPreDir}\n" + $"\tFragmentStreet: {FragmentStreet}\n" + $"\tFragmentSuffix: {FragmentSuffix}\n" + $"\tFragmentPostDir: {FragmentPostDir}\n" + $"\tFragmentUnit: {FragmentUnit}\n" + $"\tFragment: {Fragment}\n" + $"\tFragmentPMBPrefix: {FragmentPMBPrefix}\n" + $"\tFragmentPMBNumber: {FragmentPMBNumber}}}\n"; } } /// <summary> /// Represents error information returned by the AV3 service, /// including error type codes and descriptive messages. /// </summary> public class Error { [DataMember(Name = "Type")] public string Type { get; set; } [DataMember(Name = "TypeCode")] public string TypeCode { get; set; } [DataMember(Name = "Desc")] public string Desc { get; set; } [DataMember(Name = "DescCode")] public string DescCode { get; set; } public override string ToString() { return $"Type: {Type} " + $"TypeCode: {TypeCode} " + $"Desc: {Desc} " + $"DescCode: {DescCode} "; } } /// <summary> /// Utility class providing synchronous and asynchronous HTTP GET methods /// and URL encoding for ServiceObjects API clients. /// </summary> public static class Helper { // Reuse a single HttpClient instance for performance and resource management private static readonly HttpClient HttpClient = new HttpClient(); /// <summary> /// Performs a synchronous HTTP GET request and deserializes the JSON response into the specified type. /// </summary> /// <typeparam name="T">The target type to deserialize the JSON response into.</typeparam> /// <param name="url">Full URL including query string.</param> /// <param name="timeoutSeconds">Request timeout in seconds.</param> /// <returns>Deserialized object of type T.</returns> public static T HttpGet<T>(string url, int timeoutSeconds) { HttpClient.Timeout = TimeSpan.FromSeconds(timeoutSeconds); using var httpResponse = HttpClient.GetAsync(url).GetAwaiter().GetResult(); httpResponse.EnsureSuccessStatusCode(); var stream = httpResponse.Content.ReadAsStream(); return JsonSerializer.Deserialize<T>(stream)!; } /// <summary> /// Performs an asynchronous HTTP GET request and deserializes the JSON response into the specified type. /// </summary> /// <typeparam name="T">The target type to deserialize the JSON response into.</typeparam> /// <param name="url">Full URL including query string.</param> /// <param name="timeoutSeconds">Request timeout in seconds.</param> /// <returns>A Task that resolves to a deserialized object of type T.</returns> public static async Task<T> HttpGetAsync<T>(string url, int timeoutSeconds) { 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)!; } /// <summary> /// URL-encodes the specified string, treating null as an empty string. /// </summary> /// <param name="value">The string to URL-encode.</param> /// <returns>URL-encoded representation of the input.</returns> public static string UrlEncode(string value) => HttpUtility.UrlEncode(value ?? string.Empty); }
Address Validation US 3 Python Code Snippet
''' Service Objects, Inc. This module provides the get_best_matches function to validate and standardize US addresses using Service Objects’ AV3 API. It handles live/trial endpoints, fallback logic, and JSON parsing. Functions: get_best_matches(business_name: str, address: str, address_2: str, city: str, state: str, postal_code: str, license_key: str, is_live: bool) -> dict: ''' import requests # HTTP client for RESTful API calls # Endpoint URLs for AV3 service primary_url = 'https://sws.serviceobjects.com/AV3/api.svc/GetBestMatchesJson?' backup_url = 'https://swsbackup.serviceobjects.com/AV3/api.svc/GetBestMatchesJson?' trial_url = 'https://trial.serviceobjects.com/AV3/api.svc/GetBestMatchesJson?' def get_best_matches(business_name: str, address: str, address_2: str, city: str, state: str, postal_code: str, license_key: str, is_live: bool) -> dict: ''' Call AV3 get_best_matches API and return validation results. Parameters: business_name (str): Company name to assist suite parsing. address (str): Primary street address (e.g., '123 Main St'). Required. address_2 (str): Secondary address info (e.g., 'C/O John Smith'). city (str): City name; required if PostalCode not provided. state (str): State code or full name; required if PostalCode not provided. postal_code (str): 5- or 9-digit ZIP; required if City/State not provided. license_key (str): Service Objects license key. is_live (bool): True for production endpoints, False for trial URL. Returns: dict: Parsed JSON response with address candidates or error info. ''' # Prepare query parameters for AV3 API params = { 'BusinessName': business_name, 'Address' : address, 'Address2' : address_2, 'City' : city, 'State' : state, 'PostalCode' : postal_code, 'LicenseKey' : license_key } # Select the base URL: production vs trial url = primary_url if is_live else trial_url # Attempt primary (or trial) endpoint first try: response = requests.get(url, params=params, timeout=10) data = response.json() # If API returned an error in JSON payload, trigger fallback if 'Error' in data: if is_live: # Try backup URL when live response = requests.get(backup_url, params=params, timeout=10) data = response.json() # If still error, propagate exception if 'Error' in data: raise RuntimeError(f"AV3 service error: {data['Error']}") else: # Trial mode should not fallback; error is terminal raise RuntimeError(f"AV3 trial error: {data['Error']}") # Success: return parsed JSON data return data except requests.RequestException as req_exc: # Network or HTTP-level error occurred # TODO: Instrument alerting on repeated failures if is_live: try: # Fallback to backup URL on network failure response = requests.get(backup_url, params=params, timeout=10) data = response.json() if 'Error' in data: raise RuntimeError(f"AV3 backup error: {data['Error']}") return data except Exception as backup_exc: # Both primary and backup failed; escalate raise RuntimeError("AV3 service unreachable on both endpoints") from backup_exc else: # In trial mode, propagate the network exception raise
Address Validation 3 NodeJS REST Code Snippet
/** * @module AV3AddressValidation * @description * Client module for the AV3 GetBestMatchesJson operation. * Validates and standardizes U.S. addresses via Service Objects’ AV3 API, * with built‑in production/trial endpoints and automatic fallback logic. */ import fetch from 'node-fetch'; // Base endpoints for AV3 service const ENDPOINTS = { production: 'https://ws.serviceobjects.com/av3/api.svc/', backup: 'https://wsbackup.serviceobjects.com/av3/api.svc/', trial: 'https://trial.serviceobjects.com/av3/api.svc/' }; /** * Build a fully‑qualified URL for the GetBestMatchesJson endpoint. * @param {object} params Key/value pairs of query parameters. * @param {string} baseUrl Base URL (must end with '/'). * @returns {string} Fully‑qualified URL including encoded query string. */ function buildGetBestMatchesUrl(params, baseUrl) { const url = new URL('GetBestMatchesJson', baseUrl); Object.entries(params).forEach(([key, value]) => { url.searchParams.append(key, value ?? ''); }); return url.toString(); } /** * Perform an HTTP GET request and parse JSON response. * @param {string} url URL to request. * @returns {Promise<any>} Parsed JSON body. * @throws {Error} On HTTP or parse errors. */ async function httpGetJson(url) { const res = await fetch(url); if (!res.ok) throw new Error(`HTTP ${res.status} ${res.statusText}`); return res.json(); } /** * @typedef {object} GetBestMatchesOptions * @property {string} businessName Company name to assist suite parsing. * @property {string} address Primary street address (e.g., '123 Main St'). * @property {string} [address2] Secondary address info (e.g., 'C/O John Smith'). * @property {string} [city] City; required if postalCode omitted. * @property {string} [state] State code or full name; required if postalCode omitted. * @property {string} [postalCode] 5‑ or 9‑digit ZIP; required if city/state omitted. * @property {string} licenseKey Valid AV3 license key. * @property {'production'|'trial'} [environment='production'] * 'production' for live+backup, 'trial' for trial only. * @property {number} [timeoutMs=15000] * Request timeout in milliseconds. */ /** * Retrieve standardized address candidates via AV3 GetBestMatches. * Automatically falls back from production to backup on error TypeCode '3'. * @param {GetBestMatchesOptions} opts Operation settings. * @returns {Promise<object>} Service response JSON. * @throws {Error} On unrecoverable HTTP or service errors. */ export async function getBestMatches(opts) { const { businessName, address, address2 = '', city = '', state = '', postalCode = '', licenseKey, environment = 'production', timeoutMs = 15000 } = opts; // Assemble query parameters matching API names const params = { BusinessName: businessName, Address: address, Address2: address2, City: city, State: state, PostalCode: postalCode, LicenseKey: licenseKey }; // Choose primary URL based on environment const baseUrl = environment === 'trial' ? ENDPOINTS.trial : ENDPOINTS.production; const primaryUrl = buildGetBestMatchesUrl(params, baseUrl); // Helper to call with timeout const call = url => Promise.race([ httpGetJson(url), new Promise((_, rej) => setTimeout(() => rej(new Error('Timeout')), timeoutMs)) ]); try { let result = await call(primaryUrl); // Fallback if production + service-level fatal error if (environment === 'production' && result.Error?.TypeCode === '3') { const backupUrl = buildGetBestMatchesUrl(params, ENDPOINTS.backup); result = await call(backupUrl); } return result; } catch (err) { // On network or HTTP failure, retry backup for production if (environment === 'production') { const backupUrl = buildGetBestMatchesUrl(params, ENDPOINTS.backup); return call(backupUrl); } throw err; } }