Email Validation C# Code Snippet

using System.Web;

namespace email_validation_3_dot_net.REST
{
    /// <summary>
    /// Provides functionality to call the ServiceObjects Email Validation 3 REST API's ValidateEmailAddress endpoint,
    /// performing email validation with optional correction support and fallback to a backup endpoint in live mode.
    /// </summary>
    public class ValidateEmailAddressClient
    {
        // Base URLs for the Email Validation 3 service.
        private const string LiveBaseUrl = "https://sws.serviceobjects.com/ev3/web.svc/";
        private const string BackupBaseUrl = "https://swsbackup.serviceobjects.com/ev3/web.svc/";
        private const string TrialBaseUrl = "https://trial.serviceobjects.com/ev3/web.svc/";

        /// <summary>
        /// Synchronously calls the ValidateEmailAddress REST endpoint to validate an email address,
        /// 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 email address, license key, and options.</param>
        /// <returns>Deserialized <see cref="EV3Response"/> containing the validation results.</returns>
        public static EV3Response Invoke(ValidationEmailAddressInput input)
        {
            //Use query string parameters so missing/options fields don't break
            //the URL as path parameters would.
            string url = BuildUrl(input, input.IsLive ? LiveBaseUrl : TrialBaseUrl);
            EV3Response response = Helper.HttpGet<EV3Response>(url, input.TimeoutSeconds);

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

            return response;
        }

        /// <summary>
        /// Asynchronously calls the ValidateEmailAddress REST endpoint to validate an email address,
        /// 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 email address, license key, and options.</param>
        /// <returns>Deserialized <see cref="EV3Response"/> containing the validation results.</returns>
        /// <exception cref="ArgumentException">Thrown when the email address is missing.</exception>
        public static async Task<EV3Response> InvokeAsync(ValidationEmailAddressInput input)
        {
            //Use query string parameters so missing/options fields don't break
            //the URL as path parameters would.
            string url = BuildUrl(input, input.IsLive ? LiveBaseUrl : TrialBaseUrl);
            EV3Response response = await Helper.HttpGetAsync<EV3Response>(url, input.TimeoutSeconds).ConfigureAwait(false);

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

            return response;
        }

        // Build the full request URL, including URL-encoded query string
        public static string BuildUrl(ValidationEmailAddressInput input, string baseUrl)
        {
            var qs = $"JSON/ValidateEmailAddress?" +
                     $"EmailAddress={HttpUtility.UrlEncode(input.EmailAddress)}" +
                     $"&AllowCorrections={HttpUtility.UrlEncode(input.AllowCorrections)}" +
                     $"&TIMEOUT={HttpUtility.UrlEncode(input.Timeout)}" +
                     $"&LicenseKey={HttpUtility.UrlEncode(input.LicenseKey)}";
            return baseUrl + qs;
        }

        private static bool IsValid(EV3Response response) =>
            response?.Error == null || response.Error.TypeCode != "3";

        /// <summary>
        /// Represents the input parameters for the ValidateEmailAddress REST API call.
        /// </summary>
        /// <param name="EmailAddress">The email address to validate.</param>
        /// <param name="LicenseKey">Your license key to use the service.</param>
        /// <param name="AllowCorrections">Whether the service should return a corrected email address if one is found (true/false).</param>
        /// <param name="IsLive">Determines whether to use the live or trial service.</param>
        /// <param name="TimeoutSeconds">Timeout, in seconds, for the call to the service.</param>
        public record ValidationEmailAddressInput(
            string EmailAddress = "",
            string LicenseKey = "",
            string AllowCorrections = "",
            string Timeout = "",
            bool IsLive = true,
            int TimeoutSeconds = 15
        );
    }
}


using System.Runtime.Serialization;

namespace email_validation_3_dot_net.REST
{
    /// <summary>
    /// Represents the combined request and response data for performing comprehensive
    /// email address validation using the Email Validation 3 REST API.
    /// </summary>
    [DataContract]
    public class EV3Response
    {
        public string LicenseKey { get; set; }
        public string EmailAddress { get; set; }
        public string AllowCorrections { get; set; }
        public ValidateEmailInfo ValidateEmailInfo { get; set; }
        public Error Error { get; set; }
    }

