Educational

Bulk Address Validation: CSV Upload Costs Compared

List prices for cleaning a file of 10,000, 100,000 and 1,000,000 US addresses, read from each vendor's own page on the same day. Plus what a real 10,000-row file cost, and a short Python script for the API route.

Daniel Okafor
October 16, 2026 · 8 min read · Last reviewed

A bulk address validation CSV upload checks a whole file of addresses at once and returns it cleaned. At list prices read on October 16, 2026, a 100,000-row US file costs $350 in Melissa credits, $485 on Smarty's monthly plan, $2,699 in Byteplant credits and $475 or $3,000 at PostGrid, depending on its plan. sthan.io Address Cleaner charges at most $120, because you pay $1.20 per 1,000 rows found in postal records.

What a file of addresses costs at each size

All five tools below take an uploaded file and verify the US addresses in it. sthan.io is our own product. Prices are list prices for US addresses, read on each vendor's own page on October 16, 2026. Where a vendor sells plans, we picked the cheapest plan that covers the file in one go. Where a page has a tier selector, we clicked each tier and read its own price.

Vendor and tool10,000 rows100,000 rows1,000,000 rowsHow it is priced
sthan.io Address Cleaner$12 if every row is billed$120 if every row is billed$1,200 if every row is billed (10 files of 100,000)$1.20 per 1,000 rows found in postal records. Rows that need review or are not found are free. Free preview of the first 100 rows a day; $1.00 minimum. Up to 100,000 rows per file
Melissa online portal (Listware Online)$40$350$3,200Credits: an address Check costs 1 credit per record (US and Canada). Credit packs: $40 for 10,000, $350 for 100,000, $3,200 for 1,000,000
Smarty Bulk Address Validation upload$88$485$3,720 (yearly plan, $3,720 per year)Lookups: each address is one lookup, bulk or single. Monthly 10,000 plan; monthly 170,000 plan; 1,000,000 needs the yearly plan
Byteplant Address-Validator, one-time credits$284.90$2,699Quote ("individual offer"; list price shown $28,490)US addresses cost 1 credit each; the pricing calculator showed these totals
PostGrid Standard plan, monthly, with its CSV List Uploader$45$475$4,975Business: $45 a month, 10,000 lookups. Growth: $225 a month, 50,000 lookups, then $0.005 per additional lookup. All four Standard plans list a CSV List Uploader. PostGrid does not say on these pages whether uploaded rows use the plan's lookups
PostGrid Bulk Verification (a separate rate)$300 to $500$3,000Talk to SalesPer address, US and Canada: $0.05 in the 100-10k band, $0.03 in the 10k-100k band; "100k Plus" says Talk to Sales

The sthan.io figures are examples with every row billed, that is, every row found in postal records. What a real file costs depends on how many rows come back needs review or not found. The free preview shows the first 100 rows a day cleaned at no charge, and a file of up to 100 rows that the preview covered in full is cleaned free. PostGrid's 10,000 figure is a range because its 100-10k and 10k-100k bands both include 10,000; its 100,000 figure uses the $0.03 band, and 100,000 is also where its "100k Plus" Talk to Sales band starts. PostGrid's Standard figures assume uploaded rows use the plan's lookups: 100,000 rows on Growth is $225 plus 50,000 extra lookups at $0.005, and 1,000,000 rows is $225 plus 950,000 at $0.005. PostGrid's bulk guide says the upload step shows "a summary of your available versus used lookups, along with the total cost of processing", but neither the guide nor the pricing page says whether a Standard plan's lookups pay for an upload. These totals are our multiplication of the per-row prices.

What stands out:

  • You pay sthan.io only for rows it finds. Rows marked needs review or not found cost nothing, so a messy file costs less than the every-row examples above. Before a file starts, your card shows a hold for the most it can cost, and the real amount is taken when it is done.
  • Melissa has the lowest displayed price among the priced alternatives in this table, because a US address Check is 1 credit in Listware. Melissa stays lowest when PostGrid's Standard plan route is counted. Byteplant at 1,000,000 rows and PostGrid's Bulk Verification above 100,000 rows quote on request, so they are not in that comparison. Melissa adds that "Your first 1000 addresses are free*" in the online portal. Its main pricing page gives other credit counts for a US address (3 credits in its FAQ, 10 on its pay-as-you-go card), so ask which one applies to your file before you buy.
  • Smarty's plans run out by lookups or time, "whichever comes first." Its upload tool takes "Excel and CSV (up to 500,000 rows)", so a 1,000,000-row file needs two uploads or its command line tool.
  • Byteplant credits never expire, which suits a one-time cleanup. For 1,000,000 rows the calculator asked us to request a quote.
  • PostGrid has two routes. Its Standard plans include the CSV List Uploader and a monthly number of lookups. Its Bulk Verification tab has a separate per-address price that shows only when you move the slider; the slider starts at the free 100 lookups. Ask PostGrid which one an upload is billed under before you buy.

