# Bulk Email Address Validation in Node.js
* * *
**Tags**
[ Code, tutorials, and best practices ](https://www.twilio.com/en-us/blog/tag.topic%253Acode%252C-tutorials%252C-and-best-practices) [ JavaScript ](https://www.twilio.com/en-us/blog/tag.tech-stack%253Ajavascript) [ Node.js ](https://www.twilio.com/en-us/blog/tag.tech-stack%253Anode-js)
**Products**
[ Twilio SendGrid Email API logo Email API ](https://www.twilio.com/en-us/products/email-api)
* * *
[ Start for free  ](https://www.twilio.com/try-twilio)
Time to read: 6 minutes
  * [ Facebook logo ](https://www.facebook.com/sharer/sharer.php?u=https://www.twilio.com/en-us/blog/developers/tutorials/building-blocks/bulk-email-address-validation-node-js "Share via Facebook")
  * [ Twitter Logo Follow us on Twitter ](https://twitter.com/intent/tweet?url=https://www.twilio.com/en-us/blog/developers/tutorials/building-blocks/bulk-email-address-validation-node-js "Share via X")
  * [ LinkedIn logo ](https://www.linkedin.com/sharing/share-offsite/?url=https://www.twilio.com/en-us/blog/developers/tutorials/building-blocks/bulk-email-address-validation-node-js "Share via LinkedIn")
  *   * [ ](https://www.twilio.com/blog.feed.xml "Twilio RSS")


May 07, 2024 
**Written by**
[ Yukti Ahuja ](https://www.twilio.com/en-us/blog/authors/author.yahuja)
Twilion 
**Reviewed by**
[ Chris Kemnitzer ](https://www.twilio.com/en-us/blog/authors/author.ckemnitzer)
Twilion 
[ Jesse Sumrak ](https://www.twilio.com/en-us/blog/authors/author.jsumrak)
Twilion 
[ Shanelle Thadani ](https://www.twilio.com/en-us/blog/authors/author.sthadani)
Twilion 
* * *
[Bulk Email Address Validation in Node.js](https://www.twilio.com/en-us/blog/developers/tutorials/building-blocks/bulk-email-address-validation-node-js#introduction)
Email address validation helps identify email addresses in your marketing lists and customer base that are likely to produce a hard bounce and impact your sender score. The validation algorithm runs numerous checks to determine if an address is legitimate, such as if a domain is set up to receive email, if it’s disposable, if the name was likely button mashed, and more.  

Email address validation is one meaningful component of building strong email sending practices and reaching your customers. This blog post will provide an in depth tutorial of how to integrate with [Twilio SendGrid’s Bulk Email Address Validation](https://sendgrid.com/en-us/blog/bulk-email-address-validation?utm_referrer=https%3A%2F%2Fwww.twilio.com%2Fen-us%2Fblog%2Fdevelopers%2Ftutorials%2Fbuilding-blocks%2Fbulk-email-address-validation-node-js) using Node.js.
For more information on how to integrate, check out the [Email Address Validation documentation](https://docs.sendgrid.com/ui/managing-contacts/email-address-validation).
## [Real Time Validation vs Bulk Email Address Validation](https://www.twilio.com/en-us/blog/developers/tutorials/building-blocks/bulk-email-address-validation-node-js#real-time-validation-vs-bulk-email-address-validation)
When it comes to validating email addresses, there are two main approaches: _real time validation_ and _Bulk Email Address Validation_. Real time validation has been around for a while, and involves validating email addresses one by one. This method is best suited for scenarios where only a few email addresses need to be validated or when validation needs to be seamlessly integrated into a user-facing application, like during the sign-up process on a website
Bulk email address validation is a crucial process for businesses and organizations engaged in email marketing that need more confidence within large subscriber lists or customer databases. This method is particularly useful for managing extensive amounts of data, and SendGrid’s implementation enables the validation of up to a million email addresses in one go. By ensuring the accuracy and deliverability of email lists before launching campaigns, Bulk Email Address Validation helps maintain good email deliverability and ensures that messages reach real, active recipients.
## [How do I get access?](https://www.twilio.com/en-us/blog/developers/tutorials/building-blocks/bulk-email-address-validation-node-js#how-do-i-get-access)
Bulk Email Address Validation is exclusively accessible to [Email API Pro and Premier le](https://sendgrid.com/en-us/pricing?utm_referrer=https%3A%2F%2Fwww.twilio.com%2Fen-us%2Fblog%2Fdevelopers%2Ftutorials%2Fbuilding-blocks%2Fbulk-email-address-validation-node-js)[vel accounts](https://sendgrid.com/en-us/pricing?utm_referrer=https%3A%2F%2Fwww.twilio.com%2Fen-us%2Fblog%2Fdevelopers%2Ftutorials%2Fbuilding-blocks%2Fbulk-email-address-validation-node-js). Until your account is upgraded to Pro or Premier, the option to generate an email address validation API key will not be visible. The email address validation API key is distinct from your other keys, and is essential for both asynchronous bulk email address validations and real-time email address validations. Employing this Bulk Email Address Validation feature aids in purifying your current database; however, SendGrid advises verifying email addresses upon their entry into your customer funnel.
You can use this API to:
  * Validate a CSV of email addresses asynchronously in a single job
  * The CSV can contain up to 1M emails or 50MB of data


Results are sent to the email address linked with the SendGrid account.
## [Prerequisites](https://www.twilio.com/en-us/blog/developers/tutorials/building-blocks/bulk-email-address-validation-node-js#prerequisites)
  * Twilio SendGrid Pro or Premier Account. If you don’t yet have one, you can [sign up for an account here](https://signup.sendgrid.com/).
  * [Node.js](https://nodejs.org/) installed on your computer.
  * email address validation API Key. If you do not have one, please create one using the [email address validation API Key Creation Guide](https://docs.sendgrid.com/ui/managing-contacts/email-address-validation/bulk-email-address-validation-overview). Here is a view of my API Keys page in my SendGrid console:


![API keys setup in sendgrid](https://www.twilio.com/content/dam/twilio-com/global/en/blog/importer-images/a-c/bulk-email-address-validation-node-js/media0/_jcr_content/renditions/compressed-original.webp)
![](https://www.twilio.com/content/dam/twilio-com/global/en/blog/importer-images/a-c/bulk-email-address-validation-node-js/media0/_jcr_content/renditions/compressed-original.webp)
## [Let’s get started](https://www.twilio.com/en-us/blog/developers/tutorials/building-blocks/bulk-email-address-validation-node-js#lets-get-started)
Here are the basic steps of our build today:
  * Upload a CSV
  * Get job status list
  * Get job status


### [Upload a CSV](https://www.twilio.com/en-us/blog/developers/tutorials/building-blocks/bulk-email-address-validation-node-js#upload-a-csv)
#### Set Environment Variables
Create an `.env` file to store your environment variables `SENDGRID_API_KEY` in the following format. Further details about your node environment variables can be found [here](https://sendgrid.com/en-us/blog/node-environment-variables?utm_referrer=https%3A%2F%2Fwww.twilio.com%2Fen-us%2Fblog%2Fdevelopers%2Ftutorials%2Fbuilding-blocks%2Fbulk-email-address-validation-node-js). It is advisable not to include this file in version control.
Copy code
```
SENDGRID_API_KEY=<"YOUR_SENDGRID_EMAIL_VALIDATION_KEY">
```

#### Request the presigned URL and headers
The bulk email address validation process takes place asynchronously. This endpoint returns a URL (`upload_uri`) and HTTP headers (`upload_headers`) which can subsequently be used to PUT a file of email addresses to be validated.
Uploaded CSV files can be in the following formats: `.csv` or `.zip`.
You must include the field `file_type` with the value `csv` or `zip` in your request body.
You can find the code repository here: <https://github.com/yuktiahuja-twilio/EmailBulkValidationApi.git>
**Example Node.js code**
Copy code
```
const client = require('@sendgrid/client');
require('dotenv').config();
client.setApiKey(process.env.SENDGRID_API_KEY);


const data = {
	"file_type": "csv"
};

const request = {
  url: `/v3/validations/email/jobs`,
  method: 'PUT',
  body: data
}

client.request(request)
  .then(([response, body]) => {
    console.log(response.statusCode);
    console.log(response.body);
  })
  .catch(error => {
    console.error(error);
  });
```

**Example code output**
The output of this script will return `job_id`, `upload_uri`, and `upload_headers`.
![Please make a note of the output from this script, which will include `job_id`, `upload_uri`, and `upload_headers`.](https://www.twilio.com/content/dam/twilio-com/global/en/blog/importer-images/a-c/bulk-email-address-validation-node-js/media1/_jcr_content/renditions/compressed-original.webp)
![](https://www.twilio.com/content/dam/twilio-com/global/en/blog/importer-images/a-c/bulk-email-address-validation-node-js/media1/_jcr_content/renditions/compressed-original.webp)
#### Make a second API call
Once you receive the response body you can then initiate a second API call where you use the supplied URL and HTTP header to upload your file.
_File Format_
The uploaded file must be saved either as a CSV or ZIP, ensuring alignment with both the file type specified in the initial request and the expected headers in the response containing the URL. The file should have the header "emails" and exclusively contain the email addresses intended for validation.
For csv file sizes please refer [here](https://docs.sendgrid.com/ui/managing-contacts/email-address-validation/bulk-email-address-validation-overview#step-1-prepare-your-csv-file).
_Example CSV Contents_
Copy code
```
emails
yahuja@twilio.com
sendgriddemo1@gmail.com
test@exampledomain.com
test2@exampledomain.com
eofjeh@mail.con
differentTest@differentexampledomain.com
lastEmail@lastexampledomain.net
AaBbCcDd@gmail.con
ajsiof@gmail.com
```

**Example Node.js code**
Copy code
```
const axios = require('axios');
const fs = require('fs');

// Replace these with your actual values

const filePath = '/Users/yahuja/Demo/sgEmailValidation/spreadsheet/emailvalidation.csv'; // The path to the file you want to upload
const uploadUri = 'https://evbulkupload-prod-us-east-2-emails-csv.s3.us-east-2.amazonaws.com/25810133_01HNPW0EA2XWEH0C0TZ6ARYRZD?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIAS4765TJFFO7HTIDY%2F20240203%2Fus-east-2%2Fs3%2Faws4_request&X-Amz-Date=20240203T065530Z&X-Amz-Expires=3600&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEKf%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMiJIMEYCIQDNXDJaL3Tta8VgH1X6vU%2FkNTjHFdC1M5mBox2Lc%2BkJFAIhALAhfKW4X2cfaVRXSM9T3NXr4KsxmTz3J%2FGhnqEUWRRLKosDCHAQBBoMMTk5NzEzNzI1MDAyIgxpw6miFKHjiWtMO5Qq6AKLuccBukE8Oec89Hyv6XWhgMA3VkbxA%2FGoB6WmG38fp%2BN5%2Blf2%2BP7sYn0P7jGd3S3GEbwP%2FKa2p4jVKrGw802Nvo%2BlXSlmaFlsl9t2I3Dzsh%2F63wcmc%2FrpZO6PB6bZbNsuvNrjS9s3Mp0Sj7d0v6pv7C4CSxZvS8Z56I%2BbdV7KVz5DQnSw%2Fn4%2BpIZ0xi62HFry4yGzhfoUBqedpdm5mRTeCJmqLFX0wJQRlrpEMdu3%2FaasPOOSd6E6dUYDDcKdWuGOLveTcxzqfIEvM84kp1uv2lM%2BL0ZpqY1CMpGaldjrITLaIE9PjtL7Au%2BxJR5f%2FYrG2nqmseR4LGLewOLykFoc2s7xPO1LrWbOoXav6nfzJHZMgff4Vw6QRr6auCikPDpupLzojD%2BdXsLFycPga70SuISrsT05GM8wOpYXqciacCrBUvhAmxmARzETFQOUEq6kQcKXCWhdzlCsim2FT3UcxTy%2BxRLyaVUw7cX3rQY6nAE1UydxDZ96d3oSwG%2BXBmC0jSiJkvzQkiMx0CL00NMhd%2BeISnevMT%2BCwCt5NQ9g6th6Kj97KuaO9xLHjsiwChViTZjvMasmI769jDgSErxYjz9jhAU4PWRIx1IQVexKUvD17O%2FMT7Bn%2FkRGuZxFgwdcpHlYoBU%2BWe15RYTMrlvpN8IbgKOxMMuxcDVdAtrJU%2FsGxtvbhn3A3TQtghE%3D&X-Amz-SignedHeaders=content-type%3Bhost%3Bx-amz-server-side-encryption&X-Amz-Signature=d7228a5b141f4fb2694fa63d4af93f7269f815dca78a5e0f6810c3136fbdc720'; // The URI you received from the previous request

const fileSize = fs.statSync(filePath).size;

const uploadFile = async (filePath, uploadUri) => {
  try {
    const fileStream = fs.createReadStream(filePath);

    const response = await axios.put(uploadUri, fileStream, {
      headers: {
        'x-amz-server-side-encryption': 'aws:kms',
        'content-type': 'text/csv',
        'Content-Length': fileSize
      },
    });

    console.log('File uploaded successfully', response.data);
  } catch (error) {
    console.error('Error uploading file', error.response ? error.response.data : error.message);
  }
};
uploadFile(filePath, uploadUri);
```

**Example code output**
The upload is successful! 
![The csv file is uploaded successfully. ](https://www.twilio.com/content/dam/twilio-com/global/en/blog/importer-images/a-c/bulk-email-address-validation-node-js/media2/_jcr_content/renditions/compressed-original.webp)
![](https://www.twilio.com/content/dam/twilio-com/global/en/blog/importer-images/a-c/bulk-email-address-validation-node-js/media2/_jcr_content/renditions/compressed-original.webp)
### [Get Job Status List](https://www.twilio.com/en-us/blog/developers/tutorials/building-blocks/bulk-email-address-validation-node-js#get-job-status-list)
This endpoint retrieves information on all bulk email address validation operations associated with a user.
**Example Node.js code**
Copy code
```
const client = require('@sendgrid/client');
require('dotenv').config();
client.setApiKey(process.env.SENDGRID_API_KEY);

const request = {
  url: `/v3/validations/email/jobs`,
  method: 'GET'
}

client.request(request)
  .then(([response, body]) => {
    console.log(response.statusCode);
    console.log(response.body);
  })
  .catch(error => {
    console.error(error);
  });
```

**Example code output**
![All the bulk email validation endpoints for the user. Please take note of the id and the status parameter.](https://www.twilio.com/content/dam/twilio-com/global/en/blog/importer-images/a-c/bulk-email-address-validation-node-js/media3/_jcr_content/renditions/compressed-original.webp)
![](https://www.twilio.com/content/dam/twilio-com/global/en/blog/importer-images/a-c/bulk-email-address-validation-node-js/media3/_jcr_content/renditions/compressed-original.webp)
### [Get Job Status](https://www.twilio.com/en-us/blog/developers/tutorials/building-blocks/bulk-email-address-validation-node-js#get-job-status)
This endpoint gives you all the details about a specific bulk email address validation job. Take note of the `id` parameter mentioned earlier and substitute it in the following code snippet.
**Example Node.js Code**
****
Copy code
```
const client = require('@sendgrid/client');
require('dotenv').config();
client.setApiKey(process.env.SENDGRID_API_KEY);

const request = {
  url: `/v3/validations/email/jobs/01HN16FEFV9SDQQ2AYVX65VPKX`, //replace the job_id here
  method: 'GET'
}

client.request(request)
  .then(([response, body]) => {
    console.log(response.statusCode);
    console.log(response.body);
  })
  .catch(error => {
    console.error(error);
  });
```

**Example code output**
![Successful result of bulk validation api call via node.js](https://www.twilio.com/content/dam/twilio-com/global/en/blog/importer-images/a-c/bulk-email-address-validation-node-js/media4/_jcr_content/renditions/compressed-original.webp)
![](https://www.twilio.com/content/dam/twilio-com/global/en/blog/importer-images/a-c/bulk-email-address-validation-node-js/media4/_jcr_content/renditions/compressed-original.webp)
## [Final Results](https://www.twilio.com/en-us/blog/developers/tutorials/building-blocks/bulk-email-address-validation-node-js#final-results)
Once the job is finished, you'll receive an email in your inbox with a link to download the output CSV. If there's an error during the job processing, you'll also get an email notification in your inbox.
![Snapshot of the email from SendGrid when the email validation export is ready](https://www.twilio.com/content/dam/twilio-com/global/en/blog/importer-images/a-c/bulk-email-address-validation-node-js/media5/_jcr_content/renditions/compressed-original.webp)
![](https://www.twilio.com/content/dam/twilio-com/global/en/blog/importer-images/a-c/bulk-email-address-validation-node-js/media5/_jcr_content/renditions/compressed-original.webp)
When you click the **Download** option, the file opens in your SendGrid portal and should initiate an automatic download. 
![Download the export of bulk email address validation results ](https://www.twilio.com/content/dam/twilio-com/global/en/blog/importer-images/a-c/bulk-email-address-validation-node-js/media6/_jcr_content/renditions/compressed-original.webp)
![](https://www.twilio.com/content/dam/twilio-com/global/en/blog/importer-images/a-c/bulk-email-address-validation-node-js/media6/_jcr_content/renditions/compressed-original.webp)
Here is a sample output for my csv: 
![CSV output example](https://www.twilio.com/content/dam/twilio-com/global/en/blog/importer-images/a-c/bulk-email-address-validation-node-js/media7/_jcr_content/renditions/compressed-original.webp)
![](https://www.twilio.com/content/dam/twilio-com/global/en/blog/importer-images/a-c/bulk-email-address-validation-node-js/media7/_jcr_content/renditions/compressed-original.webp)
You can use a mix of these fields to refine your search for what you consider a valid address. Verdict section provides one of three classifications: "Valid," "Risky," or "Invalid." These categories are based on the detailed results. Score is the value ranging from 0 to 1, indicating the probability that the email address is valid, expressed as a percentage. For example, a score of 0.94 could be interpreted as a 94% likelihood that the email is valid.
The API returns a verdict of VALID, RISKY, or INVALID. The score is also returned to provide more fine grain details. A score of 0 maps to INVALID. A score > 0 but < 0.66 maps to RISKY. A score >= 0.66 maps to VALID.
Additional details on interpreting the results can be found [here](https://docs.sendgrid.com/ui/managing-contacts/email-address-validation/bulk-email-address-validation-overview).
## [Conclusion](https://www.twilio.com/en-us/blog/developers/tutorials/building-blocks/bulk-email-address-validation-node-js#conclusion)
Conducting an email address validation check is a proactive measure that positively impacts your long-term email marketing efforts. This not only reduces the risk of emails bouncing but also plays a crucial role in building a positive sender reputation, ultimately boosting the success of your email campaigns. For more information on Single vs Bulk Email Address Validation API please visit the technical documentation [here](https://docs.sendgrid.com/ui/managing-contacts/email-address-validation) .
_Now that you have the capability to programmatically utilize the Bulk email address validation API, I'm excited to see what you build! Don't hesitate to reach out to sendgrid support to share your experiences, or ask any questions_ _._
##  Related Posts 
  * [ ![](https://www.twilio.com/content/dam/twilio-com/global/en/blog/insights/card-images/card-insights-guy-in-a-phone-call-4-1.png/_jcr_content/renditions/compressed-800.webp) Customer lifetime value: formula, calculation & examples Jesse Sumrak  ](https://www.twilio.com/en-us/blog/insights/customer-lifetime-value-clv)
  * [ ![](https://www.twilio.com/content/dam/twilio-com/global/en/blog/developers/developers-imagery-by-post/p-s/send-bulk-sms-with-php-and-twilio/send-bulk-sms-with-php-and-twilio.png/_jcr_content/renditions/compressed-800.webp) Send Bulk SMS With PHP and Twilio Matthew Setter  ](https://www.twilio.com/en-us/blog/developers/tutorials/send-bulk-sms-with-php-and-twilio)
  * [ ![](https://www.twilio.com/content/dam/twilio-com/global/en/blog/insights/card-images/generic-card-images/card-insights-fill-shapes-4.png/_jcr_content/renditions/compressed-800.webp) 13 email marketing KPIs to watch closely in 2026 Grant Olsen  ](https://www.twilio.com/en-us/blog/insights/13-email-marketing-kpis-to-watch-closely-in-2024)


##  Related Resources 
[ From APIs to SDKs to sample apps API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform. An icon of a right arrow ](https://www.twilio.com/docs) [ The latest ebooks, industry reports, and webinars Learn from customer engagement experts to improve your own communication. An icon of a right arrow ](https://www.twilio.com/en-us/resource-center) [ Twilio's developer community hub Best practices, code samples, and inspiration to build communications and digital engagement experiences. An icon of a right arrow ](https://www.twilio.com/en-us/developers)
