Email Validation – Mailtrap https://mailtrap.io Modern email delivery for developers and product teams Mon, 24 Feb 2025 10:08:27 +0000 en-US hourly 1 https://mailtrap.io/wp-content/uploads/2023/01/cropped-favicon-1-32x32.png Email Validation – Mailtrap https://mailtrap.io 32 32 How to Validate Email Address in Go: Developer’s Tutorial https://mailtrap.io/blog/go-email-validation/ Thu, 20 Feb 2025 10:28:44 +0000 https://mailtrap.io/?p=41060 In this guide, I’ll walk you through the most common (and efficient) Go email validation approaches and provide you with code snippets for each.

Namely, I’ll cover Go email validation using:

Note: I’ll also include a section on email verification, to which you can jump to by clicking here.

Validate emails in Go using regex

To perform basic regex, or regular expression, checks against the email IDs, I recommend using Go’s native regexp package

The package is a part of Go’s standard library and is quite straightforward to use. It’s ideal for quick validation checks of the basic email address structure, but that’s that.

To get started, simply copy the following code into your main.go file:

package main

import (
	"fmt"
	"regexp"
)

func main() {
	// Define the stricter email regex pattern (based on RFC 5322)
	emailRegex := `^[a-zA-Z0-9.!#$%&'*+/=?^_` + "`" + `{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$`

	// Compile the regex
	re := regexp.MustCompile(emailRegex)

	// Test email addresses
	emails := []string{
		"test@example.com",           // Valid
		"invalid-email@",             // Invalid (missing domain)
		"user@domain.co",             // Valid
		"user@.com",                  // Invalid
		"foo@bar.com",                // Valid
		"special_chars+123@sub.com",  // Valid
		"missing@tld",                // Valid
		"email@domain-with-hyphen.com", // Valid
		"user@localhost",             // Invalid (no TLD)
	}

	// Validate each email and print the result
	for _, email := range emails {
		if re.MatchString(email) {
			fmt.Printf("%s is valid\n", email)
		} else {
			fmt.Printf("%s is invalid\n", email)
		}
	}
}