sthan.io is not CASS-certified. Melissa, Smarty, Byteplant and PostGrid each say on these pages that their address checks are CASS certified. That matters for mail sent at USPS automation prices and for carrier route coding (see the last question below). Check the rules for your own mailing.

What a real 10,000-row file cost

On October 12 and 13, 2026 we ran a 10,000-row spreadsheet through sthan.io Address Cleaner. Every row was a real US address from public address records that had never been sent to us. We made the list messy the way customer lists are: about 40% of rows left as typed, about 20% with two letters swapped in the street name, about 20% with no ZIP (2,009 rows) and about 20% all in lower case. Because we knew the right address for every row, we could check every answer. The full write-up is in address cleansing vs verification vs standardization.

ResultRowsShareWhat it meansCharged
Verified6,05260.5%Gets mail as typed. Short forms written out, a missing ZIP added.Yes
Corrected1,42114.2%Gets mail after a fix. Every fix is listed next to the row.Yes
Unit missing3793.8%The building gets mail, but the apartment or suite number is missing.Yes
Not deliverable5115.1%A real address the post office does not deliver to.Yes
Needs review1,19211.9%A likely answer that changes more than we can be sure of.No
Not found4454.5%No match.No

The job record shows a charge of $9.94 for 8,280 billed rows. The first 100 rows of the file had been cleaned in the free preview, so they were free; 83 of them had a billed status. The 1,637 rows marked needs review or not found were free too. The card hold before the run, the most the file could cost after its 100 free rows, was $11.88. Of the 8,363 rows that got an answer we charge for, 8,117 matched the known right address exactly. We read the other 246 by hand: each one was the same address written the postal way, such as a spelled-out word or an added plural. None was a different address.

Most fixes were small. Address Cleaner fixed 1,104 misspelled street names, 536 wrong or short town names (like "atl" for Atlanta), 25 street directions and 14 ZIP codes. It also added a ZIP to 1,884 of the 2,009 rows that had none. Your own numbers will depend on your list: a clean export from a CRM will have more verified rows, and addresses typed by customers on a phone may need more fixes.

What you get back is your file with all your original columns, plus the cleaned address, city, state, ZIP and ZIP+4, whether mail can be delivered, county, a status for every row and a list of what changed. A large file can take several hours; the results link is emailed to you, and files are deleted after 30 days.

The API route: loop over the rows

For one file, the Address Cleaner needs no plan and no code. If you clean 100,000 rows every month, the verification API is cheaper: its 100,000-request plan is $65 a month against $120 in the cleaner. The script below reads a CSV with an address column, waits between calls to stay under your plan's per-minute limit, retries when the API answers 429 (too many requests), and writes each result as soon as it has it, so a stopped run keeps its finished rows.

import csv
import sys
import time
import urllib.parse

import requests

API = "https://api.sthan.io/v2/address-verification/usa/"
KEY = "YOUR_API_KEY"
PER_MINUTE = 10  # free tier; the $12 plan allows 500 a minute
FIELDS = ["input", "status", "fullAddress", "zip4", "dpvConfirmation", "deliverableStatus"]

def verify(address):
    url = API + urllib.parse.quote(address, safe="")
    while True:
        r = requests.get(url, headers={"Authorization": "Bearer " + KEY}, timeout=120)
        if r.status_code == 429:  # over the per-minute limit: wait and retry
            time.sleep(int(r.headers.get("Retry-After", "30")))
            continue
        return r

def main(src, dst):
    gap = 60.0 / PER_MINUTE
    with open(src, newline="", encoding="utf-8") as fin, \
         open(dst, "w", newline="", encoding="utf-8") as fout:
        out = csv.DictWriter(fout, fieldnames=FIELDS)
        out.writeheader()
        for row in csv.DictReader(fin):
            started = time.monotonic()
            r = verify(row["address"])
            result = (r.json().get("Result") or {}) if r.ok else {}
            out.writerow({
                "input": row["address"],
                "status": r.status_code,
                "fullAddress": result.get("fullAddress"),
                "zip4": result.get("zip4"),
                "dpvConfirmation": result.get("dpvConfirmation"),
                "deliverableStatus": result.get("deliverableStatus"),
            })
            fout.flush()  # keep finished rows if the run stops
            time.sleep(max(0.0, gap - (time.monotonic() - started)))

