Incorrect address data leads to wasted postage, returned mail, and delayed campaigns. When your customer database contains thousands of records, checking each address manually is not realistic.
This tutorial shows you how to use Node.js, PostgreSQL, and Lob’s Address Verification API to verify addresses in batches and flag records that need attention before you mail them.
Set up the database and Node.js app
Before starting, make sure you have Node.js, npm, PostgreSQL, and a Lob API key.
Create a PostgreSQL table for your address records:
CREATE TABLE addresses (
id SERIAL PRIMARY KEY,
recipient TEXT,
primary_line TEXT NOT NULL,
city TEXT,
state TEXT,
zip_code TEXT,
deliverability TEXT,
verification_action TEXT
);
Next, create the Node.js project and install the PostgreSQL and environment-variable packages:
mkdir bulk-address-verification
cd bulk-address-verification
npm init -y
npm install pg dotenv
Create a .env file containing your database connection string and Lob API key:
DATABASE_URL=postgresql://user:password@localhost:5432/address_demo
LOB_API_KEY=your_api_key
Keep this file out of source control so your credentials remain private.
Connect Node.js to PostgreSQL
Create an index.js file and add the database connection:
import "dotenv/config";
import pg from "pg";
const pool = new pg.Pool({
connectionString: process.env.DATABASE_URL,
});
Retrieve the address records that have not yet been verified:
const { rows } = await pool.query(`
SELECT
id,
recipient,
primary_line,
city,
state,
zip_code
FROM addresses
WHERE deliverability IS NULL
ORDER BY id
`);
The query returns the original database ID along with the address fields required for verification.
Verify addresses in bulk
Lob’s bulk US verification endpoint accepts up to 20 addresses per request. Larger lists should be divided into batches.
Add this function to send a batch:
async function verifyAddresses(addresses) {
const authorization = Buffer.from(
`${process.env.LOB_API_KEY}:`
).toString("base64");
const response = await fetch(
"https://api.lob.com/v1/bulk/us_verifications?case=proper",
{
method: "POST",
headers: {
Authorization: `Basic ${authorization}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
addresses: addresses.map((address) => ({
recipient: address.recipient,
primary_line: address.primary_line,
city: address.city,
state: address.state,
zip_code: address.zip_code,
})),
}),
}
);
if (!response.ok) {
throw new Error(`Verification failed: ${response.status}`);
}
const data = await response.json();
return data.addresses;
}
Call the function with a batch of database records:
const batch = rows.slice(0, 20);
const results = await verifyAddresses(batch);
A test API key can help you confirm that the integration works. Actual deliverability results require a live API key.
Turn deliverability results into actions
The API returns a deliverability value for each address. Use that value to decide what happens next:
function getAction(deliverability) {
switch (deliverability) {
case "deliverable":
return "ready_to_mail";
case "deliverable_unnecessary_unit":
return "use_standardized_address";
case "deliverable_missing_unit":
case "deliverable_incorrect_unit":
return "manual_review";
case "undeliverable":
return "suppress_until_corrected";
default:
return "manual_review";
}
}
The statuses mean:
- Deliverable: The address is supported for USPS delivery.
- Deliverable with an unnecessary unit: The address is deliverable, but the unit information is not needed.
- Deliverable with a missing or incorrect unit: The building is deliverable, but the apartment or suite information needs attention.
- Undeliverable: USPS delivery is not supported for the address as entered.
An undeliverable result should not automatically erase the customer record. The address may contain a correctable typo or outdated information. Suppress it from mailing until it can be reviewed.
Save the verification results
Update each database record with its deliverability status and recommended action:
for (let index = 0; index < results.length; index += 1) {
const result = results[index];
const original = batch[index];
await pool.query(
`
UPDATE addresses
SET
deliverability = $1,
verification_action = $2
WHERE id = $3
`,
[
result.deliverability || "error",
getAction(result.deliverability),
original.id,
]
);
}
You can then query the table to separate records that are ready to mail from those that need correction:
SELECT *
FROM addresses
ORDER BY verification_action, id;
For a larger database, repeat the process in batches until every unverified record has been checked.
Use bulk verification without creating new data problems
A few practical rules make the workflow more reliable:
- Keep the original address until you decide whether to accept the standardized version.
- Record when verification occurred so older results can be checked again.
- Add retry handling for temporary API or network failures.
- Protect address data and avoid including complete customer records in logs.
- Send missing-unit, incorrect-unit, and API-error results to review.
Bulk verification works best alongside point-of-entry checks. Verifying addresses when customers submit them prevents new errors, while periodic bulk verification improves list hygiene across existing records.
Verification can reduce avoidable mailing problems, but it cannot prevent every return. A verified location may still produce undeliverable mail if the recipient moved, the mailbox is inaccessible, or conditions changed after verification.
Add address verification to your mailing workflow
You now have the foundation for a Node.js workflow that retrieves address records, verifies them in batches, and assigns a clear next step to each result.
Lob uses postal and other address data to standardize records and evaluate deliverability before mail enters production. Book a demo to explore how address verification can fit into your application.
Frequently asked questions about bulk address verification
FAQs
What is bulk address verification?
Bulk address verification checks multiple address records in one request. It standardizes the submitted information and returns deliverability data for each address.
How many addresses can Lob verify in one bulk request?
The bulk US verification endpoint accepts up to 20 addresses per request. Divide larger databases into multiple batches.
Should undeliverable addresses be deleted?
Not automatically. Suppress the address from mailing and review it first. A typo, missing field, or outdated record may be correctable.
Does address verification identify customers who moved?
No. Address verification evaluates whether the submitted location is valid and deliverable. It does not confirm that a particular recipient currently lives there.



.png)
.png)