    /// <summary>
    /// Represents the detailed results of any email validation operation in the Email Validation 3 REST API.
    /// </summary>
    [DataContract]
    public class ValidateEmailInfo
    {
        public int Score { get; set; }
        public string IsDeliverable { get; set; }
        public string EmailAddressIn { get; set; }
        public string EmailAddressOut { get; set; }
        public bool EmailCorrected { get; set; }
        public string Box { get; set; }
        public string Domain { get; set; }
        public string TopLevelDomain { get; set; }
        public string TopLevelDomainDescription { get; set; }
        public string IsSMTPServerGood { get; set; }
        public string IsCatchAllDomain { get; set; }
        public string IsSMTPMailBoxGood { get; set; }
        public string WarningCodes { get; set; }
        public string WarningDescriptions { get; set; }
        public string NotesCodes { get; set; }
        public string NotesDescriptions { get; set; }
        public Error Error { get; set; }
        public override string ToString()
        {
            string error = Error != null ? Error.ToString() : "None";
            return $"ValidateEmailInfo: Score = {Score}, IsDeliverable = {IsDeliverable}, " +
                   $"EmailAddressIn = {EmailAddressIn}, EmailAddressOut = {EmailAddressOut}, " +
                   $"EmailCorrected = {EmailCorrected}, Box = {Box}, Domain = {Domain}, " +
                   $"TopLevelDomain = {TopLevelDomain}, TopLevelDomainDescription = {TopLevelDomainDescription}, " +
                   $"IsSMTPServerGood = {IsSMTPServerGood}, IsCatchAllDomain = {IsCatchAllDomain}, " +
                   $"IsSMTPMailBoxGood = {IsSMTPMailBoxGood}, WarningCodes = {WarningCodes}, " +
                   $"WarningDescriptions = {WarningDescriptions}, NotesCodes = {NotesCodes}, " +
                   $"NotesDescriptions = {NotesDescriptions}, Error = {error}";
        }
    }
    /// <summary>
    /// Represents error information in the Lead Validation International REST API response.
    /// </summary>
    [DataContract]
    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 $"Error: Type = {Type}, TypeCode = {TypeCode}, Desc = {Desc}, DescCode = {DescCode}";
        }
    }
}


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

namespace email_validation_3_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);
    }
}

Email Validation 3 Python Code Snippet

import requests  # HTTP client for RESTful API calls
from ev3_response import EV3Response, Error, ValidateEmailInfo

# Endpoint URLs for EV3 ValidateEmailAddress REST API
primary_url = "https://sws.serviceobjects.com/ev3/web.svc/JSON/ValidateEmailAddress?"
backup_url = "https://swsbackup.serviceobjects.com/ev3/web.svc/JSON/ValidateEmailAddress?"
trial_url = "https://trial.serviceobjects.com/ev3/web.svc/JSON/ValidateEmailAddress?"