if __name__ == "__main__":
    main(sys.argv[1], sys.argv[2])

Run it as python verify_csv.py addresses.csv results.csv. Set PER_MINUTE to your plan's limit: 10 on the free tier, 500 on the $12 plan. The free tier also stops at 100 a day; when the API answers 429, the script waits the number of seconds in the Retry-After header and tries again.

What it returned on three rows

We ran the script on October 16, 2026 against the live API with three rows: two office buildings with a suite number, and one public building typed in lower case with no ZIP Code. At the free-tier pace of 10 a minute, it finished in about 20 seconds. This is the output file:

input,status,fullAddress,zip4,dpvConfirmation,deliverableStatus
"1355 Market St Ste 900, San Francisco, CA 94103",200,"1355 Market St STE 900, San Francisco, CA 94103-1337",1337,Y,Confirmed
1600 pennsylvania ave nw washington dc,200,"1600 Pennsylvania Ave NW, Washington, DC 20500-0005",0005,Y,Confirmed
"233 S Wacker Dr Suite 3300, Chicago, IL 60606",200,"233 S Wacker Dr STE 3300, Chicago, IL 60606-6387",6387,Y,Confirmed

All three came back Y and Confirmed, with the suite written the postal way (STE) and a ZIP+4 added. The loop waits for each answer before it sends the next, so it runs slower than the per-minute cap when responses are slow. For a large file, open the output in a spreadsheet as it grows and spot-check rows that did not come back Confirmed.

sthan.io's cost per row on the API

These are sthan.io's monthly plans for US address verification. The cost of a one-time file is one month of the plan that covers it.

RowsPlanPrice a monthCost per rowPer-minute limit
3,000 (up to 100 a day)Free$0$010
10,000Basic$12$0.0012500
100,000Starter$65$0.000652,500 to 5,000 (Starter range)
1,000,000Enterprise$300$0.000350,000

Cost per row is our division of the plan price by its row count. An API plan is a monthly number of requests; the cleaner charges only rows found in postal records.

Where sthan.io fits. For a file, sthan.io Address Cleaner takes an Excel or CSV file of up to 100,000 rows and needs no account: a free preview cleans the first 100 rows a day, and a file is charged $1.20 per 1,000 rows found in postal records, with a $1.00 minimum. Rows that need review or are not found are free. For code, the US Address Verification API returns the standardized address, ZIP+4 and a deliverability status for each row (3,000 free a month, up to 100 a day, no credit card; then $12 a month for 10,000). sthan.io is not CASS-certified, so for mail sent at USPS automation prices or carrier route coding, use CASS-certified address matching (see is CASS certification required).

Frequently Asked Questions

At list prices read on October 16, 2026: $350 in Melissa credits, $485 for Smarty's monthly 170,000-lookup plan, $2,699 in Byteplant one-time credits, and at PostGrid $475 on its monthly Growth plan if uploaded rows use plan lookups, or $3,000 at its separate Bulk Verification rate. sthan.io Address Cleaner charges at most $120, because only rows found in postal records cost $1.20 per 1,000.
Only small amounts. sthan.io Address Cleaner shows your first 100 rows each day cleaned free in a preview, Melissa says your first 1,000 addresses in its online portal are free, Smarty's free trial covers 1,000 US lookups, Byteplant's first 100 address validations are free, and PostGrid gives 100 bulk credits for testing.
Yes. sthan.io Address Cleaner takes an Excel, CSV or TSV file of up to 100,000 rows and 50 MB, with no account, and returns your original columns plus the cleaned address, ZIP+4, county and a status for every row. It costs $1.20 per 1,000 rows found in postal records, with a $1.00 minimum; rows that need review or are not found are free.
sthan.io Address Cleaner takes up to 100,000 rows per file. Smarty's upload tool supports Excel and CSV files up to 500,000 rows and points to its command line tool for larger lists, and PostGrid says you can upload and verify up to 1 million addresses at a time.
You need CASS-certified address matching for mail sent at USPS automation prices, and USPS rules also say carrier route coding must be performed using CASS-certified software. Check the rules and required paperwork for your own mailing. sthan.io is not CASS-certified.

Sources

All read October 16, 2026. Prices change; check the vendor page before you buy.

Clean your first 100 rows free

No account needed. Upload a spreadsheet and see the first 100 rows cleaned before you pay anything.

Daniel Okafor
Written by Daniel Okafor

Daniel Okafor writes about step-by-step Python and Django integrations for address verification, parsing and autocomplete.

More from Daniel Okafor