This regex is based on RFC 5322 and will make sure that the email:

  • Starts with a valid local part (username) that can consist of alphanumeric (a-z, A-Z, 0-9) and special (., !., #, $) characters.
  • Contains an @ symbol that separates the username and the domain.
  • Can have hyphens (-) but cannot start or end with one.
  • Has a valid domain part that starts with an alphanumeric character and is between 1 and 63 characters long.
  • Ends with a top-level domain (TLD) that contains at least two alphabetic characters (e.g., com, .org, etc.).

For testing purposes, I’ve added the // Test email addresses part of the code snippet. So, if you run the app with go run main.go, you should get the following results:

test@example.com is valid
invalid-email@ is invalid
user@domain.co is valid
user@.com is invalid
foo@bar.com is valid
special_chars+123@sub.com is valid
missing@tld is invalid
email@domain-with-hyphen.com is valid
user@localhost is invalid

Of course, feel free to change the emails in // Test email addresses if you want to test them out further. As for testing out different regex patterns, I suggest using regex101 or Go Playground. ⚒️

Important

  • Although simple to use, regex can’t cover all cases, such as super long or internationalized domains. You can see the possible trade-offs in this article
  • To extend the validation functionality of regex, you can combine it with other packages I’ll talk about in this article.⚒️

Validate emails in Go using the net/mail package 

Another native Go package you can use is net/mail. Similarly to the regex check from the previous chapter, it follows the syntax specified in RFC 5322, and it’s extended by RFC 6532.

Net/mail focuses solely on email parsing and syntax, making it a tad bit more advanced, but still a basic validation solution.

To use net/mail, copy the following code snippet into your main.go:

package main

import (
	"fmt"
	"net/mail"
)

func main() {
	// List of email addresses to validate
	emails := []string{
		"test@example.com",
		"invalid-email@",             // Missing domain
		"user@domain.co",             // Valid
		"user@.com",                  // Invalid domain
		"foo@bar.com",                // Valid
		"missing@tld",                // Invalid
		"email@domain-with-hyphen.com", // Valid
	}

	for _, email := range emails {
		// Use mail.ParseAddress for validation
		_, err := mail.ParseAddress(email)
		if err != nil {
			fmt.Printf("%s is invalid: %v\n", email, err)
		} else {
			fmt.Printf("%s is valid\n", email)
		}
	}
}

By adding this regex validation logic to your Go app/project, you ensure that:

  • The username (local part) cannot start or end with a dot (.).
  • The domain must have at least one period.
  • Domains cannot have consecutive periods or start/end with a hyphen (-).
  • The entire email doesn’t exceed 254 characters.
  • The email doesn’t contain any invalid characters (e.g., spaces and commas).
  • Both the local and the domain parts meet length constraints of the standard (e.g., 64-character limit for the local part) 

And when you run the code, you should expect to see these results:

test@example.com is valid
invalid-email@ is invalid: mail: missing '@' or angle-addr
user@domain.co is valid
user@.com is invalid: mail: invalid domain
foo@bar.com is valid
missing@tld is invalid: mail: invalid domain
email@domain-with-hyphen.com is valid

Tip: To validate multiple email addresses in a single string (e.g., a comma-separated list), use mail.ParseAddressList. And here’s a code example you can copy/paste:

package main

import (
	"fmt"
	"net/mail"
)

func main() {
	// Comma-separated list of email addresses
	emailList := "test@example.com, invalid-email@, user@domain.co, foo@bar.com"

	// Parse and validate the list
	addresses, err := mail.ParseAddressList(emailList)
	if err != nil {
		fmt.Printf("Invalid list: %v\n", err)
		return
	}

	// Print valid addresses
	fmt.Println("Valid emails:")
	for _, address := range addresses {
		fmt.Println(address.Address)
	}
}

And here’s the output you can expect in case any email in the list is invalid:

Invalid list: mail: missing '@' or angle-addr

Validate emails in Go using external packages

If you want to spice it up a bit, you can also use external packages for Go. I’ve scoured the web for the best ones, tried them all, and ditched the packages that aren’t being regularly maintained and the ones that are not efficient. Here’s what I came up with: 

go-playground/validator

validator by go-playground isn’t your typical validation package as it has more features than just validation. Also, it doesn’t include DNS/MX records or SMTP checks, which makes it great for users who don’t require any external dependencies but still want to implement straightforward validation logic. 

With go-playground/validator, you can:

  • Validate the email format.
  • Define custom validation functions for more specific use cases.
    • For example: 
  • Validate struct fields based on tags, which can come in handy for form or input validation. E.g.
type User struct {
    Email string `validate:"required,email"`
}
  • Validate strings, numbers, URLs, and more.

And, similarly to checkmail, this package also offers detailed error messages for better debugging. It even supports field-error mapping. 

To set up and use go-playground’s validator, you first need to install it with the following command:

go get github.com/go-playground/validator/v10

Then, import the package in your main.go file:

import (
    "fmt"
    "github.com/go-playground/validator/v10"
)

Create and initialize a new validator instance:

validate := validator.New()

Lastly, define a struct with validation tags and validate it:

type User struct {
    Email string `validate:"required,email"`
}

func main() {
    user := User{Email: "example@example.com"}
    err := validate.Struct(user)

    if err != nil {
        // Print detailed validation errors
        for _, err := range err.(validator.ValidationErrors) {
            fmt.Printf("Field '%s' failed validation for tag '%s'\n", err.Field(), err.Tag())
        }
    } else {
        fmt.Println("Validation passed!")
    }
}

To validate individual fields instead of a struct, use this code:

err := validate.Var("example@example.com", "required,email")
if err != nil {
    fmt.Println("Invalid email!")
} else {
    fmt.Println("Valid email!")
}

On the other hand, if you want to define and register custom validation functions, here’s a code snippet you can play around with and use:

// Custom function to validate email domain
func validDomain(fl validator.FieldLevel) bool {
    domain := "example.com"
    return strings.HasSuffix(fl.Field().String(), domain)
}

func main() {
    validate := validator.New()

    // Register custom validation tag
    validate.RegisterValidation("domain", validDomain)

    type User struct {
        Email string `validate:"required,email,domain"`
    }

    user := User{Email: "test@example.com"}
    err := validate.Struct(user)

    if err != nil {
        fmt.Println("Validation failed:", err)
    } else {
        fmt.Println("Validation passed!")
    }
}

AfterShip/email-verifier

Don’t let the name of this package confuse you, because email-verifier by AfterShip is actually an email validator (more on differences between verification and validation in the next chapter). The package offers more advanced features than the previous two and allows you to;

  • Validate the email address format.
  • Perform DNS/MX record checks
  • Verify the SMTP connection.
  • Identify disposable email addresses, such as Mailinator.
  • Detect email addresses that belong to free providers (e.g., Gmail, Yahoo, etc.)
  • Identify role-based email addresses like support@domain.com.
  • Check for catch-all domains that accept emails from any address.

Additionally, email-verifier provides you with precise feedback when an email fails validation, instead of detailed error messages. Here’s how it works:

Start by installing the package with the following command:

go get github.com/AfterShip/email-verifier

Import the package and any other necessary libraries in your main.go file:

package main

import (
    "fmt"
    emailverifier "github.com/AfterShip/email-verifier"
)


var (
	verifier = emailverifier.NewVerifier()
)
func main() {
      email := "test@example.com"

	ret, err := verifier.Verify(email)
	if err != nil {
		fmt.Println("verify email address failed, error is: ", err)
		return
	}
	if !ret.Syntax.Valid {
		fmt.Println("email address syntax is invalid")
		return
	}

	// Print the result fields based on the updated API
	fmt.Println("Email Validation Result:")
	fmt.Println("Email:", ret.Email)
	fmt.Println("Syntax Valid:", ret.Syntax.Valid)
	fmt.Println("Disposable:", ret.Disposable)
	fmt.Println("Reachable:", ret.Reachable)
	fmt.Println("Role Account:", ret.RoleAccount)
	fmt.Println("Free Provider:", ret.Free)
	fmt.Println("Has MX Records:", ret.HasMxRecords)

}

Note: The code above imports and creates a new instance of the package, checks the email’s format, DNS records, whether it’s disposable, catch-all, etc. However, you can add/remove features as you see fit.

How to choose the right external package for Go email validation

If you’re having a hard time choosing an external package, think about what your app needs, how easy to use the package is, and whether it’s regularly updated. 

For your convenience, here’s a table summarizing the most important aspects:

Featurego-playground/validatorAfterShip/email-verifier
Format validation
DNS/MX record check
SMTP verification
Disposable email detection
Ease of use✅ Very easy to use❌ A bit more complex
Requires external dependencies
Best forValidation with extra featuresMore complex validation
MIT license

Disclaimer: As of writing this article, all packages I mention are being actively maintained. However, I’d still recommend you to double check the release history or use Snyk to see the package health score.

Bonus: email verification in Go

If we assume that email validation ensures email addresses are entered correctly without typos, email verification is a process that takes this a step further.  

Email verification not only detects typos but also sends an activation link or code to the user’s email address, which they then need to activate to verify their address. This way, you can ensure that the email address belongs to an actual user.

For email verification in Go, I’ve found that JWT tokens work best for me. Moreover, the logic is quite simple. And here’s the code snippet you can feel free to copy/paste into your main.go file:

package main

import (
	"fmt"
	"log"
	"net/http"
	"time"

	"github.com/golang-jwt/jwt/v4"
	"gopkg.in/gomail.v2"
)

var jwtSecret = []byte("your_secret_key")

// Generate a JWT token for email verification
func generateToken(email string) (string, error) {
	claims := jwt.MapClaims{
		"email": email,
		"exp":   time.Now().Add(30 * time.Minute).Unix(),
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	return token.SignedString(jwtSecret)
}

// Send verification email
func sendVerificationEmail(email, token string) error {
	m := gomail.NewMessage()
	m.SetHeader("From", "sender@example.com")
	m.SetHeader("To", email)
	m.SetHeader("Subject", "Email Verification")
	verificationLink := fmt.Sprintf("http://localhost:8080/verify?token=%s", token)
	m.SetBody("text/plain", fmt.Sprintf("Hi,\n\nPlease verify your email by clicking the link below:\n%s\n\nThis link will expire in 30 minutes.", verificationLink))

	d := gomail.NewDialer("smtp.mailtrap.io", 587, "your_mailtrap_username", "your_mailtrap_password")
	return d.DialAndSend(m)
}

// Email verification handler
func verifyHandler(w http.ResponseWriter, r *http.Request) {
	tokenString := r.URL.Query().Get("token")
	if tokenString == "" {
		http.Error(w, "Missing token", http.StatusBadRequest)
		return
	}

	// Parse and validate the token
	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
		return jwtSecret, nil
	})

	if err != nil || !token.Valid {
		http.Error(w, "Invalid or expired token", http.StatusBadRequest)
		return
	}

	claims, ok := token.Claims.(jwt.MapClaims)
	if !ok || !token.Valid {
		http.Error(w, "Invalid token", http.StatusBadRequest)
		return
	}

	email := claims["email"].(string)
	w.Write([]byte(fmt.Sprintf("Email %s has been successfully verified!", email)))
}

