Research

How Accurate Is US Address Parsing on Messy Input?

We corrupted thousands of real US addresses with typos, dropped fields, and reordered components, then measured how often the sthan.io parser recovered the original, how often it got one wrong, and whether it warned us when it was unsure.

sthan.io Team
sthan.io Team
August 2, 2026 · 9 min read

Real addresses get typed badly. People swap letters, forget the ZIP, put things in the wrong order, and spell streets the way they sound. So the useful question about an address parser is a simple one: what does it do with the mess?

We took 200,000 real US delivery addresses and broke them on purpose: typos, missing city, state, or ZIP, scrambled order, sound-alike street spellings. Then we asked our parser to work out the original address from each broken version. Three things stood out.

  • On realistic damage, it recovered the right address 96% to 99.9% of the time. Formatting-only corruption (casing, separators, whitespace): 99.9%. A typo or a dropped field: 96%. Only under deliberately extreme corruption, several severe problems stacked on one input, does it drop to 71%. The average across everything, including those extreme cases, is 88.5%.
  • It almost never gives a wrong answer that looks right. At most 1 input in 700 got a wrong answer with no warning. Not one of those had the wrong state.
  • It tells you when it guessed. Corrections come back marked as corrected or approximate, with a lower confidence score. When it cannot work the address out at all, it says so instead of guessing.

One thing before the numbers. We only scored addresses we could first confirm are real. If an address cannot be verified against postal reference data, no parser can recover a broken version of it, so counting those would only muddy the result. The rest of this post walks through each number.

What we tested

We started from a large set of real US delivery addresses and generated controlled corruptions of each one, spanning 31 corruption types ordered from mild to severe:

  • Single and multiple typos, letter transpositions, and phonetic street spellings
  • Dropped city, dropped state, dropped ZIP, and dropped street directionals
  • Reordered fields, including fully reversed order and state-before-city forms
  • Separator and casing noise: no commas, semicolons, extra spaces, all lowercase, all uppercase

The test had two steps. Step one: check each address in its clean form and keep only the ones that resolve to a real postal address. That was 72.8% of our sample. Step two: take 29,966 corrupted variants of those verified addresses, sampled at random from more than a million we generated, and send each one to the live parser in its maximum-recovery mode. Random selection matters here. It means the mix looks like the noise a real integration sees, and nothing was hand-picked to look good.

To keep the numbers honest, the parser had never seen any of these addresses as reference data. A parser tested on data it was built from always looks better than it really is. And because every address in the test is verifiably real, every miss in this report is a genuine miss. There is no fine print behind the number.

Recovery: the right address from a corrupted one

Recovery means one thing: given a corrupted input, the parser returned the correct address, standardized. One reading note before the table. The corruption classes are not equally common in real life. Casing problems, separator noise, a typo, a dropped field: that is the overwhelming majority of what production traffic looks like, and it recovers at 96% to 99.9%. The compound class, several severe corruptions deliberately stacked on one input, is a stress test we built to find the breaking point. It drags the average down, and we report it anyway. Here is how it did:

MetricResult
Corrupted inputs tested (all verified real addresses)26,943
Recovered: formatting-only corruption (casing, separators, whitespace)99.9%
Recovered: single-field damage (a typo, a dropped field)96.2%
Recovered: structural damage (reordered fields, multiple errors)89.7%
Recovered: compound damage (several severe corruptions at once)71.2%
Recovered: average across all severities88.5%
Wrong answer with no warningat most 0.14% (about 1 in 700); wrong state: zero
Wrong answer, but flagged as uncertain3.4%
Returned nothing instead of guessing7.9%

None of this was measured on tidy inputs. Below are 20 real benchmark inputs the parser recovered correctly, five per severity class, color coded from compound damage down to formatting-only corruption. The middle column is exactly what went in. The last column is the match signal the parser returned: Exact when the address was never in doubt, and Near, Approximate, or Speculative with a confidence score when it had to correct or infer a field.

