A stolen password can look just like a real one at login. The credentials match, but that does not mean the account owner is the person signing in.
The clue can be the location. Every login includes an IP address, and an IP address lookup api can turn it into coordinates and a timestamp. You can then compare the new login with the user’s previous session.
If two logins are 12,000 km apart but only 39 minutes apart, the travel is clearly impossible. This is called impossible travel detection and is a simple IP Lookup signal for spotting suspicious logins and possible account takeovers.
Key Takeaways
- Impossible travel compares two logins on the same account and checks if the travel speed is physically possible.
- An ip address lookup api provides the latitude, longitude, and timestamp needed for the check.
- City-level accuracy is usually enough because the check looks at large distances, not exact addresses.
- Speed thresholds should allow for mobile networks, VPNs, and shared corporate networks to avoid false alerts.
- The signal works best with connection data, and suspicious logins are usually better handled with step-up authentication instead of an immediate block.
The Signal in One Sentence and a Real-Shaped Example
The idea is simple: compare the distance between two consecutive logins with the time between them. If the required travel speed is impossible, one of the sessions may not belong to the account owner.
For example, an account signs in from Lisbon at 09:12 UTC and then from Manila at 09:51 UTC. The locations are about 12,000 km apart, with only 39 minutes between logins. That would require a speed of roughly 18,400 km/h. A commercial aircraft typically cruises at around 900 km/h, making the difference obvious.
Credential theft is a real problem. In a public service announcement dated 25 November 2025, the FBI Internet Crime Complaint Center reported more than 5,100 account takeover complaints filed since January 2025, with losses above $262 million (FBI IC3, Alert I-112525-PSA).
Passwords can be stolen, so the useful question is what a valid login reveals after the password check passes.
That answer starts with the information the login request already carries.
How an IP Address Lookup API Turns a Login Into Coordinates
A raw IP address does not tell you how far someone has travelled. You first need to map it to a location. An IP address lookup api can do this using a few useful fields:
- latitude and longitude: Used to calculate the distance between two logins.
- city, region, country_code: Provide readable location details for security alerts.
- connection type: Helps distinguish mobile, broadband, and hosting connections.
- ASN and organisation: Show which network operator is behind the IP address.
You can make one lookup for each login event:
| GET <https://api.ipstack.com/{ip_address}> |
The API returns the location and connection details, which you can store with the session and compare with the previous login. A real-time IP lookup API can fit into this flow when you need the lookup result during authentication.
Two questions usually come next: how accurate are those coordinates, and how fresh does the data need to be?
IP to Coordinates: What Precision You Actually Get
IP to coordinates usually gives you an approximate city-level location, not an exact street address. The returned point may be near the centre of a city or a service area, while the actual user could be several kilometres away. Mobile networks can be less precise because the IP may point to a carrier gateway.
For impossible travel detection, this level of accuracy is usually enough. The goal is to detect a huge distance in a short time, not small movements within a city.
A 40 km error makes little difference when two logins are 12,000 km apart. That is why it is useful to set a minimum distance before applying an impossible travel rule.
Why Real-Time Lookups Beat Nightly Database Syncs for Login Checks
Fresh data matters when you are checking logins. IP assignments can change, mobile carriers can rotate addresses, and cloud providers can reassign IP ranges.
A database that updates once a day may not have the latest information. A real-time ip lookup api checks the IP when the login happens, giving you current location and connection details.
It can also provide useful information about proxies, hosting providers, or other network types. This extra context can help you tell the difference between a normal login and a suspicious one.
With fresh location data, the maths is simple.
Computing Impossible Travel: Haversine Distance Over Time Delta
The Haversine formula calculates the distance between two points on Earth. For impossible travel detection, you can use it to compare the locations of two logins:
| def great_circle_km(lat1, lon1, lat2, lon2): R = 6371 # Earth radius in km dlat = radians(lat2 – lat1) dlon = radians(lon2 – lon1) a = sin(dlat / 2) ** 2 + cos(radians(lat1)) * cos(radians(lat2)) * sin(dlon / 2) ** 2 return 2 * R * asin(sqrt(a)) |
Then calculate the travel speed using the distance and the time between the two logins:
| MIN_GAP_HOURS = 0.05 # 3 minutes, protects against clock noise GEO_SLACK_KM = 150 # absorbs city-level estimation error def implied_speed_kmh(previous, current): hours = (current.seen_at – previous.seen_at) / 3600 if hours <= MIN_GAP_HOURS: return UNKNOWN # too close to measure, score separately km = great_circle_km( previous.lat, previous.lon, current.lat, current.lon ) if km < GEO_SLACK_KM: return 0 # same metro area, no travel claim return km / hours |
The result is a speed in km/h, which makes the rule easy to understand. A speed below 900 km/h can be possible by air. Between 900 and 1,500 km/h is more suspicious and should be checked with other signals. Above 1,500 km/h is a strong impossible-travel signal.
The numbers look simple on paper, but real-world traffic is usually more complicated.
Thresholds and False Positives: Carriers, VPNs and Corporate Egress
Some normal network changes can look like impossible travel. Four common examples are:
- Mobile carrier gateways: A phone may switch between gateways that are hundreds of kilometres apart while the user stays in the same place.
- VPN toggles: A VPN can change the visible IP location to another country and then disappear a few minutes later.
- Corporate egress: Employees may share the same company network, making office and home logins look like large location jumps.
- Dual-stack and relayed traffic: IPv4 and IPv6 connections can sometimes resolve to different locations for the same user.
A few simple rules can reduce false positives. Compare consecutive successful logins instead of every request. Keep a short history of recent session locations, so repeated travel between known places is easier to recognise. Most importantly, treat IP fraud detection as one signal among several, not as a reason to block an account on its own.
Fraud IP Patterns vs Legitimate Travellers
A real traveller will usually connect through a residential or mobile network after reaching a new location. A fraud IP is more likely to come from a data centre, hosting provider, or proxy network.
That makes IP fraud detection stronger when you combine multiple signals. For example, impossible travel plus a data-centre ASN is more useful than either signal alone.
Other signals can also increase confidence, such as a new device, a password or email change during the same session, or several accounts connecting through the same ASN within a short time.
Once the signals point to a likely account takeover, the next question is what action your system should take.
Escalation Design: Step-Up Auth, Not Hard Blocks
A hard block can create problems when the location data is only an estimate. A better approach is to add more security checks as the risk increases:
- Low risk: Allow the login and save the location data for future comparisons.
- Medium risk: Allow the login, but require extra verification before sensitive actions such as a payout or changing bank details.
- High risk: Hold the session, require a second factor, and notify the account owner through a separate channel.
Do not explain the exact detection rules in user-facing messages. Attackers could use that information to adjust their attempts. Also record the results of each challenge so you can see whether your thresholds are creating too many false positives.
This works best when IP Intelligence is combined with other security signals instead of being used on its own.
Where Impossible Travel Fits in IP Address Fraud Prevention
IP address fraud prevention works best in layers, with each layer answering a different question.
| Layer | Question it answers | Typical inputs |
| Network | Where is the session coming from? | Coordinates, ASN, connection type |
| Device | Have we seen this device before? | Fingerprint, OS, app version |
| Behaviour | Does the session behave like the account owner? | Typing patterns, navigation |
| Velocity | How often does this identity appear? | Attempts per hour, accounts per IP |
Impossible travel belongs to the network layer. It is a useful trigger, not a final verdict. It is simple to calculate, does not need model training, and adds useful information to a login record.
As part of a wider IP fraud detection system, it can increase the risk score when a login needs a closer look. Other signals can then help decide what happens next.
Here is what that can look like in code.
Reference Implementation Sketch
A minimal version can fit into an existing login handler:
| import math import requests API_BASE = “<https://api.ipstack.com>” MIN_GAP_HOURS = 0.05 GEO_SLACK_KM = 150 REVIEW_KMH = 900 IMPOSSIBLE_KMH = 1500 def locate(ip_address, access_key): response = requests.get( f”{API_BASE}/{ip_address}“, params={“access_key”: access_key}, timeout=2, ) response.raise_for_status() return response.json() def great_circle_km(lat1, lon1, lat2, lon2): radius = 6371 dlat = math.radians(lat2 – lat1) dlon = math.radians(lon2 – lon1) a = ( math.sin(dlat / 2) ** 2 + math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) * math.sin(dlon / 2) ** 2 ) return 2 * radius * math.asin(math.sqrt(a)) def travel_verdict(previous, current): hours = (current[“seen_at”] – previous[“seen_at”]) / 3600 if hours <= MIN_GAP_HOURS: return “unscored” km = great_circle_km( previous[“latitude”], previous[“longitude”], current[“latitude”], current[“longitude”], ) if km < GEO_SLACK_KM: return “normal” speed = km / hours if speed >= IMPOSSIBLE_KMH: return “impossible” if speed >= REVIEW_KMH: return “review” return “normal” def score_login(user_id, ip_address, seen_at, access_key, store): geo = locate(ip_address, access_key) current = { “latitude”: geo[“latitude”], “longitude”: geo[“longitude”], “seen_at”: seen_at, } previous = store.last_login(user_id) store.save_login(user_id, current) if previous is None: return “baseline” return travel_verdict(previous, current) |
The short timeout is intentional. A login should not wait too long for an external API call. If the lookup is slow or fails, fall back to unscored. The first login on an account should also be treated as the baseline for future comparisons.
Conclusion
Impossible travel is a simple check with a useful security benefit. Two coordinates, two timestamps, and a speed calculation can turn a normal-looking login into a signal worth checking.
The hard part is not the formula. It is choosing sensible thresholds, allowing for mobile and VPN traffic, and deciding when to challenge a user instead of blocking them.
The quality of the input also matters. Location data needs to be fast enough for the login flow and fresh enough to reflect the current network. That is where a service such as ipstack can help, providing latitude, longitude, and connection details from an IP lookup api call.
FAQ
What speed threshold should impossible travel detection use?
A good starting point is 900 km/h for review and 1,500 km/h for a strong flag. Then adjust these thresholds based on your own traffic. If you have many mobile users, you may need a higher review threshold because carrier gateways can create large location jumps.
Does a VPN trigger impossible travel alerts?
Yes. Turning a VPN on or off can instantly change the apparent IP location, creating an impossible travel alert. Check the connection type and ASN along with the speed. A VPN location the account has used before is a weaker signal. A sudden jump to an unfamiliar hosting network, especially during a password change, is more suspicious and may justify an extra verification step.