func main() {
	// Simulate sending verification email
	http.HandleFunc("/send", func(w http.ResponseWriter, r *http.Request) {
		email := r.URL.Query().Get("email")
		if email == "" {
			http.Error(w, "Missing email", http.StatusBadRequest)
			return
		}
		token, err := generateToken(email)
		if err != nil {
			http.Error(w, "Failed to generate token", http.StatusInternalServerError)
			return
		}
		err = sendVerificationEmail(email, token)
		if err != nil {
			http.Error(w, "Failed to send email", http.StatusInternalServerError)
			return
		}
		w.Write([]byte("Verification email sent"))
	})

	// Verify endpoint
	http.HandleFunc("/verify", verifyHandler)

	fmt.Println("Server running on :8080")
	log.Fatal(http.ListenAndServe(":8080", nil))
}

Code breakdown:

  • generateToken creates a JWT token with the user’s email in the payload.
  • /send?email=<email> triggers the email verification flow and sendVerificationEmail.
  • sendVerificationEmail sends the email with the verification link and token.
    • Keep in mind that you need an email service for this Golang email-sending logic to work. As you can notice from the comments in the code, I personally use Mailtrap SMTP, which provides me with a reliable email infrastructure and ready-to-use code snippets.
  • verifyHandler extracts the token from the URL, verifies it, and extracts the user’s email from the token claims. 
  • /verify?token=<token> verifies the token and email.

Next, start the server with go run main.go and then run the following command to trigger an email:

http://localhost:8080/send?email=test@example.com

Check your inbox for the verification link, click it, or simply manually call:

http://localhost:8080/verify?token=<your-token>

Lastly, keep in mind that I’ve added expiration logic, so the token will be valid for 30 minutes.

Email validation as part of email testing

By inspecting the format of email addresses (validation) and the existence of a user behind them (verification), you keep your email lists clean and improve your email deliverability, but only to a certain extent. 

Namely, both validation and verification are only aspects of email testing, the missing link you’re looking for. This is an industry-standard practice that ensures your emails are pitch perfect before you send them out, that they pass spam checks, and that your domain isn’t on a blacklist.

That’s why I always recommend Mailtrap Email Testing, which can help me with all of the above and more.

With Email Testing, you can catch traffic from staging and dev environments and analyze the HTML/CSS of your emails. This allows you to easily spot and, most importantly, remove or fix any faulty lines of code you notice, making your email impeccable.

There is also the Spam Analysis feature, which lets you see how likely your emails are to pass spam filters. It’s super simple: you get a spam score, use the detailed table to make adjustments (if any are needed), and keep the score under 5 to proactively boost your email deliverability

Finally, I must mention that besides being packed with advanced features, Mailtrap Email Testing is also super easy to configure. You can learn how to test emails in Golang by reading our in-depth article or follow along with the video our YouTube team has prepared for you! 

Further reading on email validation:

]]>
How to Validate Emails in React https://mailtrap.io/blog/validate-emails-in-react/ Fri, 27 Dec 2024 09:37:00 +0000 https://mailtrap.io/?p=12988 Try to wrap your mind around this fact: 10% of email addresses entered into checkouts and sign up forms are invalid. Then, think about how mobile traffic has drastically increased in the last couple of years, and imagine the number of invalid email addresses entered via a mobile device. Since “mobile” usually goes hand in hand with “fat fingers”. 

These two simple facts remind us that email validation is still a “thing”, and it is absolutely essential to validate email address input in any registration form.

Ready to deliver your emails?
Try Mailtrap for Free

Email validation VS email verification: what you need to know

While email validation may be part of the email verification process, they are not the same. Be careful not to mix them up and not to use them interchangeably.

Email validation is a procedure that helps identify if an email address is free of typos. Basically, email validation aims to detect and prevent typos and invalid email addresses being entered into any forms. Email validation is mostly (but not always) done at the frontend.

Email validation is used:

  • To prevent users from making typos at the time of input
  • To limit the registration procedure to a certain group of users  (i.g. you can’t sign up into Cambridge University library with your personal email domain, you need your “edu” domain account  for this purpose);
  • To decrease the number of requests sent to the server and lower the server load (this is particularly important for big businesses).

Email verification is a process that helps verify if there is an actual user on the receiving end of the email address. Email validation could be part of email verification (and it usually is), however email verification is a more complex procedure involving both frontend and backend. To verify an email address properly, you will need to send an activation link/code to that email. Then the end user should activate it from their inbox: and we are talking about email confirmation here. When sending emails for a multilingual campaign, also validate React localization to ensure that all content elements are translated correctly.

Email verification is used:

  • To prevent hard bounces;
  • To protect your sender’s reputation;
  • To keep your email sending list up-to-date;
  • To prevent your domain from being blacklisted;
  • To increase security and prevent users from malicious data input;
  • To cut costs on email marketing (not to waste money on useless inactive or falsified email addresses and lists)

Email validation aka input validation 

A valid email address consists of three parts: an individual part, the at-sign @, and a domain name part. If any of these parts are missing, misspelt, or misplaced, an email address becomes invalid.

According to the specifications of most Internet mail systems, the individual (local) part of an email address may consist only of the following ASCII standard characters:

  • digits—0 to 9
  • lowercase and uppercase Latin letters—a to z and A to Z
  • printable characters—!#$%&’*+-/=?^_`{|}~
  • dot—., as long as it is not the initial or final character, or is not used in succession

The domain name part comprises of the following characters:

  • digits—0 to 9
  • lowercase and uppercase Latin letters—a to z and A to Z
  • hyphen or dot — – or . , as long as they are not the initial or final characters

So how to validate email format in React.js?

There are a lot of methods. We’ll discuss a few of the most popular ones.

Email validation regex in React.js

Whichever method of email validation in React.js you choose, you cannot do without a regular expression. It is also called validation regex or regular expression. Regex is a pattern used to match character combinations in strings. Mind that in JavaScript, regex is also an object.

Validation regex is used in all React form validation libraries, it is also essential to your individual email validation solution. Let’s just say validation regex is a must whenever you need to validate any form.

Normally, React email validation regex  would look something like this:

/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i;

Which is kind of scary, but each component of this expression has its meaning targeted at verifying the input of digits, characters, and letters of email address parts.

Email validation as part of form validation in React. Js

There are plenty of ways you can perform email validation in React.js. In fact, you can even create your own library for this purpose! However, there is no need to reinvent the wheel. One of the coolest things about React is that you can use suitable tooling for almost everything you  want 🙂

