Working code for browser fetch(), Node.js, async/await, and error handling.
Get a free API key and be making live requests in under 5 minutes.
The ZipCodesToGo ZIP Code API is a simple REST API — you send a GET request with your API key in a header and get back a JSON object with city, state, county, lat/lng, and timezone. Here's the minimal browser example:
const API_KEY = 'zcg_your_key_here'; const zip = '90210'; const response = await fetch( `https://api.zipcodestogo.com/v1/zip/${zip}`, { headers: { 'X-Api-Key': API_KEY } } ); const data = await response.json(); console.log(data.data.city); // "Beverly Hills" console.log(data.data.state); // "CA" console.log(data.data.lat); // 34.0901 console.log(data.data.timezone);// "America/Los_Angeles"
const API_KEY = 'zcg_your_key_here'; const API_BASE = 'https://api.zipcodestogo.com/v1'; async function lookupZip(zip) { if (!/^\d{5}$/.test(zip)) { throw new Error('ZIP code must be exactly 5 digits'); } const res = await fetch(`${API_BASE}/zip/${zip}`, { headers: { 'X-Api-Key': API_KEY } }); if (res.status === 404) throw new Error(`ZIP ${zip} not found`); if (res.status === 401) throw new Error('Invalid API key'); if (res.status === 429) throw new Error('Rate limit reached — upgrade plan'); if (!res.ok) throw new Error(`API error: ${res.status}`); const { data } = await res.json(); return data; // { city, state, county, lat, lng, timezone } } // Usage try { const location = await lookupZip('10001'); console.log(`${location.city}, ${location.state}`); // "New York, NY" } catch (err) { console.error('ZIP lookup failed:', err.message); }
// Auto-fill city/state when user enters a valid ZIP const zipInput = document.getElementById('zip'); const cityInput = document.getElementById('city'); const stateInput = document.getElementById('state'); const zipError = document.getElementById('zip-error'); zipInput.addEventListener('blur', async () => { const zip = zipInput.value.trim(); if (zip.length !== 5) return; try { const res = await fetch( `https://api.zipcodestogo.com/v1/zip/${zip}`, { headers: { 'X-Api-Key': 'zcg_your_key_here' } } ); if (!res.ok) throw new Error(); const { data } = await res.json(); cityInput.value = data.city; stateInput.value = data.state; zipError.textContent = ''; } catch { zipError.textContent = 'ZIP code not found. Please check and try again.'; cityInput.value = stateInput.value = ''; } });
// Node.js 18+ has fetch built-in. For older Node use node-fetch. const API_KEY = process.env.ZIP_API_KEY; // store in env, not code export async function getZipData(zip) { const res = await fetch( `https://api.zipcodestogo.com/v1/zip/${zip}`, { headers: { 'X-Api-Key': API_KEY } } ); if (!res.ok) throw new Error(`ZIP lookup failed: ${res.status}`); const { data } = await res.json(); return data; } // Example: Express route // app.get('/api/location', async (req, res) => { // const data = await getZipData(req.query.zip); // res.json(data); // });
Every request needs your API key in the X-Api-Key header. Never put your key directly in client-side JavaScript that ships to users — proxy requests through your backend instead, or use the free tier for read-only public tools where exposure risk is acceptable.
Go to zipcodestogo.com/api/, click your plan, and enter your email. Your key is issued immediately — no approval process. The free tier gives you 100 calls/day and doesn't require a credit card.
Store your key in an environment variable and load it with process.env.ZIP_API_KEY. Never commit keys to version control. Use a .env file locally with a package like dotenv.
{
"zip": "90210",
"data": {
"city": "Beverly Hills", // string
"state": "CA", // 2-letter abbreviation
"county": "Los Angeles", // county name (no "County")
"lat": 34.0901, // float, degrees
"lng": -118.4065, // float, degrees
"timezone": "America/Los_Angeles" // IANA tz (Pro+)
}
}
| Status | Meaning | How to handle in JS |
|---|---|---|
200 | Success — ZIP found | Parse data object normally |
404 | ZIP code not found | Show "invalid ZIP" message to user |
401 | Missing or invalid API key | Check your X-Api-Key header |
429 | Daily rate limit reached | Show retry message or upgrade plan |
500 | Server error | Retry with exponential backoff |