ZIP Code Architecture: From 5-Digit Zones to ZIP+4 Delivery Segments
Published: June 15, 2026 | Author: Elena Rostova (Logistics Systems Architect) | Category: Postal Standards
Explore the internal structure of United States Zone Improvement Plan (ZIP) codes and how geographic routing works.
A ZIP code is a set of mail delivery routes, not a shape on a map. Almost every ZIP-related bug in a geographic system starts with that one mistaken assumption, so it is worth getting straight before any of the structure matters.
ZIPs are routes, not polygons
The Postal Service assigns ZIP codes to organise the movement of mail. A code identifies the carrier routes that serve a set of delivery points. It is not a boundary, it was never drawn as one, and the USPS does not publish ZIP code polygons because there is nothing authoritative to publish.
What follows from that, all of which surprises people in production:
- A ZIP can span two states. 42223 covers Fort Campbell across the Kentucky–Tennessee line. 71749 serves addresses in both Arkansas and Louisiana. A
statecolumn derived from a ZIP will be wrong for these. - A ZIP can span several counties. Plenty do. Any "ZIP to county" table is therefore lossy: it either picks the dominant county or duplicates the row.
- ZIPs are not nested inside cities. One city has many ZIPs; one ZIP can cover several municipalities plus unincorporated land. The "city" USPS records for a ZIP is the *postal* city name, which is the name of the delivery office — frequently not the municipality the resident would name.
- A ZIP has no area. Any polygon you have seen is somebody's interpolation from delivery points, usually a vendor's. Two vendors' ZIP shapefiles disagree, and neither is wrong, because there is no correct answer.
- ZIPs change. New codes are added, boundaries of service shift, codes are retired. There is no stable version to pin.
If you need to answer "is this point inside this area", ZIP codes are the wrong tool. Use a geocoded coordinate and a real boundary — a Census tract, a county, a place.
The five digits
9 0 2 1 0
│ │ │ │ │
│ │ │ └─┴── delivery area: the local post office or delivery zone
│ └─┴────── sectional center: the processing facility's region
└────────── national area: one of ten broad zones, 0 in the northeast to 9 in the west
- Digit 1 is the national area, running roughly west with the number: 0 covers New England and the mid-Atlantic, 9 covers the Pacific coast, Alaska and Hawaii.
- Digits 2–3 identify the sectional center — the region served by one Sectional Center Facility (SCF), the processing plant mail passes through before local delivery.
- Digits 4–5 identify the delivery area within that sectional center.
The first three digits together are the prefix, and the prefix is the useful unit for most structural work: each prefix is assigned to one state, so a prefix validates a state claim where a full ZIP sometimes cannot.
Which facility actually serves a prefix is set by the USPS labeling list L005, and it changes as mail processing is consolidated. Prefixes 010–012, labeled to a Springfield, Massachusetts facility for years, are now labeled to Hartford, Connecticut. Do not hard-code a prefix-to-facility table and treat it as durable; if you need current facility assignments, read the current L005.
ZIP+4
The four-digit add-on narrows a ZIP down to something much smaller than a neighbourhood — typically one side of one block, one floor of an office building, or a single large recipient.
9 0 2 1 0 - 3 4 5 6
│ │ │ │ │
│ │ └─┴─┴── segment: a block face, a floor, a firm, a PO Box group
└─┴──────── sector: a few blocks, a group of streets
Two things to know about the add-on:
- It is derived, not chosen. You cannot compute it; it comes from matching an address against the USPS address database. Any system that invents one is producing a syntactically valid code that points nowhere.
- It is volatile. Add-ons are reassigned as delivery sequences change. Storing a ZIP+4 as a stable identifier for a location is a mistake; re-derive it when you need it.
A ZIP+4 plus the delivery point digits (two more, derived the same way) is what produces the eleven-digit code behind a POSTNET or Intelligent Mail barcode.
ZCTAs: what to join Census data to
The Census Bureau needs areal units to publish statistics against, and ZIPs are not areal units. So it builds ZIP Code Tabulation Areas — ZCTAs — by taking census blocks and assigning each to the ZIP code used by the majority of its addresses.
This matters whenever you join demographic data to ZIP-keyed records:
- A ZCTA is approximately the ZIP of the same number, not identical to it. The five digits match for most; some ZIPs have no ZCTA at all.
- ZIPs with no residential delivery get no ZCTA. PO Box-only ZIPs and single-building ZIPs mostly do not appear.
- ZCTAs are rebuilt per decennial census, so a 2020 ZCTA and a 2010 ZCTA with the same number can cover different ground. Pin the vintage in your join.
- ZCTAs do not cross state lines; ZIPs do. For a two-state ZIP, the ZCTA picks one.
So: if you are computing "median income for this ZIP", you are really computing it for a ZCTA, and you should say so. The error is usually small and occasionally large.
Unique ZIPs
A unique ZIP is assigned to a single high-volume recipient — one building, one company, one institution — and all five digits route to that one destination.
Examples: 20505 is the CIA, 12345 is the General Electric plant in Schenectady, 31416 belongs to a single Savannah recipient, and many universities and large hospitals hold their own.
Two implications. First, validation: a unique ZIP will not match a residential address form's expectations, and a "verify the ZIP matches the city" check can pass while the address is nonsense. Second, geography: a unique ZIP has essentially no area, so it either vanishes from a choropleth or renders as a dot, and it has no ZCTA.
Military and diplomatic mail
APO, FPO and DPO addresses look like a format bug and are not:
SSG JANE DOE
UNIT 2050 BOX 4190
APO AE 09204
- APO is Army/Air Force Post Office, FPO is Fleet Post Office, DPO is Diplomatic Post Office.
- The "state" is a region code: AA (Americas, 340xx), AE (Europe, Middle East, Africa, Canada — 090xx–098xx), AP (Pacific, 962xx–966xx).
- The city field is literally
APO,FPOorDPO. There is no municipality.
Any form that requires a US state from a fixed list of 50, or validates city names against a gazetteer, rejects these. They are domestic mail at domestic rates, and rejecting them is both a bug and, for a service selling to military families, a visible one. Accept AA, AE, AP in your state field and accept the three city literals.
What to do with all this
- Store the ZIP as a string.
07030is not 7030, and a numeric column eats the leading zero. - Treat ZIP as an attribute of an address, not a location. Derive location from coordinates.
- If you need the state, trust the prefix over a lookup table you cannot source.
- Re-derive ZIP+4 rather than storing it as truth.
- Accept five digits, five-plus-four with a hyphen, and the nine-digit unhyphenated form. Normalise to one on write.
import re
ZIP = re.compile(r"^(\d{5})(?:-?(\d{4}))?quot;)
def normalise_zip(value: str):
m = ZIP.match(value.strip())
if not m:
return None
zip5, plus4 = m.groups()
return {"zip5": zip5, "plus4": plus4, "formatted": f"{zip5}-{plus4}" if plus4 else zip5}
normalise_zip("07030") # {'zip5': '07030', 'plus4': None, 'formatted': '07030'}
normalise_zip("902103456") # {'zip5': '90210', 'plus4': '3456', 'formatted': '90210-3456'}
To see which prefixes belong to a given state, or to generate codes inside a prefix for test data, use the ZIP prefix lookup.