Email validation in React.js could be seen as part of a more general context: form management and form validation. There are plenty of libraries to manage forms in React  such as Formik, React Final Form, Unform, React Form, Simple React Validator etc. In this article, I’ll show you how to validate email addresses with the two of them:  Formik and React Hook Form.

Method one: email validation with Formik library

Formik is a React and React Native library that helps you create and validate forms in React “without the tears”.

First, you need to install Formik:

npm i formik

Then add the useFormik hook to manage submissions, and changes in email inputs in the src/App.js :

import { useFormik } from 'formik';

Then structure the useFormik hook:

const formik = useFormik({
  initialValues: {
    email: '',
  },
  validate,
  onSubmit: (values) => {
    alert(JSON.stringify(values, null, 2))
  },
})

where initialValues is an object containing the default values, and onSubmit is the function that is called when the email form validation passes.

validate is our separate validation function, that is in charge of handling our form validation per se.

Here’s how you code the validate function:

const validate = (values) => {
  const errors = {}

  if (!values.email) {
    errors.email = 'Required'
  } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
    errors.email = 'Invalid email address'
  }

  return errors
}

This is how the entire piece of code would look like (where the return function obviously returns the pre-coded form after validation):

import React from 'react';
import { useFormik } from 'formik'

const validate = (values) => {
  const errors = {}

  if (!values.email) {
    errors.email = 'Required'
  } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
    errors.email = 'Invalid email address'
  }

  return errors
}

export default function App() {
  const formik = useFormik({
    initialValues: {
      email: '',
    },
    validate,
    onSubmit: (values) => {
      alert(JSON.stringify(values, null, 2))
    },
  })
return (
      <form onSubmit={formik.handleSubmit}>
          <label htmlFor="email">Email</label>
          <input type="email" name="email" id="email"
            onChange={formik.handleChange} onBlur={formik.handleBlur} value={formik.values.email} />
          {formik.touched.email && formik.errors.email ? (
            <span>{formik.errors.email}</span>
          ) : null}
          <button type='submit'>Submit</button>
      </form>
  );
}
// or any of your form created previously

Method two: email validation with React Hook Form library

React Hook Form is famous for its simple and highly preformative validation solutions. It allows you to add form validation to HTML input elements with bare minimum lines of code. 

Now, let’s see how it works. 

First, you need to install the library:

npm install react-hook-form

Second, get to understand the two basic functions crucial to the process of email validation:

useForm

This one is to call the hook, and it contains all the parameters you need to validate an email address.

register()

This one registers the field and all the validation options so that useForm could operate and run validation.

The entire code for email validation will with React Hook library look like this:

import React from 'react';
import { useForm } from 'react-hook-form';

export default function App() {
  const {
    register,
    handleSubmit,
    formState: { errors }
  } = useForm();
  const onSubmit = (values) => alert(JSON.stringify(values, null, 2));

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        type="text"
        placeholder="Email"
        {...register("email", { required: true, pattern: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i })}
      />
      {errors.email && <span>Invalid email</span>}

      <input type="submit" />
    </form>
  );
}

But let me give you a hint. The team behind React Hook library is one of the nicest in the world. Not only have they created the detailed documentation with examples, but also a form validation builder. So, all you need to do is go there, and grab your ready-made email validation code lines.

Method three: validate email format with the validator module 

Another way to verify whether email address input is valid or not is by using the validator module in your React app. It’s pretty straightforward. Just follow this example:

Install the validator module to your React app.

npm install validator

We won’t go into UI details here, so the email form will look as basic as it can be. 

In your App.js file write the following lines of code:

import React, { useState } from "react";
import validator from "validator";

export default function App() {
  const [message, setMessage] = useState("");
  const validateEmail = (e) => {
    const email = e.target.value;

    if (validator.isEmail(email)) {
      setMessage("Thank you");
    } else {
      setMessage("Please, enter valid Email!");
    }react
  };

  return (
    <div>
      <h2>Validating Email in ReactJS</h2>
      <label htmlFor="userEmail">Enter Email:</label>
      <input
        type="text"
        id="userEmail"
        onChange={(e) => validateEmail(e)}
      ></input>
      <br />
      <span
        style={{
          fontWeight: "bold",
          color: "red"
        }}
      >
        {message}
      </span>
    </div>
  );
}

Finally, run the app from the root directory with the npm start to see how it works.

Add CSS and go fancy with the UI/UX if you need it.

Method four: write your own code lines (because why not?)

Yes, we know there might be a thousand and one reasons why you need to manually validate email format with React.js. We’ll go for the one that is simple and written to speed up the process of validation. 

Let’s now see how it’s done.

import React, { useState } from "react";
 
const isEmail = (email) =>
  /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(email);
 
export default function App() {
  const [values, setValues] = useState({ email: "" });
  const [errors, setErrors] = useState({});
 
  const validateAndSubmitForm = (e) => {
    e.preventDefault();
 
    const errors = {};
 
    if (!isEmail(values.email)) {
      errors.email = "Wrong email";
    }
 
    setErrors(errors);
 
    if (!Object.keys(errors).length) {
      alert(JSON.stringify(values, null, 2));
    }
  };
 
  const setEmail = (e) => {
    setValues((values) => ({ ...values, email: e.target.value }));
  };
 
  return (
    <form onSubmit={validateAndSubmitForm}>
      <h2>Validating Email in ReactJS</h2>
      <span>Enter Email: </span>
      <input
        type="text"
        id="userEmail"
        value={values.email}
        onChange={setEmail}
      />{" "}
      <input type="submit" />
      <br />
      {Object.entries(errors).map(([key, error]) => (
        <span
          key={`${key}: ${error}`}
          style={{
            fontWeight: "bold",
            color: "red"
          }}
        >
          {key}: {error}
        </span>
      ))}
    </form>
  );
}

Instead of conclusion

There are numerous ways to validate email in React.js. In general, it is recommended to use libraries for complex forms containing email validation. Libraries are speedy solutions for standard but sophisticated validations. 

Write your own coding solution for email validation in React.js in the following cases: when the form is very simple (it saves time and ensures speedy download), and when the form requires flexibility or an extraordinary approach to email validation.

And remember to avoid confusion between email validation with email verification. 

Stay calm and React.js.

]]>
How to Validate Emails in Python: A Go-to Guide for Software Engineers https://mailtrap.io/blog/python-validate-email/ Tue, 08 Oct 2024 08:58:40 +0000 https://blog.mailtrap.io/?p=3027 In this tutorial, I break down the various approaches to Python email validation and show you how I typically go about it, code examples included.

P.S. I’ll also cover email verification by the end of the article, so, stick around or [jump ahead].

Ready to deliver your emails?
Try Mailtrap for Free

Validating emails with a regex

The most basic method I’ll show you is regex, or regular expressions. Python regex checks inserted email addresses for certain conditions and returns either a “valid” or “invalid” response.

To run basic regex checks, you can simply paste the following code snippet into your dedicated project file for validation (e.g., validate.py):

import re

mail1 = 'example@example.com'  # valid
mail2 = 'exa-mple@example.com'  # valid
mail3 = 'exa mple@example.com'  # not-valid (contains a space)
mail4 = 'example@example@example.com'  # not-valid (multiple @ symbols)
mail5 = 'example@examplecom'  # not-valid (missing '.' in domain part)

def validate(email):
    pattern = r'^[\w\.-]+@[a-zA-Z\d-]+\.[a-zA-Z]{2,}$'
    if re.match(pattern, email):
        print(f'{email} is correct')
    else:
        print(f'{email} is incorrect')

validate(mail1)
validate(mail2)
validate(mail3)
validate(mail4)
validate(mail5)

Explanation:

  • The mail1, mail2, etc., are email IDs I added so you can easily test whether your validation logic works.
  • The regex pattern in the validate function body is a string that represents an email and contains the criteria you want email addresses to meet.
  • The code checks addresses for basic email structure (e.g., correct formatting with one “@” and a valid domain).
  • We also use the re module for searching regex patterns and print for the valid/invalid messages.

Now, let me show you some examples of how you can play around with Python regex and adjust it according to your preferences. ⬇️

Example 1

The following regex checks if an email address is properly formatted and verifies if the top-level domain length is between two and four characters. You might want to raise the final number to a higher value to include top-level domains such as .travel, but that might also lead to some false positives.

^[\w.-]+@[\w.+-]+\.[a-zA-Z]{2,}

On the other hand, this script is not good for catching typos or fake email addresses such as !32d!3@dfsjn@dwef.com.

Example 2:

Let’s make it more sophisticated and assume we want the following criteria to be met for an account@domain email address:

  • Both the account and domain name include case-insensitive alphanumeric characters. Periods (.), dashes (-), and underscores (_) are also allowed.
  • Both must only start and end with alphanumeric characters. 
  • Neither the account nor domain may contain white spaces.
  • The account must have at least one character and the domain must have at least two.
  • The domain must include at least one period.
  • And of course, there must be an ‘@’ symbol separating the account and domain.
(^[A-Za-z0-9][A-Za-z0-9_.+-]+){1,}@[A-Za-z0-9_.-]+\.[A-Za-z]{2,}$

This is also a basic regex, and it will still capture some fake addresses. Although .com, .org, or .net domains need to be two or more characters long, many other top-level domains will allow just one character to be present. For example, Google’s Chinese domain, g.cn, would fail this test, but emails sent to big_brother@g.cn may just reach the target.

Above all, this regex completely ignores 99.9% of typos, making it ineffective as a standalone solution.

Example 3:

Since the other two examples did almost nothing about typos, you can also include another condition for popular email providers, such as Gmail:

import re
example = "example@gmial.com"
if re.search("@gm(ia|a|i)l.com$", example):
  print("Maybe you meant @gmail.com?")

If the domain name is gmial.com, gmal.com, or gmil.com (very likely indicating a Gmail account) then we can show a warning to the user. You can also expand this check for other popular email providers such as Yahoo and Outlook if you wish.

And, of course, to validate all possible typos, more sophisticated methods should be used, but listing the most common typos might just do the job.

Important: I must point out that however sophisticated regex you write, it will eventually fail for some legitimate email. You can read more about the possible trade-offs here. 🧐

Validating emails with Python libraries

A bit more advanced approach to Python email validation is to use libraries. I’ve had the most luck with the following two, and here’s how you can use them:

email-validator

email-validator is a Python library that not only focuses on the domain part of an email address, but also checks if it’s in an @x.com format. Moreover, it checks the basic email format, proper DNS records, internationalized domain names, and more.

As a bonus, the library also comes with a validation tool. It checks if the domain name can be resolved, thus giving you a good idea about its validity.

To install it, use the pip package installer and run the following command:

pip install email-validator

And here’s a code snippet you can use:

from email_validator import validate_email, EmailNotValidError

mail1 = 'example@example.com'  # valid
mail2 = 'exa-mple@example.com'  # valid
mail3 = 'exa mple@example.com'  # not-valid (contains a space)
mail4 = 'example@example@example.com'  # not-valid (multiple @ symbols)
mail5 = 'example@examplecom'  # not-valid (missing '.' in domain part)

def validate(email):
    try:
        email_info = validate_email(email)  # validate and get email info
        email = email_info.normalized  # validates the address and gives you its normalized form
        print(f'{email} is valid')  # print success message
    except EmailNotValidError as e:  # catch invalid emails
        print(f'{email} is not valid')  # print failure message
        print(str(e))  # print the specific error message

validate(mail1)
validate(mail2)
validate(mail3)
validate(mail4)
validate(mail5)

pyIsEmail

pylsEmail is another popular Python package that can be used to validate both a domain and an email address with just one call. If a given address can’t be validated, the script will inform you of the most likely reasons.

You can install it via pip with the following command:

$ pip install pyIsEmail

Then, simply copy the following code snippet into your validate.py file:

from pyisemail import is_email

mail1 = 'example@example.com'  # valid
mail2 = 'exa-mple@gmail.com'  # valid
mail3 = 'exa mple@gmail.com'  # not-valid
mail4 = 'example@example@example.com'  # not-valid
mail5 = 'example@gmail'  # not-valid

def validate(email):
    detailed_result = is_email(email, diagnose=True)
    print(detailed_result.description)

validate(mail1)
validate(mail2)
validate(mail3)
validate(mail4)
validate(mail5)

Validating emails with an external API

Finally, there are many APIs you can use with your Python app to validate email addresses. For your convenience, here’s a table comparing the features of the most popular ones:

Validation CheckMailValidation.ioMailboxlayerHunter.io APIZeroBounce API
Syntax 
MX Records
SMTP Server
Catch-All
Role-Based Email Detection
Typo Suggestions
Temporary Email Detection
Mailbox Full Detection
Spam Trap Detection
Blacklist Status
IP Address Validation

Pro tip: When choosing an API, I’d suggest you consider the level of email address validation your Python program needs, how easy to use it is, and whether it offers a solid price to feature ratio. Most importantly, ensure it’s being regularly updated and maintained, as you don’t want an outdated API.

