Why "1 city = 1 area code" breaks local phone number matching (and how to model overlays in JavaScript)
A common mistake in CRM routing and voice applications is checking whether two phone numbers belong to the same metro area by comparing their first three digits (npaA === npaB). That worked before the mid-1990s, when st
A common mistake in CRM routing and voice applications is checking whether two phone numbers belong to the same metro area by comparing their first three digits (npaA === npaB).
That worked before the mid-1990s, when state utility commissions relieved exhausted area codes through geographic splitsβdrawing a boundary line on a map and forcing everyone on one side to change their phone number. Under 47 CFR 52.19, commissions shifted almost entirely to all-services distributed overlays: adding a new area code to the exact same geographic footprint so existing subscribers keep their numbers and everyone dials 10 digits.
As a result, neighbors on the same streetβor two phone lines in the same officeβroutinely have different area codes.
How overlays stack up in fast-growing metros
Look at seven major Texas and Southwest metros from NANPA's active area code records:
-
Houston (713 area code guide): Five area codes cover the same Houston territoryβ
713(1947),281(split in 1996, re-merged into a full overlay in 1999),832(1999),346(2014), and621(2025). -
Dallas (214 area code guide): Four codes share the Dallas metroβ
214(1947),972,469, and945. -
Fort Worth (817 area code guide): Shares the Fort Worth region (
817, created in 1953) with overlay682. -
Austin (512 area code guide): Original 1947 code
512shares Central Texas with overlay737. -
San Antonio (210 area code guide): Split from
512in 1992 and now shares Bexar County with overlay726. -
Phoenix (602 area code guide): Split into
602,480, and623in 1999, then combined in 2023 by eliminating the internal boundaries so all three codes overlay the entire metro. -
Las Vegas (702 area code guide): Original 1947 code
702shares Clark County with overlay725(added in 2014).
Normalizing area codes to their overlay group
Instead of comparing raw 3-digit strings, map every area code in an overlay complex to a canonical metro cluster:
const OVERLAY_GROUPS = [
{ metro: "Houston, TX", primary: "713", codes: ["713", "281", "832", "346", "621"] },
{ metro: "Dallas, TX", primary: "214", codes: ["214", "972", "469", "945"] },
{ metro: "Fort Worth, TX", primary: "817", codes: ["817", "682"] },
{ metro: "Austin, TX", primary: "512", codes: ["512", "737"] },
{ metro: "San Antonio, TX", primary: "210", codes: ["210", "726"] },
{ metro: "Phoenix, AZ", primary: "602", codes: ["602", "480", "623"] },
{ metro: "Las Vegas, NV", primary: "702", codes: ["702", "725"] },
];
const codeToMetro = new Map();
for (const group of OVERLAY_GROUPS) {
for (const code of group.codes) {
codeToMetro.set(code, group);
}
}
function extractNpa(phone) {
const digits = String(phone).replace(/\D/g, "");
const ten = digits.length === 11 && digits.startsWith("1") ? digits.slice(1) : digits;
return ten.slice(0, 3);
}
function sameLocalMarket(numA, numB) {
const npaA = extractNpa(numA);
const npaB = extractNpa(numB);
if (npaA === npaB) {
return { sameMarket: true, metro: codeToMetro.get(npaA)?.metro ?? `NPA ${npaA}` };
}
const gA = codeToMetro.get(npaA);
const gB = codeToMetro.get(npaB);
if (gA && gB && gA.primary === gB.primary) {
return {
sameMarket: true,
metro: gA.metro,
primary: gA.primary,
sharedCodes: gA.codes.length,
};
}
return {
sameMarket: false,
metroA: gA?.metro ?? npaA,
metroB: gB?.metro ?? npaB,
};
}
Running the comparison
console.log(sameLocalMarket("713-200-1000", "621-200-1000"));
console.log(sameLocalMarket("214-200-1000", "945-200-1000"));
console.log(sameLocalMarket("214-200-1000", "817-200-1000"));
console.log(sameLocalMarket("602-200-1000", "480-200-1000"));
Output:
| Pair | npaA === npaB |
sameLocalMarket(a, b) |
Why |
|---|---|---|---|
713 vs 621
|
false |
true (Houston, TX, 5 shared codes) |
621 is the 2025 overlay on the 713/281/832/346 footprint |
214 vs 945
|
false |
true (Dallas, TX, 4 shared codes) |
945 is the 2021 overlay on 214/972/469
|
214 vs 817
|
false |
false (Dallas, TX vs Fort Worth, TX) |
Adjacent DFW numbering plan areas, separate overlay pools |
602 vs 480
|
false |
true (Phoenix, AZ, 3 shared codes) |
Former split boundaries were merged into a single overlay in 2023 |
Practical takeaways for number provisioning
-
Don't hardcode a single area code per city. If a customer asks for a "Houston local number" and
713inventory is tight,281,832,346, and621cover the exact same rate centers. -
Watch for boundary eliminations. Metros like Phoenix (
602/480/623) and Houston (713/281) started as geographic splits and later converted into unified overlays when one side ran low on numbers. - Keep an updated overlay table. You can check current overlay groups for every state on EaseDial's full U.S. area code list or browse individual city histories in the U.S. area code lookup directory.
Disclosure: I work with the team at EaseDial, which publishes the area code guides linked above.
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.