If you target proxies by city, you will eventually look up an exit IP and get two different answers.
Here is one we saw this week. Same IP, same carrier (T-Mobile USA, AS21928), checked a few minutes apart:
- ipinfo: Fort Worth, Texas
- ip-api: Chicago, Illinois
That is not a typo in either database. Mobile carrier IPs are hard to place. Traffic from many phones leaves through a small number of carrier gateways, and the address pool behind those gateways gets reassigned across regions. Each database makes its own guess from its own signals, so they often land on different cities. Fixed broadband IPs (cable, fiber, DSL) usually agree much more closely.
What to check instead of one lookup
- Ask two databases, not one. If both name the same city, you can trust it. If they disagree, you know the city is uncertain, which is still useful to know.
-
Look at the ASN and the mobile flag. If the ASN is a mobile carrier, or the lookup says
mobile: true, treat the city as approximate and plan for region-level accuracy. - Check the exit, not the label. Whatever your proxy username asks for, verify the IP you actually got from the place you will use it.
A small script
import json, sys, urllib.request
def get(url):
with urllib.request.urlopen(url, timeout=10) as r:
return json.load(r)
def check(ip):
a = get(f"http://ip-api.com/json/{ip}?fields=countryCode,regionName,city,isp,as,mobile,proxy,hosting")
b = get(f"https://ipinfo.io/{ip}/json")
same_city = (a.get("city") or "").lower() == (b.get("city") or "").lower()
print(f"ip-api : {a.get('city')}, {a.get('regionName')} ({a.get('as')}) mobile={a.get('mobile')}")
print(f"ipinfo : {b.get('city')}, {b.get('region')} ({b.get('org')})")
print("city agrees" if same_city else "city DISAGREES: treat it as region-level only")
if __name__ == "__main__":
# Pass an IP, or leave it empty to check the exit you are using right now
ip = sys.argv[1] if len(sys.argv) > 1 else get("https://api.ipify.org?format=json")["ip"]
check(ip)
Run it through your proxy (for example with HTTPS_PROXY set) and it checks the exit you are actually using. Both services have free tiers with rate limits, which is fine for spot checks but not for every request.
Takeaway
City targeting is a request, not a guarantee, and the answer depends on whose database you ask. For mobile IPs, check two sources and trust the region more than the city.
Written by the team at Roam (roamproxy.com), where we run residential and static proxies and check exits this way ourselves.

Top comments (0)