If you’re wondering how any of these external APIs work, here’s a code snippet you can use to test the functionality of, for example, MailValidation.io:

import requests
from key import TEAM_SLUG, API_KEY

mail1 = 'example@gmail.com'  # not-valid
mail2 = 'test.mailtrap1234@gmail.com'  # valid

def validate(email):
    url = f"https://app.mailvalidation.io/a/{TEAM_SLUG}/validate/api/validate/"
    headers = {
        'content-type': 'application/json',
        'accept': 'application/json',
        'Authorization': 'Api-Key ' + API_KEY,
    }
    data = {'email': email}
    response = requests.post(
        url=url,
        headers=headers,
        json=data,
    )
    valid = response.json()['is_valid']
    if valid:
        print(f'{email} is correct')
    else:
        print(f'{email} is incorrect')

validate(mail1)
validate(mail2)

Keep in mind that you can also use MailValidation.io and the other APIs from the table to validate emails in bulk and emails from .txt, CSV, and other Excel file formats.

Bonus: email verification in Python

As you might have figured it out by now, email validation mostly focuses on making sure email addresses are entered correctly, without typos.

However, there’s also email verification, a process that goes a step further and not only scans for typos but also sends an activation link to the user’s email address, which they then have to activate. This way, you can actually make sure there’s someone behind the email address.

And here’s how I typically configure email verification in Python:

1. Setup your Python project

To verify emails in Python, you’ll first need to install the following libraries:

  • Flask – A lightweight Python web framework we’ll use for routing.
  • PyJWT – Library we’ll use to generate and validate JWT tokens.
pip install Flask PyJWT 

2. Generate tokens and send an email

Next, we’ll use the following code to generate an encoded token with expiration time exp and add email-sending functionality to our Python app via SMTP:

import smtplib
import jwt  # Correct import statement for PyJWT
from email.mime.text import MIMEText
from datetime import datetime, timedelta

# Configuration
port = 587
smtp_server = "smtp.mailtrap.io"  # Corrected SMTP
login = "your_mailtrap_username"  # Your login
password = "your_mailtrap_password"  # Your password
sender_email = "sender@example.com"
receiver_email = "newuser@example.com"

# Generate a JWT token for verification (valid for 30 minutes)
secret_key = 'your_secret_key'
token = jwt.encode(
    {"email": receiver_email, "exp": datetime.utcnow() + timedelta(minutes=30)},
    secret_key,
    algorithm="HS256"
)

# Email content with token embedded in verification URL
verification_link = f"http://localhost:5000/verify/{token}"
text = f"""\
Hi,

Please verify your email address exists by clicking on the link below:
{verification_link}

This link will expire in 30 minutes.
"""

# Create MIMEText object
message = MIMEText(text, "plain")
message["Subject"] = "Email Verification"
message["From"] = sender_email
message["To"] = receiver_email

# Send the email
with smtplib.SMTP(smtp_server, port) as server:
    server.starttls()  # Secure the connection
    server.login(login, password)
    server.sendmail(sender_email, receiver_email, message.as_string())

print('Email sent with verification token')

Tip: I typically add this code in a sendmail.py file I create for email-sending functionality.

3. Create a route to verify the token 

Then, we need to leverage Flask to create a route and verify the token. For this, copy the following code snippet into your main application file (e.g., app.py):

from flask import Flask, jsonify, request
import jwt

app = Flask(__name__)
secret_key = 'your_secret_key'

# Route to verify the token
@app.route('/verify/<token>', methods=['GET'])
def verify_token(token):
    try:
        # Decode the token
        decoded_token = jwt.decode(token, secret_key, algorithms=["HS256"])
        email = decoded_token["email"]
        return jsonify({"message": f"Email {email} has been successfully verified!"}), 200
    except jwt.ExpiredSignatureError:
        return jsonify({"error": "Verification link has expired."}), 400
    except jwt.InvalidTokenError:
        return jsonify({"error": "Invalid token."}), 400

if __name__ == "__main__":
    app.run(debug=True)

Next, run python sendmail.py (the first script) to send verification email to your email address. Once you click the link, the request will be handled by the flask server which you’ve just built.

And finally, try running your server and running python app.py to send yourself a test email. If everything’s working as intended, you should get an email message with a link you can click on to make a request on the server.

Email validation & verification in email testing

Confirming the correctness of an email address (validation) and the existence of a user behind it (verification) are just two of many aspects of an effective email testing strategy. 

Email testing is an industry-standard practice that ensures your sending code works flawlessly and that your emails successfully avoid spam filters, landing where they’re supposed to → recipients’ inboxes.

Consider it like car service before going on a road trip: adding a new exhaust or summer tires is cool, but without inspecting your vehicle beforehand, you don’t know where you’ll end up. 🚨

That’s why I always recommend using Mailtrap Email Testing, which lets you catch traffic from staging and dev environments and analyze the HTML/CSS of your emails. This way, you can remove or fix any faulty lines of code and ensure your messages are flawless before they reach your recipients.

What’s more, with the Spam Analysis feature, you get to see how likely your emails are to pass through spam filters. And by keeping the spam score under 5, you proactively boost your email deliverability

Lastly, besides offering a plethora of advanced features, Mailtrap Email Testing is super easy to use. You can learn how to test emails in Python by reading our step-by-step guide. Or, better yet if you’re a visual learner, follow along with the video we prepared for you! 👀

Further reading on email validation:

]]>
How to Validate Emails in PHP: regex, filter_var(), and API Explained https://mailtrap.io/blog/php-email-validation/ Mon, 13 May 2024 12:04:35 +0000 https://mailtrap.io/?p=29631 Be it marketing or transactional emails, email address validation is a necessity, or you could risk the reputation of your email domain. 

This tutorial covers the ins and outs of PHP email validation and is primarily designed for beginners. However, I assume you already got the basics of PHP programming skills. 

Also, I’d like to stress the difference between email validation and verification. Validation is about the correct formatting of an email address, and it’s a part of verification. It can be done on the server and the client side and I’ll focus on the server side here (no JavaScript, HTML, etc). 

So, let’s get to coding.  

Note: The exemplary scripts are based on PHP 8.3.6, and may not work on PHP 7.x.y versions. 

Ready to deliver your emails?
Try Mailtrap for Free

PHP email validation function: filter_var()

The filter_var() function is part of PHP’s filter extension, which provides a convenient way to perform validation and sanitization of various data types using a single function call. 

For email validation, filter_var() offers a straightforward, reliable method to quickly assess whether an email address is valid according to PHP standards. For instance, you could integrate it with email form validation on your website. 

Here, I won’t cover the frontend stuff, input fields, and all. I already created an extensive PHP form validation guide, so feel free to check it out. 

