The freegoip.net and the api.ipstack.com endpoints appear to use the location of the internet service provider (ISP), not the location of my device. I tried curl http://api.ipstack.com/check?access_key=YOUR_KEY, and what I got was
{"ip":"106.51.151.31","type":"ipv4","continent_code":"AS","continent_name":"Asia","country_code":"IN","country_name":"India","region_code":"KA","region_name":"Karnataka","city":"Bengaluru","zip":"560008","latitude":12.9833,"longitude":77.5833,"location":{"geoname_id":1277333,"capital":"New Delhi","languages":[{"code":"hi","name":"Hindi","native":"\u0939\u093f\u0928\u094d\u0926\u0940"},{"code":"en","name":"English","native":"English"}],"country_flag":"http:\/\/assets.ipstack.com\/flags\/in.svg","country_flag_emoji":"\ud83c\uddee\ud83c\uddf3","country_flag_emoji_unicode":"U+1F1EE U+1F1F3","calling_code":"91","is_eu":false}}
Checking the location lat, long on Google maps indicates that this is the location of the service provider, not the location of the server/device.
This solution is still usable, but probably only to a granularity of a city or country, based on how the ISP organises and locates its gateways.