CorruptionInput, as typedRecoveredSignal
Compound damage several severe corruptions at once · 71.2% recovered in this class
Typos throughout, no ZIP 2 emreald ln doevr new hmapshire 2 Emerald Ln, Dover, NH 03820 Approximate · 0.7
Two typos, no ZIP 18 CQDTER CT, ALOWN, TX 18 Carter Ct, Allen, TX 75002-5286 Approximate · 0.7
Typos, random case, spaces 312 cLraK sT CacYe soUth acRolIna 29033 312 Clark St, Cayce, SC 29033-3911 Approximate · 0.7
Two typos, no ZIP 275 DKRCHSSTER AVE, BKSTLN, MA 275 Dorchester Ave, South Boston, MA 02127-1809 Approximate · 0.85
Typos throughout, no ZIP 617 csating cv montgomrey alabaam 617 Casting Cv, Montgomery, AL 36108-1355 Approximate · 0.7
Structural damage reordered fields, multiple errors · 89.7% recovered in this class
Fully reversed order 79252 TX QUANAH EDDY ST 1600 1600 Eddy St, Quanah, TX 79252-6428 Approximate · 0.7
ZIP first, city last 50519-5025 608 2ND ST IA BODE 608 2nd St, Bode, IA 50519-5025 Exact
House number at the end RD M, CORTEZ, CO 81321 24553 24553 Rd M, Cortez, CO 81321-8854 Approximate · 0.7
State and city swapped 403 7TH ST, IA, BODE 50519-9501 403 7th St, Bode, IA 50519-9501 Approximate · 0.7
State first IA, 3 G AVE W, ALBIA, 52531-1003 3 G Ave W, Albia, IA 52531-1003 Exact
Single-field damage a typo or a dropped field · 96.2% recovered in this class
City missing 1025 BRIAR AVE OH 43160 1025 Briar Ave, Washington Court House, OH 43160-1007 Exact
ZIP missing 108 J RD, VOSS, TX 108 J Rd, Voss, TX 76888 Exact
Misspelled city 5 JUDY LN, CJIVO, CA 95926 5 Judy Ln, Chico, CA 95926-1714 Approximate · 0.7
Phonetic street spelling 2533 TAPHT AVE, OREGON, OH 43616 2533 Taft Ave, Oregon, OH 43616-3829 Speculative · 0.5
Single typo 63 MAUN RD, GILL, MA 01354 63 Main Rd, Gill, MA 01354 Near · 0.9
Formatting only casing, separators, whitespace · 99.9% recovered in this class
Noise prefix Deliver to: 96 3RD ST, TROY, NY 12180 96 3rd St, Troy, NY 12180-4037 Exact
Tabs for commas 20161 BATTERY PARK RD, SMITHFIELD, VA 23430 20161 Battery Park Rd, Smithfield, VA 23430-5609 Exact
No commas 52 FEDERAL RD DANBURY CT 06810 52 Federal Rd, Danbury, CT 06810-6129 Exact
Random mixed case 1566 W CoMET rD, neW fRAnkLIn, OH 44216 1566 W Comet Rd, New Franklin, OH 44216 Near · 0.9
All lowercase 49 river rd w, berlin, ma 01503 49 River Rd W, Berlin, MA 01503-1645 Exact

Notice two things. The parser also cleaned up the casing and filled in the ZIP+4 wherever it could. And look at the last column: formatting-only corruption came back Exact, while every typo, dropped field, and reorder came back marked as a correction. It never pretended a repaired address was an exact match.

When it is unsure, it tells you

A miss will rarely hurt you. You get no answer, you see it, you handle it. The dangerous case is a silent substitution: the parser returns a different address than the one you meant and stamps it as an exact, high-confidence match. No warning. That is how a package ends up at the wrong house while everyone believes the data was clean.

In this test, that happened on at most 37 inputs out of 26,943, about 1 in 700. We say "at most" because we scored against reference data that has flaws of its own, so some of those 37 answers may actually be fine. Not one of them had the wrong state. Everything else that was wrong or uncertain came with a warning. When the parser changes something, it lowers the match tier and the confidence score:

  • matchTier drops from Exact to Near, Approximate, or Speculative
  • confidence drops below 1
  • matchCode flags which components were corrected or left unconfirmed

Here is one of the heavier inputs from the benchmark: a misspelled street, a misspelled city, a misspelled state, and no ZIP. This is the response it produced.

// input:  "2 emreald ln doevr new hmapshire"
{
  "fullAddress": "2 Emerald Ln, Dover, NH 03820",
  "matchTier": "Approximate",
  "confidence": 0.7,
  "matchCode": {
    "houseNumber": "Matched",
    "street": "Corrected",
    "city": "Inferred",
    "state": "Matched",
    "zipCode": "Inferred"
  }
}

