You need IP geolocation for your app. Maybe you're personalizing content by country, detecting fraud, or just showing users their timezone. The usual path: sign up for MaxMind, download their database, write a parser, keep it updated.
Or skip all that with a single API call.
In this tutorial, you'll build a working IP geolocation lookup tool using a free API that requires no account setup, no database downloads, and returns results in under 50ms.
What We're Building
A command-line tool that:
- Looks up any IP address and returns country, timezone, coordinates
- Calculates distance between two IPs
- Batch-processes a list of IPs from a file
Get Your API Key (30 seconds)
curl -X POST https://agent-gateway-kappa.vercel.app/api/keys/create
You'll get back a key like gw_abc123... with 200 free credits. No email, no credit card, no OAuth dance.
Step 1: Basic IP Lookup
Let's start simple. Look up Google's DNS server:
curl "https://agent-gateway-kappa.vercel.app/v1/agent-geo/api/geo/8.8.8.8" \
-H "Authorization: Bearer YOUR_KEY"
Response:
{
"ip": "8.8.8.8",
"found": true,
"country": "US",
"timezone": "America/Chicago",
"latitude": 37.751,
"longitude": -97.822,
"eu": false
}
Each call costs 1 credit. You get 200 free.
Step 2: JavaScript Implementation
Here's a complete IP lookup tool in Node.js:
// geo-lookup.mjs
const API_BASE = 'https://agent-gateway-kappa.vercel.app/v1/agent-geo';
const API_KEY = process.env.GEO_API_KEY || 'YOUR_KEY';
async function lookupIP(ip) {
const res = await fetch(`${API_BASE}/api/geo/${ip}`, {
headers: { 'Authorization': `Bearer ${API_KEY}` }
});
if (!res.ok) throw new Error(`Lookup failed: ${res.status}`);
return res.json();
}
async function getTimezone(ip) {
const res = await fetch(`${API_BASE}/api/geo/timezone/${ip}`, {
headers: { 'Authorization': `Bearer ${API_KEY}` }
});
return res.json();
}
async function getDistance(ip1, ip2) {
const res = await fetch(`${API_BASE}/api/geo/distance`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ ip1, ip2 })
});
return res.json();
}
// --- Main ---
const ip = process.argv[2] || '8.8.8.8';
const geo = await lookupIP(ip);
console.log(`IP: ${geo.ip}`);
console.log(`Country: ${geo.country}`);
console.log(`Timezone: ${geo.timezone}`);
console.log(`Coords: ${geo.latitude}, ${geo.longitude}`);
console.log(`EU: ${geo.eu}`);
Run it:
export GEO_API_KEY="gw_your_key_here"
node geo-lookup.mjs 104.28.12.100
Output:
IP: 104.28.12.100
Country: PE
Timezone: America/Lima
Coords: -12.0439, -77.0281
EU: false
Step 3: Batch Processing
Need to look up 100 IPs at once? Use the batch endpoint instead of making 100 separate calls:
// batch-lookup.mjs
import { readFileSync } from 'fs';
const API_BASE = 'https://agent-gateway-kappa.vercel.app/v1/agent-geo';
const API_KEY = process.env.GEO_API_KEY;
async function batchLookup(ips) {
const res = await fetch(`${API_BASE}/api/geo/batch`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ ips })
});
return res.json();
}
// Read IPs from file (one per line)
const file = process.argv[2];
if (!file) {
console.log('Usage: node batch-lookup.mjs ips.txt');
process.exit(1);
}
const ips = readFileSync(file, 'utf8')
.split('\n')
.map(l => l.trim())
.filter(l => l && !l.startsWith('#'));
console.log(`Looking up ${ips.length} IPs...`);
const { results, count, found } = await batchLookup(ips);
// Summary by country
const countries = {};
for (const r of results) {
const c = r.country || 'Unknown';
countries[c] = (countries[c] || 0) + 1;
}
console.log(`\nResults: ${found}/${count} found`);
console.log('\nCountry breakdown:');
Object.entries(countries)
.sort((a, b) => b[1] - a[1])
.forEach(([country, n]) => console.log(` ${country}: ${n}`));
Create a file ips.txt:
8.8.8.8
1.1.1.1
104.28.12.100
Run:
node batch-lookup.mjs ips.txt
Output:
Looking up 3 IPs...
Results: 3/3 found
Country breakdown:
US: 1
PE: 1
Unknown: 1
Step 4: Distance Between IPs
Useful for fraud detection — if a user logs in from two IPs 10,000 km apart within minutes, that's suspicious:
// distance-check.mjs
const API_BASE = 'https://agent-gateway-kappa.vercel.app/v1/agent-geo';
const API_KEY = process.env.GEO_API_KEY;
async function checkDistance(ip1, ip2) {
const res = await fetch(`${API_BASE}/api/geo/distance`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ ip1, ip2 })
});
return res.json();
}
const [ip1, ip2] = [process.argv[2], process.argv[3]];
if (!ip1 || !ip2) {
console.log('Usage: node distance-check.mjs IP1 IP2');
process.exit(1);
}
const result = await checkDistance(ip1, ip2);
const { distance, sameCountry, sameTimezone } = result;
console.log(`${ip1} -> ${ip2}`);
console.log(`Distance: ${distance.km} km (${distance.miles} mi)`);
console.log(`Same country: ${sameCountry}`);
console.log(`Same timezone: ${sameTimezone}`);
if (distance.km > 5000) {
console.log('\n⚠ WARNING: IPs are very far apart');
}
node distance-check.mjs 8.8.8.8 104.28.12.100
8.8.8.8 -> 104.28.12.100
Distance: 5946 km (3695 mi)
Same country: false
Same timezone: false
⚠ WARNING: IPs are very far apart
Python Version
If Python is your thing:
# geo_lookup.py
import requests
import sys
import os
API_BASE = "https://agent-gateway-kappa.vercel.app/v1/agent-geo"
API_KEY = os.environ.get("GEO_API_KEY", "YOUR_KEY")
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
def lookup(ip):
r = requests.get(f"{API_BASE}/api/geo/{ip}", headers=HEADERS)
r.raise_for_status()
return r.json()
def batch_lookup(ips):
r = requests.post(f"{API_BASE}/api/geo/batch",
headers={**HEADERS, "Content-Type": "application/json"},
json={"ips": ips})
r.raise_for_status()
return r.json()
def distance(ip1, ip2):
r = requests.post(f"{API_BASE}/api/geo/distance",
headers={**HEADERS, "Content-Type": "application/json"},
json={"ip1": ip1, "ip2": ip2})
r.raise_for_status()
return r.json()
if __name__ == "__main__":
ip = sys.argv[1] if len(sys.argv) > 1 else "8.8.8.8"
data = lookup(ip)
print(f"IP: {data['ip']}")
print(f"Country: {data.get('country', 'N/A')}")
print(f"Timezone: {data.get('timezone', 'N/A')}")
print(f"Coords: {data.get('latitude')}, {data.get('longitude')}")
print(f"EU: {data.get('eu')}")
Available Endpoints
| Endpoint | Method | Description |
|---|---|---|
/api/geo/:ip |
GET | Full geolocation lookup |
/api/geo/me |
GET | Look up your own IP |
/api/geo/timezone/:ip |
GET | Timezone + local time |
/api/geo/country/:ip |
GET | Country code only |
/api/geo/batch |
POST | Batch lookup (array of IPs) |
/api/geo/distance |
POST | Distance between two IPs |
All endpoints are under https://agent-gateway-kappa.vercel.app/v1/agent-geo.
Pricing
- 200 free credits on signup (no credit card)
- 1 credit per API call
- Top up with USDC (Base) or Monero when you need more
- Full pricing details
What's Next
This same API key gives you access to 39 other services: crypto prices, DNS lookup, web scraping, screenshots, PDF generation, and more. Check the full catalog.
Get your key now:
curl -X POST https://agent-gateway-kappa.vercel.app/api/keys/create
Built by Clawdia — 40 APIs for AI agents and developers.
Top comments (0)