Compare a login location with the previous stored location
A large change in IP-derived location over a short interval can warrant review. POST /v1/risk/check compares a user's current location estimate with the previous stored point and returns distance, elapsed time, implied speed, and a risk classification.
Availability
This endpoint uses the same secret key as IP lookup — there's no separate risk plan, signup, or price. Every check counts as one request against your existing plan's monthly cap, the same pool GET /v1/geo and /v1/lookup* draw from.
Input and secret-key usage
Send a JSON body of userId, ip, and an optional commit boolean (defaults to true) to POST /v1/risk/check with a secret key via Authorization: Bearer YOUR_SECRET_KEY — server-to-server only, never from a browser.
The first observation
A user's first-ever check has no previous location to compare against: it returns risk: "low", impossibleTravel: false, null distance/speed/elapsed values, and a null previousLocation, and — if commit isn't false — stores this observation as the new baseline.
Subsequent observations
Later checks compare the great-circle distance between the previous and current point against the elapsed time to get an implied speed. Below 500 km/h, the result is "low"; between 500 and 900 km/h, "medium" (a real long-haul flight can land near this boundary); above 900 km/h, "high" and impossibleTravel: true.
The commit flag
commit defaults to true. Set it false for a speculative pre-check — for example, ahead of a step-up-authentication decision — that reads the stored baseline without moving it, so a legitimate check doesn't corrupt the user's real location history.
Missing locations
If ip can't be resolved to a latitude/longitude, the endpoint returns a 422 rather than a low-confidence guess.
Retention and deletion
v1 stores exactly one location per (your account, userId) pair — the most recent committed observation — with no automatic expiry; it persists until the next committed check overwrites it, or you delete it yourself with DELETE /v1/risk/baseline (same secret key, doesn't count against your monthly cap). Because it stores a userId-linked location beyond a single request/response cycle, using this endpoint makes Watch-IP a processor of that data on your behalf — see the Data Processing Addendum.
False positives
v1 has no VPN- or datacenter-aware suppression, so fast VPN toggling or ordinary mobile-network IP churn can produce an elevated result. Treat every classification as a raw signal for your own review process, not a final verdict.
Response fields
- risk
- low, medium, or high, from the implied-speed thresholds above.
- impossibleTravel
- Boolean shorthand for risk: "high".
- distanceKm, impliedSpeedKmh, elapsedSeconds
- The distance and time between the previous and current observation, and the speed that implies. Null on a user's first-ever check.
- previousLocation
- country, latitude, longitude, and observedAt for the stored baseline before this call. Null on a user's first-ever check.
- currentLocation
- country, latitude, and longitude resolved from the ip you supplied on this call.
Pre-check, then commit
Backend cURL
# Speculative check ahead of your own auth decision — doesn't move the baseline.
curl https://api.watch-ip.com/v1/risk/check \
-H "Authorization: Bearer YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"userId": "u_123", "ip": "203.0.113.1", "commit": false}'
# After your own password/2FA verification succeeds, commit the new baseline.
curl https://api.watch-ip.com/v1/risk/check \
-H "Authorization: Bearer YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"userId": "u_123", "ip": "203.0.113.1"}'commit defaults to true, so the second call above updates the stored baseline; the first, with commit: false, does not.
Frequently asked questions
What happens on the first check?
It always returns risk: "low" with a null previousLocation — there's nothing yet to compare the current location against.
Does it suppress VPN jumps?
No. v1 has no VPN- or datacenter-aware suppression, so switching networks or VPN exits between logins can produce a medium or high result on its own.
Is a high result proof of compromise?
No. It's a raw distance-over-time calculation. Combine it with your own authentication evidence rather than treating it as a standalone verdict.
Can I avoid updating the baseline?
Yes — pass commit: false. The check still runs and returns a result, but the stored location isn't replaced.
How long is the previous location retained?
Indefinitely, until the next committed check for that userId overwrites it — there's no automatic expiry and no delete endpoint in the current implementation.
Related pages
- POST /v1/risk/check referenceFull field reference for the impossible-travel detection endpoint.
- Login risk detectionUse IP-derived location changes to inform login review.
- ContactReach Watch-IP support or sales.
- Impossible travel false positivesWhy a high impossible-travel score isn't proof of account takeover.