The parser corrected the street, inferred the city and ZIP, and did not pretend to be certain. It returned Approximate at confidence 0.7 with a per-field breakdown of exactly what it changed.

This lets you set a simple rule in your code. Accept exact, high-confidence results automatically. Send anything marked corrected or approximate to a review step. In this run, 918 answers were wrong and said so themselves: their tier and confidence told you up front to double-check them.

Refusing addresses that do not exist

A parser that always returns something is easy to build and dangerous to use. So we also fed it poisoned input: made-up house numbers, the wrong state for a ZIP, the wrong ZIP for a city, and flipped street directions. The right response there is to refuse, to flag the fix, or to restore the true address. The parser did one of those 99.5% of the time. For made-up house numbers specifically, it returned nothing 99.9% of the time instead of inventing a match.

It shows the same restraint on ordinary broken input. When too much of an address is destroyed, it returns nothing rather than guessing. That happened on 7.9% of the test, and the next section breaks down where.

Where recovery falls short

So where does the missing 11.5% go? Split it up: 7.9% refused to answer, 3.4% were wrong but flagged themselves, and at most 0.14% slipped through silently. Every address in the test is real, so the refusals are genuine misses. They pile up exactly where you would guess:

  • Several typos and no ZIP. When the street and the city are both misspelled and there is no ZIP, there is not much left to work with. On those inputs alone, refusals run 31% to 38%. Could the parser guess? Sure. Guessing is how wrong-address databases get built, so it refuses instead. This is a deliberate choice, and it is the largest remaining group.
  • Severely reordered input. Fully reversed and ZIP-first orderings still fail more than average when the reordering also strips the fields that anchor a search. This class got much smaller in recent releases and keeps shrinking.

We publish this because knowing where the parser fails is as useful as knowing where it works. It tells you exactly where to add a check in your own flow: if your form asks for a ZIP, you close most of the remaining gap.

What this means for your integration

  • Trust the exact, high-confidence results. They are almost never silently wrong, so you can accept them without a human in the loop.
  • Use the match tier and confidence as a routing signal. Send corrected or approximate answers to review or to a user confirmation step.
  • Expect no answer on genuinely bad input. A refusal is information. Treat it as "ask the user to check," not as a bug.
  • Provide a ZIP when you can. It is the single most valuable anchor when the rest of the input is noisy.

You can run the same kinds of inputs against the API yourself. The free tier includes 100 lookups every month, no card required.

Frequently Asked Questions

We corrupted real, verified US addresses on purpose and asked the parser to recover them. On realistic damage it found the right address 96% to 99.9% of the time: 99.9% on formatting-only corruption, 96% on typos and dropped fields. Deliberately extreme corruption, several severe problems stacked on one input, recovers at 71%, which brings the average across everything to 88.5%. At most 1 in 700 inputs got a wrong answer without a warning, and none of those had the wrong state.
It is when a parser returns a different address than the one you meant and reports it as an exact, high-confidence match with no warning. This is the failure mode that quietly corrupts a database. In our test it happened on at most 1 in 700 inputs, and none of those had the wrong state. Every other correction announced itself through a lower match tier and confidence score.
Read it as a stress-test average, and not as what typical traffic experiences. Everyday corruption, meaning typos, dropped fields, and formatting noise, recovers at 96% to 99.9%, and that is what most production input looks like. The 88.5% average includes deliberately brutal cases we built to find the breaking point, mostly multiple typos with no ZIP left to anchor the search. There the parser refuses rather than guesses, and we think that is the right call. The parser had also never seen any of these addresses as reference data, which keeps every number conservative.
Yes. Accept results with an exact match tier and a confidence of 1 automatically, and route anything corrected, approximate, or below 1 to review. The response includes a per-component match code so you can see exactly what changed.

Try it on your own messy addresses

Run corrupted, real-world inputs against the sthan.io API. Get 100 free lookups every month.

sthan.io Team
Written by sthan.io Team

The sthan.io engineering team builds and maintains address parsing, verification, geocoding, and autocomplete APIs. We benchmark our own systems on real, corrupted input and publish the numbers, including where they fall short.

Learn more about us