def validate_email_address(
    email_address: str,
    allow_corrections: str,
    license_key: str,
    timeout: str,
    is_live: bool = True,
    timeout_seconds: int = 15,
) -> EV3Response:
    """
    Call EV3 ValidateEmailAddress API to validate an email address.

    Parameters:
        email_address: Email address to validate.
        allow_corrections: "true" or "false" - whether the API can return a corrected email.
        license_key: Your ServiceObjects license key.
        timeout: Timeout value (in milliseconds) passed to the API.
        is_live: Value to determine whether to use the live or trial servers.
        timeout_seconds: Timeout, in seconds, for the call to the service.

    Returns:
        EV3Response: Parsed JSON response with validation results or error details.
    """

    params = {
        "EmailAddress": email_address,
        "AllowCorrections": allow_corrections,
        "TIMEOUT": timeout,
        "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=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"EV3 service error: {data['Error']}")
            else:
                # Trial mode error is terminal
                raise RuntimeError(f"EV3 trial error: {data['Error']}")

        # Convert JSON response to EV3Response for structured access
        error = Error(**data.get("Error", {})) if data.get("Error") else None
        validate_info = (
            ValidateEmailInfo(**data.get("ValidateEmailInfo", {}))
            if data.get("ValidateEmailInfo")
            else None
        )

        return EV3Response(
            LicenseKey=data.get("LicenseKey"),
            EmailAddress=data.get("EmailAddress"),
            AllowCorrections=data.get("AllowCorrections"),
            ValidateEmailInfo=validate_info,
            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"EV3 backup error: {data['Error']}") from req_exc

                error = Error(**data.get("Error", {})) if data.get("Error") else None
                validate_info = (
                    ValidateEmailInfo(**data.get("ValidateEmailInfo", {}))
                    if data.get("ValidateEmailInfo")
                    else None
                )

                return EV3Response(
                    LicenseKey=data.get("LicenseKey"),
                    EmailAddress=data.get("EmailAddress"),
                    AllowCorrections=data.get("AllowCorrections"),
                    ValidateEmailInfo=validate_info,
                    Error=error,
                )
            except Exception as backup_exc:
                raise RuntimeError("EV3 service unreachable on both endpoints") from backup_exc
        else:
            raise RuntimeError(f"EV3 trial error: {str(req_exc)}") from req_exc


from dataclasses import dataclass
from typing import Optional


@dataclass
class Error:
    Type: Optional[str] = None
    TypeCode: Optional[str] = None
    Desc: Optional[str] = None
    DescCode: Optional[str] = None
    Number: Optional[str] = None

    def __str__(self) -> str:
        return (f"Error: Type={self.Type}, TypeCode={self.TypeCode}, "
                f"Desc={self.Desc}, DescCode={self.DescCode}")


@dataclass
class ValidateEmailInfo:
    Score: Optional[str] = None
    IsDeliverable: Optional[str] = None
    EmailAddressIn: Optional[str] = None
    EmailAddressOut: Optional[str] = None
    EmailCorrected: Optional[str] = None
    Box: Optional[str] = None
    Domain: Optional[str] = None
    TopLevelDomain: Optional[str] = None
    TopLevelDomainDescription: Optional[str] = None
    IsSMTPServerGood: Optional[str] = None
    IsCatchAllDomain: Optional[str] = None
    IsSMTPMailBoxGood: Optional[str] = None
    WarningCodes: Optional[str] = None
    WarningDescriptions: Optional[str] = None
    NotesCodes: Optional[str] = None
    NotesDescriptions: Optional[str] = None
    Error: Optional['Error'] = None

    def __str__(self) -> str:
        error = str(self.Error) if self.Error else "None"
        return (f"ValidateEmailInfo: Score={self.Score}, IsDeliverable={self.IsDeliverable}, "
                f"EmailAddressIn={self.EmailAddressIn}, EmailAddressOut={self.EmailAddressOut}, "
                f"EmailCorrected={self.EmailCorrected}, Box={self.Box}, Domain={self.Domain}, "
                f"TopLevelDomain={self.TopLevelDomain}, TopLevelDomainDescription={self.TopLevelDomainDescription}, "
                f"IsSMTPServerGood={self.IsSMTPServerGood}, IsCatchAllDomain={self.IsCatchAllDomain}, "
                f"IsSMTPMailBoxGood={self.IsSMTPMailBoxGood}, WarningCodes={self.WarningCodes}, "
                f"WarningDescriptions={self.WarningDescriptions}, NotesCodes={self.NotesCodes}, "
                f"NotesDescriptions={self.NotesDescriptions}, Error={error}")


@dataclass
class EV3Response:
    LicenseKey: Optional[str] = None
    EmailAddress: Optional[str] = None
    AllowCorrections: Optional[str] = None
    ValidateEmailInfo: Optional['ValidateEmailInfo'] = None
    Error: Optional['Error'] = None

    def __str__(self) -> str:
        validate_email_info = str(self.ValidateEmailInfo) if self.ValidateEmailInfo else "None"
        error = str(self.Error) if self.Error else "None"
        return (f"EV3Response: LicenseKey={self.LicenseKey}, EmailAddress={self.EmailAddress}, "
                f"AllowCorrections={self.AllowCorrections}, ValidateEmailInfo={validate_email_info}, Error={error}")

Email Validation 3 NodeJS Code Snippet

import axios from 'axios';
import querystring from 'querystring';
import { EV3Response } from './ev3_response.js';

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

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

/**
 * @constant
 * @type {string}
 * @description The base URL for the trial ServiceObjects Email Validation 3 API service.
 */
const TrialBaseUrl = 'https://trial.serviceobjects.com/ev3/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 '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 ValidateEmailAddress 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/ValidateEmailAddress?${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<EV3Response>">A promise that resolves to an EV3Response 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 EV3Response(response.data);
    } catch (error) {
        throw new Error(`HTTP request failed: ${error.message}`);
    }
};

/**
 * <summary>
 * Provides functionality to call the ServiceObjects Email Validation 3 API's ValidateEmailAddress endpoint,
 * performing email validation with optional correction support and fallback to a backup endpoint in live mode.
 * </summary>
 */