Anyway, the FILTER_SANITIZE_EMAIL (as part of ‘filter_var’ function) is engineered to remove characters not permitted in email addresses. This includes, but is not limited to: 

  • Spaces, 
  • Commas 
  • Certain special characters (/, |, #, etc.) 

The primary purpose of sanitizing email inputs is to ensure that the data is clean and safe to be processed or stored. This is important when the data gets displayed on a web page, or is included in database queries. The reason is that it helps prevent XSS (Cross-Site Scripting) and SQL injection attacks.

Here’s a practical example of how to sanitize an email input using filter_var():

<?php
// Example email input
$userInputEmail = "john.doe@example.com<script>alert('XSS');</script>";

// Sanitize the email input
$sanitizedEmail = filter_var($userInputEmail, FILTER_SANITIZE_EMAIL);

echo "Original: " . $userInputEmail . "<br>";
echo "Sanitized: " . $sanitizedEmail;
?>

In this example, the script tag would be removed from the email input, displaying the sanitized version as john.doe@example.com. It shows how FILTER_SANITIZE_EMAIL strips unwanted and potentially harmful characters from email inputs. 

Following this, you would typically validate the sanitized email to ensure it meets the format standards for a valid email address, which I’ll discuss next using FILTER_VALIDATE_EMAIL.

Validating emails with FILTER_VALIDATE_EMAIL

The FILTER_VALIDATE_EMAIL checks whether the given string conforms to the format of a valid email address. It ensures the email address includes a valid username, an @ symbol, and a valid domain name with a domain extension.

Simply, FILTER_VALIDATE_EMAIL enforces proper email format standards. And here’s what the standards typically include:

  • A username – can contain letters, numbers, dots, hyphens, and underscores.
  • An @ symbol as a separator.
  • A domain name that includes letters and may contain dots or hyphens.
  • A domain extension, which must be at least two characters long and primarily contain letters.

While very effective for basic validation, the filter has some limitations:

  • Unicode characters: It does not support email addresses with international characters outside of the basic Latin alphabet.
  • Advanced formats: Certain valid email formats as per the Internet standards (RFC standards) may not be recognized by this filter, such as emails with quoted strings or certain special characters.

The limitations indicate that FILTER_VALIDATE_EMAIL may not suffice for applications requiring robust internationalization or adherence to the latest email address standards.

But no worries, I’ll tell you how to overcome that under the Email validation in PHP using API section. Here’s a practical example of how to use the filter for basic validation. 

<?php
// Example email input
$userInputEmail = "john.doe@example.com";

// Validate the email input
if (filter_var($userInputEmail, FILTER_VALIDATE_EMAIL)) {
    echo "The email address '$userInputEmail' is considered valid.";
} else {
    echo "The email address '$userInputEmail' is considered invalid.";
}
?>

To wrap up, I’d like to give you some tips on how to handle verification failures without annoying your users. 

  • User feedback: Just an “Invalid email address” message won’t suffice. Provide clear and constructive feedback to users, helping them understand why their email was invalid and what they can do to correct it.
  • Logging: Keep logs of failed validation attempts for debugging purposes or to identify potential misuse of the system. 
  • Alternative validation: Consider alternative methods of validation for special cases, such as allowing list-specific addresses or domain-specific addresses

Regular expression for email validation in PHP

Regular expressions (regex) offer a flexible method for validating email addresses in a PHP function. 

For instance, this approach works nicely in scenarios where you might need to validate emails based on specific criteria that are not covered by FILTER_VALIDATE_EMAIL, such as:

  • Restricting email addresses to certain domains.
  • Enforcing specific prefixes or suffixes in the email username.
  • Allowing newer top-level domains (TLDs) or internationalized domain names.

Also, regex can be used to implement complex pattern-matching rules necessary for applications requiring precise control over the user input.

Now, I’ll show you how to create and integrate a regex. But before that, I’d have to touch upon the components of an email address as defined by the RFC 5322 standard. It helps wrap your mind around pattern-matching syntax for email validation use cases. 

  • Local part: The local part of the email (before the @ symbol) may include a variety of characters (a-z, A-Z, 0-9) including special characters such as . (dot), – (hyphen), and _ (underscore). It can also contain quoted strings allowing almost any character within the quotes.
  • Domain part: The domain part (after the @ symbol) typically includes alphanumeric characters and may include hyphens and dots. The domain must not start or end with a hyphen.

Here’s an example of a pattern that matches the given standards. 

<?php
$email = "test@example.com";
$pattern = '/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/';

if (preg_match($pattern, $email)) {
    echo "The email address '$email' is considered valid.";
} else {
    echo "The email address '$email' is considered invalid.";
}
?>

The regex matches the following:

  • One or more characters in the local part, including alphanumeric characters and special characters (._%+-).
  • An @ symbol, separating the local and domain parts.
  • A domain part consisting of one or more alphanumeric characters, potentially including dots and hyphens.
  • A top-level domain (TLD) that must be at least two characters long.

So far so good, but if you need a more custom thing, here are a couple of suggestions on how to tweak the function filters. 

  1. Tighten the criteria: Restrict the email to specific domains or subdomains by replacing the domain part of the pattern with a literal string (e.g., example.com).
// Example for tightened criteria: Only allowing emails from specific domains
$pattern = '/^[a-zA-Z0-9._%+-]+@(example\.com|example\.net)$/';
  1. Relax the criteria: Allow additional characters in the local part or more variations in the TLD.
// Example for a relaxed criteria: Allowing international characters in the local part
$pattern = '/^[a-zA-Z0-9._%+-\p{L}]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/u';

Even though regexes provide significant control over input validation, it’s vital to test thoroughly (I’ll cover that in a second) to ensure that the pattern meets all functional requirements. The goal is to avoid excluding valid emails or including invalid ones inadvertently.

This is how you might approach testing a regex pattern for email validation:

<?php
$emails = [
    "test@example.com", // Valid
    "test.example@com", // Invalid: no top-level domain
    "test_example.com", // Invalid: missing '@'
    "test@example.com.", // Invalid: dot at the end of the domain
    "ñandu@dominio.com" // Valid if Unicode is considered
];

$pattern = '/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/';

foreach ($emails as $email) {
    if (preg_match($pattern, $email)) {
        echo "The email address '$email' is valid.\n";
    } else {
        echo "The email address '$email' is invalid.\n";
    }
}
?>

Also, you should consider debugging, check the tips to follow:

  • Use online regex testers: Tools like Regex101 or RegExr can help visualize how your regex matches against test strings, providing explanations and highlighting potential issues.
  • Log troublesome inputs: When a user input fails validation, log the input for review. This can help identify what the regex may be failing to catch.
  • Unit testing: Implement unit tests to automatically check the regex against known valid and invalid emails.

As regexes can be a blessing and a curse, I’ll finish this section with some best practices and common mishaps. 

Best Practices:

  • Keep it readable: While regex can be compact, overly complex patterns can become unreadable and difficult to maintain. Use comments and break complex patterns into smaller parts if necessary.
  • Use non-capturing groups: Unless you need to capture parts of the email for later use in the code, use non-capturing groups(?: ... ) to avoid unnecessary performance overhead.
  • Specify character ranges explicitly: Avoid using broad classes like ‘.\*’ when validating emails. Instead, encode exactly which characters are allowed in each part of the email.
  • Use anchors: Always use ^ (start of string) and $ (end of string) anchors to ensure that the entire string matches the pattern, preventing partial matches.

Common Mishaps:

  • Escaping characters: Failing to escape special regex characters like ., ?, and + can lead to unintended matches.
  • Performance issues: Regex that uses excessive backtracking (e.g., nested quantifiers like (a+)+) can cause performance issues.
  • Unicode ignorance: If international characters are a requirement, forgetting to handle Unicode properly can exclude valid emails with international characters.

Email validation in PHP using API

APIs offer advanced capabilities beyond what local methods can provide, and here’s what they are. 

  1. Enhanced accuracy: APIs often use sophisticated algorithms with a real-time data lookup that goes beyond simple format validation. They can check if an email address is correctly formatted and verify it (confirm the address exists and can receive emails).
  1. Reduce local resource usage: Offloading the validation process to an external service can reduce the load on your local systems, which is beneficial for applications with high volumes of email processing.
  1. Access to additional data: Some APIs also offer information like whether the email is a disposable address, its risk score for being spam, or its general reputation.

For this tutorial, I’ll discuss a generic approach to integrating an email validation API. While specific details can vary between providers, the general principles of making a request and handling a response are similar across most services.

I assume that you already chose an email validation API provider and obtained their API credentials. So, here’s how to implement the request. 

<?php
$email = "test@example.com";
$apiKey = "YOUR_API_KEY";
$apiUrl = "https://api.emailvalidator.com/validate?apiKey={$apiKey}&email={$email}";

$response = file_get_contents($apiUrl);
if ($response !== false) {
    $data = json_decode($response, true);
    print_r($data);
} else {
    echo "API request failed.";
}
?>

In this scenario, it’s also important to handle API responses properly and manage errors. The responses usually come in JSON format containing various fields indicating the validation results. You need to parse these responses and react accordingly in your application logic.

As for managing errors, you should cover network issues, invalid API keys, or exceeded rate limits. Use try-catch blocks or check for errors in the response to ensure robustness. Here’s an example. 

<?php
try {
    $response = file_get_contents($apiUrl);
    if ($response === false) {
        throw new Exception("API request failed.");
    }
    $data = json_decode($response, true);
    if (isset($data['error'])) {
        throw new Exception("Error from API: " . $data['error']);
    }
    print_r($data);
} catch (Exception $e) {
    echo "An error occurred: " . $e->getMessage();
}
?>

Email validation as part of email testing

I won’t beat around the bush, here are four main reasons to validate addresses when testing emails. 

  1. Deliverability, deliverability, and always deliverability

By verifying that an email address is formatted correctly and is valid, you reduce the risk of sending emails to non-existent addresses, which can hurt your sender’s reputation and impact deliverability.

  1. Spam compliance 

Sending emails to invalid addresses frequently leads to higher bounce rates, which are monitored by Internet Service Providers (ISPs). Consequently, it can lead to blacklisting of your sending IP address. By ensuring that email addresses are valid, you avoid penalties associated with violating spam laws (CAN-SPAM and GDPR).

  1. Improved quality of user data

Regular email validation as part of email testing helps maintain high-quality user data. Clean, validated email lists improve the effectiveness of email marketing campaigns and reduce the cost associated with managing undeliverable emails.

  1. Automation

Automating email validation processes can significantly enhance the efficiency and reliability of your email testing strategies. Automation ensures that email validation checks are performed consistently, without manual intervention, making the processes scalable and error-resistant.

Of course, there are specific tools and techniques to automate email tests. First, I’ll cover Mailtrap Email Testing, part of Mailtrap Email Delivery Platform. Then, I’ll talk about dedicated validation services, custom scripts, and cron jobs.  

Mailtrap Email Testing is an email sandbox to inspect and debug emails in staging, dev, and QA environments before sending them to recipients. 

I need to stress that the sandbox doesn’t include email validation. However, you can run a custom validation script and a cron job in parallel with Mailtrap Email Testing. Or you could check the addresses just before sending the emails on production. 

This is particularly useful if you use Mailtrap Testing API, which allows you to easily test templates and automate QA processes. Then, you can switch from sandbox to production environment and keep sending to valid addresses. 

Aside from a reliable REST API, and a fake SMTP server, you also get the following:

  • HTML/CSS check
  • Spam score check
  • API for QA automation
  • Ready-to-use integrations in 20+ languages (Ruby, Python, PHP, Node.js, .Net, etc.)
  • Emails preview
  • Multiple inboxes for different projects and stages
  • User management, SSO

Lastly, the whole setup is straightforward, you just need to do the following: 

  1. Sign up for Mailtrap
  2. Go to Email Testing > Inboxes > My Inbox  
  3. Choose your preferred integration or copy-paste SMTP credentials to your project
  4. Run the code and get the test email in an instant
Mailtrap email tesing HTML preview

Now, here’s a custom PHP email validation script that can be run as a cron job to validate email addresses with a third-party API:

<?php
function validateEmail($email) {
    $apiKey = 'YOUR_API_KEY';
    $apiUrl = "https://api.emailvalidator.com/validate?apiKey={$apiKey}&email={$email}";

    $response = file_get_contents($apiUrl);
    if ($response !== false) {
        $data = json_decode($response, true);
        return $data['isValid'];
    }
    return false;
}

// Example email to validate
$email = 'test@example.com';
if (validateEmail($email)) {
    echo "Email is valid.\n";
} else {
    echo "Email is invalid.\n";
}
?>

Also, here’s how to automate the whole thing with a cron job on a Linux server. 

0 1 * * * /usr/bin/php /path/to/your/script.php

The job runs the script once a day at 1:00 AM. 

Now, your task is to set up all the automation, sit back and relax knowing your domain and IP reputations are safe. 

Want to learn more about validation? Check out our YouTube channel featuring videos such as:

 

]]>