- C#
- Python
- NodeJS
Name Validation 2 C# Code Snippet
namespace name_validation_2_dot_net.REST
{
/// <summary>
/// Provides functionality to call the ServiceObjects DOTS Name Validation 2 REST API's NameInfoV2 endpoint,
/// retrieving name validation information (e.g., name parsing, gender, scores) with fallback to a backup endpoint
/// for reliability in live mode.
/// </summary>
public class NameInfoV2Client
{
private const string LiveBaseUrl = "https://sws.serviceobjects.com/NV2/api.svc/";
private const string BackupBaseUrl = "https://swsbackup.serviceobjects.com/NV2/api.svc/";
private const string TrialBaseUrl = "https://trial.serviceobjects.com/NV2/api.svc/";
/// <summary>
/// Synchronously calls the NameInfoV2 REST endpoint to retrieve name validation information,
/// attempting the primary endpoint first and falling back to the backup if the response is invalid
/// (Error.TypeCode == "3") in live mode.
/// </summary>
/// <param name="input">The input parameters including name, option, license key.</param>
/// <returns>Deserialized <see cref="NameInfoV2Response"/>.</returns>
public static NameInfoV2Response Invoke(GetNameInfoInput 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);
NameInfoV2Response response = Helper.HttpGet<NameInfoV2Response>(url, input.TimeoutSeconds);
// Fallback on error in live mode
if (input.IsLive && !IsValid(response))
{
string fallbackUrl = BuildUrl(input, BackupBaseUrl);
NameInfoV2Response fallbackResponse = Helper.HttpGet<NameInfoV2Response>(fallbackUrl, input.TimeoutSeconds);
return fallbackResponse;
}
return response;
}
/// <summary>
/// Asynchronously calls the NameInfoV2 REST endpoint to retrieve name validation information,
/// attempting the primary endpoint first and falling back to the backup if the response is invalid
/// (Error.TypeCode == "3") in live mode.
/// </summary>
/// <param name="input">The input parameters including name, option, license key.</param>
/// <returns>Deserialized <see cref="NameInfoV2Response"/>.</returns>
public static async Task<NameInfoV2Response> InvokeAsync(GetNameInfoInput 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);
NameInfoV2Response response = await Helper.HttpGetAsync<NameInfoV2Response>(url, input.TimeoutSeconds).ConfigureAwait(false);
if (input.IsLive && !IsValid(response))
{
string fallbackUrl = BuildUrl(input, BackupBaseUrl);
NameInfoV2Response fallbackResponse = await Helper.HttpGetAsync<NameInfoV2Response>(fallbackUrl, input.TimeoutSeconds).ConfigureAwait(false);
return fallbackResponse;
}
return response;
}
// Build the full request URL, including URL-encoded query string
public static string BuildUrl(GetNameInfoInput input, string baseUrl)
{
string qs = "NameInfoV2?" +
$"Name={Helper.UrlEncode(input.Name)}" +
$"&Option={Helper.UrlEncode(input.Option)}" +
$"&LicenseKey={Helper.UrlEncode(input.LicenseKey)}" +
"&format=json";
return baseUrl + qs;
}
private static bool IsValid(NameInfoV2Response response) =>
response?.Error == null || response.Error.TypeCode != "3";
/// <summary>
/// This is the primary operation for validating and parsing a name. Given a name and optional parameters,
/// </summary>
/// <param name="Name">The name to validate (required).</param>
/// <param name="Option">Comma-separated list of options for additional processing (optional).</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 GetNameInfoInput(
string Name = "",
string Option = "",
string LicenseKey = "",
bool IsLive = true,
int TimeoutSeconds = 15
);
}
}
namespace name_validation_2_dot_net.REST
{
public class NameInfoV2Response
{
public NameInfoV2 NameInfoV2 { get; set; }
public Error Error { get; set; }
public override string ToString()
{
return $"NameInfoV2: {NameInfoV2}\n" +
$"Error: {{{Error}}}";
}
}
public class NameInfoV2
{
public BestGuessName BestGuessName { get; set; }
public string NameIn { get; set; }
public string NameClassification { get; set; }
public string Prefix { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string Suffix { get; set; }
public bool FirstNameFound { get; set; }
public bool IsCommonFirstName { get; set; }
public string FirstNameOrigin { get; set; }
public string FirstNameSimilar { get; set; }
public bool LastNameFound { get; set; }
public bool IsCommonLastName { get; set; }
public string LastNameOrigin { get; set; }
public string LastNameSimilar { get; set; }
public string Gender { get; set; }
public string FirstNameAlt { get; set; }
public string MiddleNameAlt { get; set; }
public string LastNameAlt { get; set; }
public bool FirstNameAltFound { get; set; }
public bool LastNameAltFound { get; set; }
public string GenderAlt { get; set; }
public string RelatedNames { get; set; }
public bool IsCorrectedName { get; set; }
public bool IsBusinessName { get; set; }
public string BusinessName { get; set; }
public int VulgarityScore { get; set; }
public int CelebrityScore { get; set; }
public int BogusScore { get; set; }
public int GarbageScore { get; set; }
public int FirstNameDictionaryScore { get; set; }
public int MiddleNameDictionaryScore { get; set; }
public int LastNameDictionaryScore { get; set; }
public int OverallNameScore { get; set; }
public string IsNameGood { get; set; }
public string StatusCodes { get; set; }
public string Status { get; set; }
public override string ToString()
{
string Output = $"{{BestGuessName: {BestGuessName}\n" +
$"NameIn: {NameIn}\n" +
$"NameClassification: {NameClassification}\n" +
$"Prefix: {Prefix}\n" +
$"FirstName: {FirstName}\n" +
$"MiddleName: {MiddleName}\n" +
$"LastName: {LastName}\n" +
$"Suffix: {Suffix}\n" +
$"FirstNameFound: {FirstNameFound}\n" +
$"IsCommonFirstName: {IsCommonFirstName}\n" +
$"FirstNameOrigin: {FirstNameOrigin}\n" +
$"FirstNameSimilar: {FirstNameSimilar}\n" +
$"LastNameFound: {LastNameFound}\n" +
$"IsCommonLastName: {IsCommonLastName}\n" +
$"LastNameOrigin: {LastNameOrigin}\n" +
$"LastNameSimilar: {LastNameSimilar}\n" +
$"Gender: {Gender}\n" +
$"FirstNameAlt: {FirstNameAlt}\n" +
$"MiddleNameAlt: {MiddleNameAlt}\n" +
$"LastNameAlt: {LastNameAlt}\n" +
$"FirstNameAltFound: {FirstNameAltFound}\n" +
$"LastNameAltFound: {LastNameAltFound}\n" +
$"GenderAlt: {GenderAlt}\n" +
$"RelatedNames: {RelatedNames}\n" +
$"IsCorrectedName: {IsCorrectedName}\n" +
$"IsBusinessName: {IsBusinessName}\n" +
$"BusinessName: {BusinessName}\n" +
$"VulgarityScore: {VulgarityScore}\n" +
$"CelebrityScore: {CelebrityScore}\n" +
$"BogusScore: {BogusScore}\n" +
$"GarbageScore: {GarbageScore}\n" +
$"FirstNameDictionaryScore: {FirstNameDictionaryScore}\n" +
$"MiddleNameDictionaryScore: {MiddleNameDictionaryScore}\n" +
$"LastNameDictionaryScore: {LastNameDictionaryScore}\n" +
$"OverallNameScore: {OverallNameScore}\n" +
$"IsNameGood: {IsNameGood}\n" +
$"StatusCodes: {StatusCodes}\n" +
$"Status: {Status}\n";
return Output;
}
}
public class BestGuessName
{
public string Prefix { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string Suffix { get; set; }
public override string ToString()
{
return $"{{Prefix: {Prefix}\n" +
$"FirstName: {FirstName}\n" +
$"MiddleName: {MiddleName}\n" +
$"LastName: {LastName}\n" +
$"Suffix: {Suffix} }}\n";
}
}
public class Error
{
public string Type { get; set; }
public string TypeCode { get; set; }
public string Desc { get; set; }
public string DescCode { get; set; }
public override string ToString()
{
return $"Type: {Type}\n" +
$"TypeCode: {TypeCode}\n" +
$"Desc: {Desc}\n" +
$"DescCode: {DescCode} ";
}
}
}
using System.Text.Json;
using System.Web;
namespace name_validation_2_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);
}
}
Name Validation 2 Python Code Snippet
import requests
from nv2_response import NameInfoV2Response, NameInfoV2, BestGuessName, Error
# Endpoint URLs for Name Validation 2 NameInfoV2 REST API
primary_url = 'https://sws.serviceobjects.com/NV2/api.svc/NameInfoV2?'
backup_url = 'https://swsbackup.serviceobjects.com/NV2/api.svc/NameInfoV2?'
trial_url = 'https://trial.serviceobjects.com/NV2/api.svc/NameInfoV2?'
def get_name_info_v2(
name: str,
option: str,
license_key: str,
is_live: bool = True,
timeout_seconds: int = 15
) -> NameInfoV2Response:
"""
Call Name Validation 2 NameInfoV2 API to retrieve name validation information.
Parameters:
name: The name to validate.
option: Comma-separated list of options for additional processing (optional).
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:
NameInfoV2Response: Parsed JSON response with name information or error details.
"""
params = {
'Name': name,
'Option': option,
'LicenseKey': license_key,
'format': 'json'
}
# 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=timeout_seconds)
response.raise_for_status()
data = response.json()
# If API returned an error in JSON payload, trigger fallback
error = getattr(response, 'Error', None)
if not (error is None or getattr(error, 'TypeCode', None) != "3"):
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"NV2 service error: {data['Error']}")
else:
# Trial mode error is terminal
raise RuntimeError(f"NV2 trial error: {data['Error']}")
# Convert JSON response to NameInfoV2Response for structured access
error = Error(**data.get('Error', {})) if data.get('Error') else None
name_info_v2 = None
if data.get('NameInfoV2'):
best_guess_name = BestGuessName(**data['NameInfoV2'].get('BestGuessName', {})) if data['NameInfoV2'].get('BestGuessName') else None
name_info_v2 = NameInfoV2(
BestGuessName=best_guess_name,
NameIn=data['NameInfoV2'].get('NameIn'),
NameClassification=data['NameInfoV2'].get('NameClassification'),
Prefix=data['NameInfoV2'].get('Prefix'),
FirstName=data['NameInfoV2'].get('FirstName'),
MiddleName=data['NameInfoV2'].get('MiddleName'),
LastName=data['NameInfoV2'].get('LastName'),
Suffix=data['NameInfoV2'].get('Suffix'),
FirstNameFound=data['NameInfoV2'].get('FirstNameFound'),
IsCommonFirstName=data['NameInfoV2'].get('IsCommonFirstName'),
FirstNameOrigin=data['NameInfoV2'].get('FirstNameOrigin'),
FirstNameSimilar=data['NameInfoV2'].get('FirstNameSimilar'),
LastNameFound=data['NameInfoV2'].get('LastNameFound'),
IsCommonLastName=data['NameInfoV2'].get('IsCommonLastName'),
LastNameOrigin=data['NameInfoV2'].get('LastNameOrigin'),
LastNameSimilar=data['NameInfoV2'].get('LastNameSimilar'),
Gender=data['NameInfoV2'].get('Gender'),
FirstNameAlt=data['NameInfoV2'].get('FirstNameAlt'),
MiddleNameAlt=data['NameInfoV2'].get('MiddleNameAlt'),
LastNameAlt=data['NameInfoV2'].get('LastNameAlt'),
FirstNameAltFound=data['NameInfoV2'].get('FirstNameAltFound'),
LastNameAltFound=data['NameInfoV2'].get('LastNameAltFound'),
GenderAlt=data['NameInfoV2'].get('GenderAlt'),
RelatedNames=data['NameInfoV2'].get('RelatedNames'),
IsCorrectedName=data['NameInfoV2'].get('IsCorrectedName'),
IsBusinessName=data['NameInfoV2'].get('IsBusinessName'),
BusinessName=data['NameInfoV2'].get('BusinessName'),
VulgarityScore=data['NameInfoV2'].get('VulgarityScore'),
CelebrityScore=data['NameInfoV2'].get('CelebrityScore'),
BogusScore=data['NameInfoV2'].get('BogusScore'),
GarbageScore=data['NameInfoV2'].get('GarbageScore'),
FirstNameDictionaryScore=data['NameInfoV2'].get('FirstNameDictionaryScore'),
MiddleNameDictionaryScore=data['NameInfoV2'].get('MiddleNameDictionaryScore'),
LastNameDictionaryScore=data['NameInfoV2'].get('LastNameDictionaryScore'),
OverallNameScore=data['NameInfoV2'].get('OverallNameScore'),
IsNameGood=data['NameInfoV2'].get('IsNameGood'),
StatusCodes=data['NameInfoV2'].get('StatusCodes'),
Status=data['NameInfoV2'].get('Status')
)
return NameInfoV2Response(
NameInfoV2=name_info_v2,
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"NV2 backup error: {data['Error']}") from req_exc
# Convert JSON response to NameInfoV2Response for structured access
error = Error(**data.get('Error', {})) if data.get('Error') else None
name_info_v2 = None
if data.get('NameInfoV2'):
best_guess_name = BestGuessName(**data['NameInfoV2'].get('BestGuessName', {})) if data['NameInfoV2'].get('BestGuessName') else None
name_info_v2 = NameInfoV2(
BestGuessName=best_guess_name,
NameIn=data['NameInfoV2'].get('NameIn'),
NameClassification=data['NameInfoV2'].get('NameClassification'),
Prefix=data['NameInfoV2'].get('Prefix'),
FirstName=data['NameInfoV2'].get('FirstName'),
MiddleName=data['NameInfoV2'].get('MiddleName'),
LastName=data['NameInfoV2'].get('LastName'),
Suffix=data['NameInfoV2'].get('Suffix'),
FirstNameFound=data['NameInfoV2'].get('FirstNameFound'),
IsCommonFirstName=data['NameInfoV2'].get('IsCommonFirstName'),
FirstNameOrigin=data['NameInfoV2'].get('FirstNameOrigin'),
FirstNameSimilar=data['NameInfoV2'].get('FirstNameSimilar'),
LastNameFound=data['NameInfoV2'].get('LastNameFound'),
IsCommonLastName=data['NameInfoV2'].get('IsCommonLastName'),
LastNameOrigin=data['NameInfoV2'].get('LastNameOrigin'),
LastNameSimilar=data['NameInfoV2'].get('LastNameSimilar'),
Gender=data['NameInfoV2'].get('Gender'),
FirstNameAlt=data['NameInfoV2'].get('FirstNameAlt'),
MiddleNameAlt=data['NameInfoV2'].get('MiddleNameAlt'),
LastNameAlt=data['NameInfoV2'].get('LastNameAlt'),
FirstNameAltFound=data['NameInfoV2'].get('FirstNameAltFound'),
LastNameAltFound=data['NameInfoV2'].get('LastNameAltFound'),
GenderAlt=data['NameInfoV2'].get('GenderAlt'),
RelatedNames=data['NameInfoV2'].get('RelatedNames'),
IsCorrectedName=data['NameInfoV2'].get('IsCorrectedName'),
IsBusinessName=data['NameInfoV2'].get('IsBusinessName'),
BusinessName=data['NameInfoV2'].get('BusinessName'),
VulgarityScore=data['NameInfoV2'].get('VulgarityScore'),
CelebrityScore=data['NameInfoV2'].get('CelebrityScore'),
BogusScore=data['NameInfoV2'].get('BogusScore'),
GarbageScore=data['NameInfoV2'].get('GarbageScore'),
FirstNameDictionaryScore=data['NameInfoV2'].get('FirstNameDictionaryScore'),
MiddleNameDictionaryScore=data['NameInfoV2'].get('MiddleNameDictionaryScore'),
LastNameDictionaryScore=data['NameInfoV2'].get('LastNameDictionaryScore'),
OverallNameScore=data['NameInfoV2'].get('OverallNameScore'),
IsNameGood=data['NameInfoV2'].get('IsNameGood'),
StatusCodes=data['NameInfoV2'].get('StatusCodes'),
Status=data['NameInfoV2'].get('Status')
)
return NameInfoV2Response(
NameInfoV2=name_info_v2,
Error=error
)
except Exception as backup_exc:
raise RuntimeError("NV2 service unreachable on both endpoints") from backup_exc
else:
raise RuntimeError(f"NV2 trial error: {str(req_exc)}") from req_exc
from dataclasses import dataclass
from typing import Optional
@dataclass
class BestGuessName:
Prefix: Optional[str] = None
FirstName: Optional[str] = None
MiddleName: Optional[str] = None
LastName: Optional[str] = None
Suffix: Optional[str] = None
def __str__(self) -> str:
return (f"Prefix: {self.Prefix}\n"
f"FirstName: {self.FirstName}\n"
f"MiddleName: {self.MiddleName}\n"
f"LastName: {self.LastName}\n"
f"Suffix: {self.Suffix}")
@dataclass
class NameInfoV2:
BestGuessName: Optional[BestGuessName] = None
NameIn: Optional[str] = None
NameClassification: Optional[str] = None
Prefix: Optional[str] = None
FirstName: Optional[str] = None
MiddleName: Optional[str] = None
LastName: Optional[str] = None
Suffix: Optional[str] = None
FirstNameFound: Optional[bool] = None
IsCommonFirstName: Optional[bool] = None
FirstNameOrigin: Optional[str] = None
FirstNameSimilar: Optional[str] = None
LastNameFound: Optional[bool] = None
IsCommonLastName: Optional[bool] = None
LastNameOrigin: Optional[str] = None
LastNameSimilar: Optional[str] = None
Gender: Optional[str] = None
FirstNameAlt: Optional[str] = None
MiddleNameAlt: Optional[str] = None
LastNameAlt: Optional[str] = None
FirstNameAltFound: Optional[bool] = None
LastNameAltFound: Optional[bool] = None
GenderAlt: Optional[str] = None
RelatedNames: Optional[str] = None
IsCorrectedName: Optional[bool] = None
IsBusinessName: Optional[bool] = None
BusinessName: Optional[str] = None
VulgarityScore: Optional[int] = None
CelebrityScore: Optional[int] = None
BogusScore: Optional[int] = None
GarbageScore: Optional[int] = None
FirstNameDictionaryScore: Optional[int] = None
MiddleNameDictionaryScore: Optional[int] = None
LastNameDictionaryScore: Optional[int] = None
OverallNameScore: Optional[int] = None
IsNameGood: Optional[str] = None
StatusCodes: Optional[str] = None
Status: Optional[str] = None
def __str__(self) -> str:
return (f"{{BestGuessName: {self.BestGuessName.__str__() if self.BestGuessName else 'None'}\n"
f"NameIn: {self.NameIn}\n"
f"NameClassification: {self.NameClassification}\n"
f"Prefix: {self.Prefix}\n"
f"FirstName: {self.FirstName}\n"
f"MiddleName: {self.MiddleName}\n"
f"LastName: {self.LastName}\n"
f"Suffix: {self.Suffix}\n"
f"FirstNameFound: {self.FirstNameFound}\n"
f"IsCommonFirstName: {self.IsCommonFirstName}\n"
f"FirstNameOrigin: {self.FirstNameOrigin}\n"
f"FirstNameSimilar: {self.FirstNameSimilar}\n"
f"LastNameFound: {self.LastNameFound}\n"
f"IsCommonLastName: {self.IsCommonLastName}\n"
f"LastNameOrigin: {self.LastNameOrigin}\n"
f"LastNameSimilar: {self.LastNameSimilar}\n"
f"Gender: {self.Gender}\n"
f"FirstNameAlt: {self.FirstNameAlt}\n"
f"MiddleNameAlt: {self.MiddleNameAlt}\n"
f"LastNameAlt: {self.LastNameAlt}\n"
f"FirstNameAltFound: {self.FirstNameAltFound}\n"
f"LastNameAltFound: {self.LastNameAltFound}\n"
f"GenderAlt: {self.GenderAlt}\n"
f"RelatedNames: {self.RelatedNames}\n"
f"IsCorrectedName: {self.IsCorrectedName}\n"
f"IsBusinessName: {self.IsBusinessName}\n"
f"BusinessName: {self.BusinessName}\n"
f"VulgarityScore: {self.VulgarityScore}\n"
f"CelebrityScore: {self.CelebrityScore}\n"
f"BogusScore: {self.BogusScore}\n"
f"GarbageScore: {self.GarbageScore}\n"
f"FirstNameDictionaryScore: {self.FirstNameDictionaryScore}\n"
f"MiddleNameDictionaryScore: {self.MiddleNameDictionaryScore}\n"
f"LastNameDictionaryScore: {self.LastNameDictionaryScore}\n"
f"OverallNameScore: {self.OverallNameScore}\n"
f"IsNameGood: {self.IsNameGood}\n"
f"StatusCodes: {self.StatusCodes}\n"
f"Status: {self.Status}\n")
@dataclass
class Error:
Type: Optional[str] = None
TypeCode: Optional[str] = None
Desc: Optional[str] = None
DescCode: Optional[str] = None
def __str__(self) -> str:
return (f"Type: {self.Type}\n"
f"TypeCode: {self.TypeCode}\n"
f"Desc: {self.Desc}\n"
f"DescCode: {self.DescCode} ")
@dataclass
class NameInfoV2Response:
NameInfoV2: Optional[NameInfoV2] = None
Error: Optional[Error] = None
def __str__(self) -> str:
name_info = str(self.NameInfoV2) if self.NameInfoV2 else "None"
error = str(self.Error) if self.Error else "None"
return (f"NameInfoV2: {name_info}\n"
f"Error: {error}")
Name Validation 2 NodeJS Code Snippet
import axios from 'axios';
import querystring from 'querystring';
import { NameInfoV2Response } from './nv2_response.js';
/**
* @constant
* @type {string}
* @description The base URL for the live ServiceObjects Name Validation 2 API service.
*/
const LiveBaseUrl = 'https://sws.serviceobjects.com/NV2/api.svc/';
/**
* @constant
* @type {string}
* @description The base URL for the backup ServiceObjects Name Validation 2 API service.
*/
const BackupBaseUrl = 'https://swsbackup.serviceobjects.com/NV2/api.svc/';
/**
* @constant
* @type {string}
* @description The base URL for the trial ServiceObjects Name Validation 2 API service.
*/
const TrialBaseUrl = 'https://trial.serviceobjects.com/NV2/api.svc/';
/**
* <summary>
* Checks if a response from the API is valid by verifying that it either has no Error object
* or the Error.TypeCode is not equal to '3'.
* </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.TypeCode !== '3';
/**
* <summary>
* Constructs a full URL for the NameInfoV2 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}NameInfoV2?${querystring.stringify(params)}&format=json`;
/**
* <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<NameInfoV2Response>">A promise that resolves to a NameInfoV2Response 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 NameInfoV2Response(response.data);
} catch (error) {
throw new Error(`HTTP request failed: ${error.message}`);
}
};
/**
* <summary>
* Provides functionality to call the ServiceObjects Name Validation 2 API's NameInfoV2 endpoint,
* retrieving name validation information with fallback to a backup endpoint for reliability in live mode.
* </summary>
*/
const NameInfoV2Client = {
/**
* <summary>
* Asynchronously invokes the NameInfoV2 API endpoint, attempting the primary endpoint
* first and falling back to the backup if the response is invalid (Error.TypeCode == '3') in live mode.
* </summary>
* @param {string} Name - The name to validate.
* @param {string} Option - Comma-separated list of options for additional processing (optional).
* @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<NameInfoV2Response>} - A promise that resolves to a NameInfoV2Response object.
*/
async invokeAsync(Name, Option = '', LicenseKey, isLive = true, timeoutSeconds = 15) {
const params = {
Name,
Option,
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 NameInfoV2 API endpoint by wrapping the async call
* and awaiting its result immediately.
* </summary>
* @returns {NameInfoV2Response} - A NameInfoV2Response object with name validation details or an error.
*/
invoke(Name, Option = '', LicenseKey, isLive = true, timeoutSeconds = 15) {
return (async () => await this.invokeAsync(
Name, Option, LicenseKey, isLive, timeoutSeconds
))();
}
};
export { NameInfoV2Client, NameInfoV2Response };
class BestGuessName {
constructor(data = {}) {
this.Prefix = data.Prefix;
this.FirstName = data.FirstName;
this.MiddleName = data.MiddleName;
this.LastName = data.LastName;
this.Suffix = data.Suffix;
}
toString() {
return `{Prefix: ${this.Prefix}\n` +
`FirstName: ${this.FirstName}\n` +
`MiddleName: ${this.MiddleName}\n` +
`LastName: ${this.LastName}\n` +
`Suffix: ${this.Suffix}}`;
}
}
class NameInfoV2 {
constructor(data = {}) {
this.BestGuessName = data.BestGuessName ? new BestGuessName(data.BestGuessName) : "";
this.NameIn = data.NameIn;
this.NameClassification = data.NameClassification;
this.Prefix = data.Prefix;
this.FirstName = data.FirstName;
this.MiddleName = data.MiddleName;
this.LastName = data.LastName;
this.Suffix = data.Suffix;
this.FirstNameFound = data.FirstNameFound;
this.IsCommonFirstName = data.IsCommonFirstName;
this.FirstNameOrigin = data.FirstNameOrigin;
this.FirstNameSimilar = data.FirstNameSimilar;
this.LastNameFound = data.LastNameFound;
this.IsCommonLastName = data.IsCommonLastName;
this.LastNameOrigin = data.LastNameOrigin;
this.LastNameSimilar = data.LastNameSimilar;
this.Gender = data.Gender;
this.FirstNameAlt = data.FirstNameAlt;
this.MiddleNameAlt = data.MiddleNameAlt;
this.LastNameAlt = data.LastNameAlt;
this.FirstNameAltFound = data.FirstNameAltFound;
this.LastNameAltFound = data.LastNameAltFound;
this.GenderAlt = data.GenderAlt;
this.RelatedNames = data.RelatedNames;
this.IsCorrectedName = data.IsCorrectedName;
this.IsBusinessName = data.IsBusinessName;
this.BusinessName = data.BusinessName;
this.VulgarityScore = data.VulgarityScore;
this.CelebrityScore = data.CelebrityScore;
this.BogusScore = data.BogusScore;
this.GarbageScore = data.GarbageScore;
this.FirstNameDictionaryScore = data.FirstNameDictionaryScore;
this.MiddleNameDictionaryScore = data.MiddleNameDictionaryScore;
this.LastNameDictionaryScore = data.LastNameDictionaryScore;
this.OverallNameScore = data.OverallNameScore;
this.IsNameGood = data.IsNameGood;
this.StatusCodes = data.StatusCodes;
this.Status = data.Status;
}
toString() {
return `{BestGuessName: ${this.BestGuessName ? this.BestGuessName.toString() : 'null'}\n` +
`NameIn: ${this.NameIn}\n` +
`NameClassification: ${this.NameClassification}\n` +
`Prefix: ${this.Prefix}\n` +
`FirstName: ${this.FirstName}\n` +
`MiddleName: ${this.MiddleName}\n` +
`LastName: ${this.LastName}\n` +
`Suffix: ${this.Suffix}\n` +
`FirstNameFound: ${this.FirstNameFound}\n` +
`IsCommonFirstName: ${this.IsCommonFirstName}\n` +
`FirstNameOrigin: ${this.FirstNameOrigin}\n` +
`FirstNameSimilar: ${this.FirstNameSimilar}\n` +
`LastNameFound: ${this.LastNameFound}\n` +
`IsCommonLastName: ${this.IsCommonLastName}\n` +
`LastNameOrigin: ${this.LastNameOrigin}\n` +
`LastNameSimilar: ${this.LastNameSimilar}\n` +
`Gender: ${this.Gender}\n` +
`FirstNameAlt: ${this.FirstNameAlt}\n` +
`MiddleNameAlt: ${this.MiddleNameAlt}\n` +
`LastNameAlt: ${this.LastNameAlt}\n` +
`FirstNameAltFound: ${this.FirstNameAltFound}\n` +
`LastNameAltFound: ${this.LastNameAltFound}\n` +
`GenderAlt: ${this.GenderAlt}\n` +
`RelatedNames: ${this.RelatedNames}\n` +
`IsCorrectedName: ${this.IsCorrectedName}\n` +
`IsBusinessName: ${this.IsBusinessName}\n` +
`BusinessName: ${this.BusinessName}\n` +
`VulgarityScore: ${this.VulgarityScore}\n` +
`CelebrityScore: ${this.CelebrityScore}\n` +
`BogusScore: ${this.BogusScore}\n` +
`GarbageScore: ${this.GarbageScore}\n` +
`FirstNameDictionaryScore: ${this.FirstNameDictionaryScore}\n` +
`MiddleNameDictionaryScore: ${this.MiddleNameDictionaryScore}\n` +
`LastNameDictionaryScore: ${this.LastNameDictionaryScore}\n` +
`OverallNameScore: ${this.OverallNameScore}\n` +
`IsNameGood: ${this.IsNameGood}\n` +
`StatusCodes: ${this.StatusCodes}\n` +
`Status: ${this.Status}\n`;
}
}
class Error {
constructor(data = {}) {
this.Type = data.Type;
this.TypeCode = data.TypeCode;
this.Desc = data.Desc;
this.DescCode = data.DescCode;
}
toString() {
return `Type: ${this.Type}\n` +
`TypeCode: ${this.TypeCode}\n` +
`Desc: ${this.Desc}\n` +
`DescCode: ${this.DescCode} `;
}
}
class NameInfoV2Response {
constructor(data = {}) {
this.NameInfoV2 = data.NameInfoV2 ? new NameInfoV2(data.NameInfoV2) : null;
this.Error = data.Error ? new Error(data.Error) : null;
}
toString() {
return `NameInfoV2: ${(this.NameInfoV2 ? this.NameInfoV2.toString() : 'null')}\n` +
`Error: ${this.Error ? this.Error.toString() : 'null'}`;
}
}
export{ NameInfoV2Response };