const ValidateEmailAddressClient = {
    /**
     * <summary>
     * Asynchronously invokes the ValidateEmailAddress 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 name="emailAddress" type="string">The email address to validate.</param>
     * <param name="allowCorrections" type="string">Whether the service should return a corrected email address if one is found (true/false).</param>
     * <param name="licenseKey" type="string">Your license key to use the service.</param>
     * <param name="isLive" type="boolean">Determines whether to use the live or trial service.</param>
     * <param name="timeoutSeconds" type="number">Timeout, in seconds, for the call to the service.</param>
     * <returns type="Promise<EV3Response>">A promise that resolves to an EV3Response object.</returns>
     */
    async invokeAsync(emailAddress, allowCorrections, licenseKey, isLive, timeout, timeoutSeconds = 15) {
        const params = {
            EmailAddress: emailAddress,
            AllowCorrections: allowCorrections,
            TIMEOUT: timeout,
            LicenseKey: 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 fallbackResponse;
        }

        return response;
    },

    /**
     * <summary>
     * Synchronously invokes the ValidateEmailAddress API endpoint by wrapping the async call
     * and awaiting its result immediately.
     * </summary>
     * <param name="emailAddress" type="string">The email address to validate.</param>
     * <param name="allowCorrections" type="string">Whether the service should return a corrected email address if one is found (true/false).</param>
     * <param name="licenseKey" type="string">Your license key to use the service.</param>
     * <param name="isLive" type="boolean">Determines whether to use the live or trial service.</param>
     * <param name="timeoutSeconds" type="number">Timeout, in seconds, for the call to the service.</param>
     * <returns type="EV3Response">An EV3Response object with validation details or an error.</returns>
     */
    invoke(emailAddress, allowCorrections, licenseKey, isLive, timeout, timeoutSeconds = 15) {
        return (async () => await this.invokeAsync(emailAddress, allowCorrections, licenseKey, isLive, timeout, timeoutSeconds))();
    }
};

export { ValidateEmailAddressClient, EV3Response };


export class ErrorModel {
    constructor(data = {}) {
        this.Type = data.Type;
        this.TypeCode = data.TypeCode;
        this.Desc = data.Desc;
        this.DescCode = data.DescCode;
        this.Number = data.Number;
    }

    toString() {
        return `Error: Type = ${this.Type}, TypeCode = ${this.TypeCode}, Desc = ${this.Desc}, DescCode = ${this.DescCode}`;
    }
}

export class ValidateEmailInfo {
    constructor(data = {}) {
        this.Score = data.Score;
        this.IsDeliverable = data.IsDeliverable;
        this.EmailAddressIn = data.EmailAddressIn;
        this.EmailAddressOut = data.EmailAddressOut;
        this.EmailCorrected = data.EmailCorrected;
        this.Box = data.Box;
        this.Domain = data.Domain;
        this.TopLevelDomain = data.TopLevelDomain;
        this.TopLevelDomainDescription = data.TopLevelDomainDescription;
        this.IsSMTPServerGood = data.IsSMTPServerGood;
        this.IsCatchAllDomain = data.IsCatchAllDomain;
        this.IsSMTPMailBoxGood = data.IsSMTPMailBoxGood;
        this.WarningCodes = data.WarningCodes;
        this.WarningDescriptions = data.WarningDescriptions;
        this.NotesCodes = data.NotesCodes;
        this.NotesDescriptions = data.NotesDescriptions;
        this.Error = data.Error ? new Error(data.Error) : null;
    }

    toString() {
        const error = this.Error ? this.Error.toString() : "None";
        return `ValidateEmailInfo: Score = ${this.Score}, IsDeliverable = ${this.IsDeliverable}, ` +
            `EmailAddressIn = ${this.EmailAddressIn}, EmailAddressOut = ${this.EmailAddressOut}, ` +
            `EmailCorrected = ${this.EmailCorrected}, Box = ${this.Box}, Domain = ${this.Domain}, ` +
            `TopLevelDomain = ${this.TopLevelDomain}, TopLevelDomainDescription = ${this.TopLevelDomainDescription}, ` +
            `IsSMTPServerGood = ${this.IsSMTPServerGood}, IsCatchAllDomain = ${this.IsCatchAllDomain}, ` +
            `IsSMTPMailBoxGood = ${this.IsSMTPMailBoxGood}, WarningCodes = ${this.WarningCodes}, ` +
            `WarningDescriptions = ${this.WarningDescriptions}, NotesCodes = ${this.NotesCodes}, ` +
            `NotesDescriptions = ${this.NotesDescriptions}, Error = ${error}`;
    }
}

export class EV3Response {
    constructor(data = {}) {
        this.LicenseKey = data.LicenseKey;
        this.EmailAddress = data.EmailAddress;
        this.AllowCorrections = data.AllowCorrections;
        this.ValidateEmailInfo = data.ValidateEmailInfo ? new ValidateEmailInfo(data.ValidateEmailInfo) : null;
        this.Error = data.Error ? new Error(data.Error) : null;
    }

    toString() {
        const validateEmailInfo = this.ValidateEmailInfo ? this.ValidateEmailInfo.toString() : "None";
        const error = this.Error ? this.Error.toString() : "None";
        return `EV3Response: LicenseKey = ${this.LicenseKey}, EmailAddress = ${this.EmailAddress}, ` +
            `AllowCorrections = ${this.AllowCorrections}, ValidateEmailInfo = ${validateEmailInfo}, Error = ${error}`;
    }
}

export default EV3Response;