File size: 11,984 Bytes
39dc93d
ff451cf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b9ef120
aa9ba84
9cb949e
ff451cf
6e3a1cc
3c515ec
 
 
 
 
 
 
6e3a1cc
ff451cf
 
 
 
 
 
 
 
 
 
 
 
 
 
5e673b3
ff451cf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
be98a5c
c004092
39dc93d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Ziplore: free US ZIP code lookup & radius search</title>
<meta name="description" content="Free US ZIP code lookup: city, county, time zone, population, income and home value for any ZIP, plus every ZIP within N miles.">
<style>
  :root { --bg: #fbfaf7; --fg: #1d2330; --muted: #5d6675; --line: #e3e0d8; --card: #fff; --accent: #1f6f5c; --accent-fg: #fff; }
  @media (prefers-color-scheme: dark) { :root { --bg: #14171c; --fg: #e8e6e1; --muted: #9aa3ad; --line: #2b3038; --card: #1b1f26; --accent: #4fb89b; --accent-fg: #0d1a16; } }
  * { box-sizing: border-box; }
  body { margin: 0; background: var(--bg); color: var(--fg); font: 16px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif; }
  main { max-width: 980px; margin: 0 auto; padding: 24px 16px 48px; }
  h1 { font-size: 1.7rem; margin: 0 0 4px; }
  .sub { color: var(--muted); margin: 0 0 20px; }
  form { display: flex; flex-wrap: wrap; gap: 8px; align-items: end; background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 14px; }
  label { display: flex; flex-direction: column; font-size: .85rem; color: var(--muted); gap: 4px; }
  input { font: inherit; padding: 8px 10px; border: 1px solid var(--line); border-radius: 6px; background: var(--bg); color: var(--fg); width: 150px; }
  button { font: inherit; padding: 9px 16px; border: 0; border-radius: 6px; background: var(--accent); color: var(--accent-fg); cursor: pointer; }
  #status { color: var(--muted); margin: 12px 0; min-height: 1.5em; }
  .wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: 10px; background: var(--card); }
  table { border-collapse: collapse; width: 100%; font-size: .9rem; }
  th, td { text-align: left; padding: 7px 10px; border-bottom: 1px solid var(--line); white-space: nowrap; }
  th { font-weight: 600; color: var(--muted); }
  td.n { text-align: right; font-variant-numeric: tabular-nums; }
  .cta { margin-top: 24px; padding: 16px; border-radius: 10px; border: 1px solid var(--accent); background: var(--card); }
  .cta a { color: var(--accent); font-weight: 600; }
  footer { margin-top: 28px; color: var(--muted); font-size: .8rem; }
  footer a { color: inherit; }
</style>


<!-- cm:studio-meta --><meta property="og:image" content="https://cybermax-tools-cybermax.static.hf.space/brand/zip-data-api/cover.png"><meta property="og:image:width" content="1200"><meta property="og:image:height" content="630"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:image" content="https://cybermax-tools-cybermax.static.hf.space/brand/zip-data-api/cover.png"><link rel="icon" type="image/png" href="https://cybermax-tools-cybermax.static.hf.space/brand/zip-data-api/icon.png"><!-- /cm:studio-meta -->
</head>
<body><!-- cybermax-bridge:start --><div style="max-width:960px;margin:8px auto;padding:8px 14px;border:1px solid rgba(127,127,127,.35);border-radius:10px;font:14px/1.5 system-ui,sans-serif"><b>Need it fresh, filtered or via API?</b> This demo shows a free snapshot, last updated 2026-09-27. <a href="https://data.cybermax-tools.workers.dev/buy/ziplore-api?s=sp-us-zip-codes-demographics" target="_blank" rel="noopener" style="color:inherit;font-weight:600">Ziplore ZIP code API</a> (200 free calls a day, then $19/month for 60,000) · <a href="https://data.cybermax-tools.workers.dev/buy/coffermap?s=sp-us-zip-codes-demographics" target="_blank" rel="noopener" style="color:inherit;font-weight:600">Coffermap FY2025 federal spending workbook</a> ($15) · <a href="https://data.cybermax-tools.workers.dev/notify?ds=us-zip-codes-demographics&s=sp-us-zip-codes-demographics" target="_blank" rel="noopener" style="color:inherit">email me when the data updates</a></div><!-- cybermax-bridge:end --><!-- cm:banner -->
<div style="display:flex;flex-wrap:wrap;align-items:center;gap:12px 16px;max-width:980px;margin:12px auto;padding:14px 16px;border-radius:14px;background:#0f172a;color:#f8fafc;font:15px/1.4 system-ui,-apple-system,Segoe UI,sans-serif;box-sizing:border-box">
<img src="https://cybermax-tools-cybermax.static.hf.space/icons/zip-data-api.png" alt="Ziplore" width="52" height="52" style="border-radius:12px;flex:none">
<div style="flex:1 1 240px;min-width:0"><div style="font-weight:700;font-size:17px">Ziplore: US ZIP codes to county, time zone and demographics</div>
<div style="color:#cbd5e1;font-size:14px">This page is a free sample. Run it on your own list: $0.0005 per ZIP returned, unknown ZIPs free (1,000 ZIPs = $0.50).</div></div>
<a href="https://console.apify.com/actors/YLNYOeeY6ngBM70Q1/input" style="flex:none;background:#38bdf8;color:#0f172a;font-weight:700;text-decoration:none;padding:10px 16px;border-radius:10px">&#9654; Try it with a prefilled input</a>
</div>
<!-- /cm:banner -->

<main>
  <h1>Ziplore: free US ZIP code lookup & radius search</h1>
  <p class="sub">City, county, time zone and Census demographics for any US ZIP code, and every ZIP within a radius. 41,682 ZIPs, all in your browser.</p>
  <form id="f">
    <label>ZIP code or "lat,lon" <input id="q" value="10001" autocomplete="postal-code"></label>
    <label>Radius (miles, 0 = just this ZIP) <input id="mi" type="number" min="0" max="100" step="1" value="2"></label>
    <label>Min. population <input id="minpop" type="number" min="0" step="100" value="0"></label>
    <button type="submit">Look up</button>
  </form>
  <div id="status">Loading ZIP table…</div>
  <div class="wrap"><table id="t"><thead><tr><th>ZIP</th><th>City</th><th>State</th><th>County</th><th>Miles</th><th>Time zone</th><th>Local time</th><th>Population</th><th>Median household income</th><th>Median home value</th><th>Median rent</th><th>Median age</th></tr></thead><tbody></tbody></table></div>
  <div class="cta">
    <strong>Need this for a whole list, inside a workflow, or for an AI agent?</strong>
    <a href="https://apify.com/cybermax/zip-data-api" target="_blank" rel="noopener">Run Ziplore on Apify</a>: send thousands of ZIPs, addresses, "City, ST" names or coordinates and get clean JSON with county FIPS, every county a ZIP touches, UTC offsets, per-capita income, owner-occupied share and nearby ZIPs. $0.0005 per ZIP, unknown ZIPs free, and it works as an MCP tool for Claude and Cursor.
    Bulk data: <a href="https://huggingface.co/datasets/CyberMax-tools/us-zip-codes-demographics" target="_blank" rel="noopener">free dataset (CSV)</a>.
  </div>
  <footer>
    Data: <a href="https://www.geonames.org/">GeoNames</a> (CC BY 4.0), US Census Bureau (2024 Gazetteer, ACS 2020–2024 5-year estimates), time zones from timezone-boundary-builder (ODbL, © OpenStreetMap contributors). Distances are between ZIP center points. Home values of $2,000,000 and incomes of $250,000 are Census caps ("or more"). Made by CyberMax. Not affiliated with USPS or the Census Bureau.
  </footer>
</main>
<script>
let rows = [], byZip = new Map();
const $ = (id) => document.getElementById(id);
const fmt = (v, pre = '') => v == null ? '–' : pre + Number(v).toLocaleString('en-US');
const esc = (s) => String(s ?? '').replace(/[&<>"]/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c]));
function miles(a, b, c, d) {
  const r = Math.PI / 180, x = Math.sin((c - a) * r / 2) ** 2 + Math.cos(a * r) * Math.cos(c * r) * Math.sin((d - b) * r / 2) ** 2;
  return 2 * 3958.7613 * Math.asin(Math.min(1, Math.sqrt(x)));
}
function localTime(tz) {
  if (!tz) return '–';
  try { return new Intl.DateTimeFormat('en-US', { timeZone: tz, hour: 'numeric', minute: '2-digit' }).format(new Date()); } catch { return '–'; }
}
function render(list) {
  $('t').tBodies[0].innerHTML = list.map(([d, r]) => `<tr><td>${esc(r.zip)}</td><td>${esc(r.city)}</td><td>${esc(r.state)}</td><td>${esc(r.county)}</td>
    <td class="n">${d == null ? '–' : d.toFixed(1)}</td><td>${esc(r.timezone || '–')}</td><td>${localTime(r.timezone)}</td><td class="n">${fmt(r.population)}</td>
    <td class="n">${fmt(r.medianHouseholdIncome, '$')}</td><td class="n">${fmt(r.medianHomeValue, '$')}</td><td class="n">${fmt(r.medianGrossRent, '$')}</td><td class="n">${r.medianAge ?? '–'}</td></tr>`).join('');
}
function run() {
  const q = $('q').value.trim(), mi = Math.min(Math.max(Number($('mi').value) || 0, 0), 100), minPop = Number($('minpop').value) || 0;
  let lat, lon, center;
  const pt = q.match(/^(-?\d+(?:\.\d+)?)\s*[,\s]\s*(-?\d+(?:\.\d+)?)$/);
  if (pt) { lat = +pt[1]; lon = +pt[2]; }
  else {
    const z = (q.match(/\d{5}/) || [q.replace(/\D/g, '').padStart(5, '0')])[0];
    center = byZip.get(z);
    if (!center) { $('status').textContent = `${z} isn't a US ZIP code in this table.`; render([]); return; }
    lat = center.latitude; lon = center.longitude;
  }
  let list;
  if (mi > 0 || !center) {
    list = rows.filter((r) => !['AA', 'AE', 'AP'].includes(r.state)).map((r) => [miles(lat, lon, r.latitude, r.longitude), r]);
    list = mi > 0 ? list.filter(([d]) => d <= mi) : [list.filter(([, r]) => r.hasZcta).sort((a, b) => a[0] - b[0])[0]].filter(Boolean);
    list = list.filter(([d, r]) => (r.population ?? 0) >= minPop || (center && r === center)).sort((a, b) => a[0] - b[0]);
  } else list = [[null, center]];
  const shown = list.slice(0, 300);
  $('status').textContent = mi > 0 ? `${list.length} ZIP code${list.length === 1 ? '' : 's'} within ${mi} miles${list.length > 300 ? ' (first 300 shown)' : ''}.` : (center ? '' : 'Nearest ZIP code to that point:');
  render(shown);
}
$('f').addEventListener('submit', (e) => { e.preventDefault(); run(); });
fetch('zips.json').then((r) => r.json()).then(({ cols, rows: raw }) => {
  rows = raw.map((a) => Object.fromEntries(cols.map((c, i) => [c, a[i]])));
  byZip = new Map(rows.map((r) => [r.zip, r]));
  $('status').textContent = '';
  run();
}).catch(() => { $('status').textContent = 'Could not load the ZIP table. Reload the page.'; });
</script>
<!-- cybermax-more:start --><div style="max-width:960px;margin:24px auto 32px;padding:12px 0;border-top:1px solid rgba(127,127,127,.3);font-size:14px;line-height:1.6"><b>Coming soon:</b> the Ziplore API (look up any ZIP code, radius search and demographics via API) is launching on the Apify Store; see <a href="https://apify.com/cybermax" target="_blank" rel="noopener" style="color:inherit">CyberMax on Apify</a> for the live tools.<br><b>More free from CyberMax:</b> <a href="https://huggingface.co/spaces/CyberMax-tools/cybermax" target="_blank" rel="noopener" style="color:inherit">All free CyberMax demos &amp; datasets</a> · <a href="https://huggingface.co/spaces/CyberMax-tools/batch-geocoder-demo" target="_blank" rel="noopener" style="color:inherit">Pinloft: Batch Geocoder with Census FIPS & Districts</a> · <a href="https://huggingface.co/spaces/CyberMax-tools/company-name-to-domain" target="_blank" rel="noopener" style="color:inherit">Namewhere: Company Name to Domain Finder</a> · <a href="https://huggingface.co/datasets/CyberMax-tools/us-zip-codes-demographics" target="_blank" rel="noopener" style="color:inherit">Ziplore US ZIP Codes with Census Demographics (41,682 ZIPs) (free dataset)</a> · <a href="https://huggingface.co/datasets/CyberMax-tools/fipsbook-us-census-geographies" target="_blank" rel="noopener" style="color:inherit">Fipsbook: US Census Geographies with FIPS Codes, Centroids & Land Area (2025) (free dataset)</a></div><!-- cybermax-more:end -->
<!-- cybermax-count:start --><script>(function(){try{var u="https://data.cybermax-tools.workers.dev/v?p="+encodeURIComponent(location.host+location.pathname)+"&r="+encodeURIComponent((document.referrer||"").split("/")[2]||"")+(function(){var q=new URLSearchParams(location.search),s=q.get("utm_source");return s?"&us="+encodeURIComponent(s)+"&uc="+encodeURIComponent(q.get("utm_campaign")||""):""})();navigator.sendBeacon?navigator.sendBeacon(u):(new Image).src=u}catch(e){}})()</script><!-- cybermax-count:end --></body>
</html>