Address Standardization & Parsing Overview
Address standardization (also referred to as address normalization or standardisation) takes a messy, free-text address typed by a customer, scraped from a form, or pulled from a database, and turns it into structured, canonical components and standardized string expansions you can validate, match, search, and route on.
What it solves
Section titled “What it solves”The same physical address can be written dozens of valid ways: "Ave" vs "Avenue", "St" vs "Street", "Ste 200" vs "Suite 200", "Apt 4B" vs "Unit 4B", house-number-first vs house-number-last, different scripts and transliterations entirely. Free-text addresses that mean the same thing rarely look the same as strings — which breaks exact-match lookups, deduplication, and downstream systems (tax engines, shipping carriers, geocoders, search engines) that expect structured or canonical input.
Address standardisation solves this through a dual-engine architecture:
- Sequence labelling: Decomposes free text into semantic components (
houseNumber,road,unit,city,postcode,country). - Canonical expansion: Generates fully expanded, standardized string variants (
expansions) where abbreviations and street types are resolved into their canonical forms (st→street,ave→avenue,ste→suite,ny→new york).
How it works
Section titled “How it works”Rather than matching addresses against fixed per-country templates or regular expressions — which break the moment a country’s convention doesn’t fit the template — GoodVat’s standardisation engine treats address parsing as a sequence-labelling problem, the same class of problem as named-entity recognition. It uses a Conditional Random Field (CRF) statistical model trained on hundreds of millions of real-world addresses spanning every country and script, learning to segment a raw string into semantic components regardless of word order, language, or formatting convention.
Concurrently, a statistical multi-lingual token expansion engine resolves abbreviations, directional prefixes, thoroughfare types, unit designators, and multi-lingual variants. Two differently-formatted strings for the same physical address converge on the exact same canonical string representation in the expansions array.
For especially gnarly inputs — colloquial descriptions, missing unit numbers, or ambiguous transliterations — an AI resolution layer resolves ambiguity using context, not just pattern-matching.
The result: one API that parses addresses from any country, in any of 60+ languages, into the same structured shape and standardized canonical representations.
Canonical Expansions (expansions)
Section titled “Canonical Expansions (expansions)”Alongside granular fields, every successful response delivers an expansions array containing canonical string variations of the standardized address.
Abbreviation and Token Standardization
Section titled “Abbreviation and Token Standardization”The expansion engine automatically expands abbreviations, unit designators, and directionals across multiple languages:
| Category | Input Variations | Canonical Standardized Expansion |
|---|---|---|
| Street & Thoroughfare Types | St, Str, Ave, Rd, Blvd, Dr, Ln, Pkwy, Ct, Pl, Sq | street, avenue, road, boulevard, drive, lane, parkway, court, place, square |
| Secondary Unit Indicators | Ste, Ste., Apt, Apt., Fl, Bldg, Rm, Unit, # | suite, apartment, floor, building, room, unit |
| Directional Prefixes / Suffixes | N, S, E, W, NE, NW, SE, SW | north, south, east, west, northeast, northwest, southeast, southwest |
| State & Administrative Regions | NY, CA, TX, FL, IL, WA, etc. | ny / new york, ca / california, tx / texas, etc. |
| Multi-lingual / International | Str. (DE), Bd (FR), V. (IT), C/ (ES), Quatre-vingt-douze (FR) | straße, boulevard, via, calle, 92 (standardized numerals) |
Practical Use Cases for expansions
Section titled “Practical Use Cases for expansions”1. Search Suggestions & Autocomplete Indexing
Section titled “1. Search Suggestions & Autocomplete Indexing”When indexing customer addresses, locations, or delivery points in Elasticsearch, Meilisearch, Algolia, or PostgreSQL full-text search, index all elements of the expansions array. When a user types "781 Franklin St" or "781 Franklin Avenue", both query strings match the exact same indexed record without having to write custom synonym dictionaries.
2. Exact Entity Deduplication
Section titled “2. Exact Entity Deduplication”Avoid expensive, error-prone fuzzy string matching. By hashing or joining on the primary canonical expansion (address.expansions[0]), records entered as "123 Oak St Ste 200" and "123 Oak Street, Suite 200" produce identical keys.
3. Cross-System Record Reconciliation
Section titled “3. Cross-System Record Reconciliation”When synchronizing customer data across CRM (Salesforce/HubSpot), ERP (NetSuite/SAP), billing (Stripe), and shipping (Shippo/EasyPost), match records using the standardized canonical expansion string to eliminate duplicate accounts created by varied entry formats.
The API
Section titled “The API”Request
Section titled “Request”| Field | Required | Description |
|---|---|---|
query (POST) / address (GET) | Yes | The free-form address string to standardise. |
language | No | ISO 639-1 hint for the address’s language (e.g. en, de, ja). Improves parsing when the string is ambiguous. |
country | No | ISO 3166-1 alpha-3 hint for the address’s country (e.g. USA, GBR, DEU). |
curl -X POST "https://api.goodvat.com/v1/address/normalize" \ -H "Authorization: Bearer $GOODVAT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "query": "781 Franklin Ave Crown Heights Brooklyn NY 11216 USA" }'const response = await fetch('https://api.goodvat.com/v1/address/normalize', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.GOODVAT_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ query: '781 Franklin Ave Crown Heights Brooklyn NY 11216 USA', }),});
const address = await response.json();console.log('Structured:', address.road, address.cityDistrict, address.state);console.log('Canonical expansions:', address.expansions);import osimport requests
response = requests.post( "https://api.goodvat.com/v1/address/normalize", headers={ "Authorization": f"Bearer {os.environ['GOODVAT_API_KEY']}", "Content-Type": "application/json", }, json={"query": "781 Franklin Ave Crown Heights Brooklyn NY 11216 USA"},)
address = response.json()print("Structured:", address["road"], address["cityDistrict"], address["state"])print("Canonical expansions:", address.get("expansions", []))Response
Section titled “Response”A successful request returns HTTP 200 OK with only the components the parser was confident about — fields with no match are omitted rather than returned empty — alongside the expansions array.
{ "houseNumber": "781", "road": "franklin ave", "postcode": "11216", "suburb": "crown heights", "cityDistrict": "brooklyn", "state": "ny", "country": "USA", "expansions": [ "781 franklin avenue crown heights brooklyn ny 11216 usa", "781 franklin avenue crown heights brooklyn new york 11216 usa" ]}| Field | Type | Description |
|---|---|---|
expansions | string[] | A list of canonical, fully expanded string variations of the input address with abbreviations and street types standardized (e.g., st → street, ave → avenue, ny → new york). Ideal for search suggestions, deduplication, and database indexing. |
houseNumber | string | Street or building number. |
road | string | Street, road, avenue, or thoroughfare name. |
unit | string | Apartment, suite, unit, or floor number. |
level | string | Floor or level designation. |
staircase | string | Staircase identifier (used in some European addressing schemes). |
entrance | string | Entrance identifier. |
poBox | string | Post Office Box number. |
postcode | string | Postal code or ZIP code. |
suburb | string | Neighborhood, borough, or suburb. |
cityDistrict | string | District or borough within a city. |
city | string | City, town, or village. |
island | string | Island name, where relevant (e.g. archipelagic countries). |
stateDistrict | string | County or administrative district within a state or province. |
state | string | State, province, or region. |
countryRegion | string | Formal or informal region spanning multiple states (e.g. “New England”). |
country | string | ISO 3166-1 alpha-3 country code. |
worldRegion | string | Global or continental region (e.g. “European Union”). |
house | string | Name of a building, venue, or place at the address (e.g. “The Book Club”, “Eiffel Tower”). |
category | string | Category of a place-search query (e.g. “restaurants”), for near/category-style inputs. |
near | string | Place name modifying a category query. |
Use cases
Section titled “Use cases”Structured, canonical addresses are foundational infrastructure — they show up anywhere a system needs to compare, route, validate, or store a physical location. A few of the most common: