When a request is blocked, a model refuses a prompt, or a "login from a new country" email fires, the first question is usually "what address did they see?" The address printed on your laptop is often the wrong answer. 192.168.1.1 and 10.0.0.1 are private; they are reused on every LAN in the world and are never routed on the public internet. What a remote service sees is the public egress of your NAT, VPN, office gateway, or CI runner.

IP99 by ThreatHunter has a no-key call for exactly that: GET /v1/ip with no address in the path. It returns the caller's public IP plus the same risk, network, and geolocation profile you get when you look up someone else. The HTML version lives at What is my IP address?. This walkthrough uses the free profile only. JSON samples were verified on 15 November 2026 UTC. Notes: IP99, API, What is my IP.

The one-line lookup

curl https://ip99.com/v1/ip 

No API key, no registration. The path is /v1/ip, not /v1/ip/{ip}. The response shape matches a normal lookup: ip, computed_at, evidence_state, risk, network, geo.

A real call from this article's publishing environment on 15 November 2026 UTC (computed_at 2026-11-15T13:14:21Z):

{ "ip": "104.28.245.205", "computed_at": "2026-11-15T13:14:21Z", "evidence_state": "none", "geo": { "continent": "AS", "country": "CN", "region": "Henan", "city": "Zhengzhou", "district": "", "lat": 34.75798, "lon": 113.66541, "tz": "Asia/Shanghai" }, "network": { "asn": 13335, "usage_type": "IDC" }, "risk": { "score": 0, "level": "none", "signals": ["hosting"] } } 

The internet did not see a laptop's RFC1918 address. It saw a Cloudflare (AS13335) datacenter exit. usage_type: "IDC" and signals: ["hosting"] describe the network scene, not a fraud verdict — official guidance is not to block on hosting or mobile alone. Score 0 with evidence_state: "none" means IP99 holds no current risk evidence for this address, not that the address is safe. risk.score is the freshness and strength of verifiable evidence, not a probability that someone is an attacker. geo placed the block in Zhengzhou; for anycast and carrier ranges, city-level geo is often a point of presence, not a building. An empty district is a missing place name, not a zero. The same response arrived with Access-Control-Allow-Origin: *, x-daily-limit: 500, x-ratelimit-limit: 60, and x-plan: anon.

Look up any other address the same way

Once you know the egress, compare it with a well-known resolver, a customer address, or a previous snapshot:

curl https://ip99.com/v1/ip/8.8.8.8 

Verified the same day (computed_at 2026-11-15T13:14:23Z):

{ "ip": "8.8.8.8", "computed_at": "2026-11-15T13:14:23Z", "evidence_state": "none", "geo": { "continent": "NA", "country": "US", "region": "California", "city": "Mountain View", "tz": "America/Los_Angeles" }, "network": { "asn": 15169, "usage_type": "IDC" }, "risk": { "score": 0, "level": "none", "signals": ["hosting"] } } 

Same shape, same reading rules. hosting is here because the usage type is IDC, not because Google Public DNS is a proxy. The API treats the address as a required path parameter when you pass one: private and reserved ranges return 400 reserved_ip; a malformed value returns 400 invalid_ip. Free /v1/ip answers for now only; passing ?at= is 400 at_unsupported.

Private addresses have no public profile

If you paste the address from ip addr or ipconfig into a public lookup, you often get an error, not a "clean" score:

curl https://ip99.com/v1/ip/192.168.1.1 curl https://ip99.com/v1/ip/10.0.0.1 curl https://ip99.com/v1/ip/127.0.0.1 curl https://ip99.com/v1/ip/169.254.1.1 

Verified 15 November 2026 UTC, all four returned HTTP 400:

{"error":{"code":"reserved_ip","message":"private or reserved address has no public risk profile"}} 

::1 does the same. Official docs: branch on error.code, never on error.message — the message is prose for humans and its wording may change. These ranges are not on the public internet, so there is no public risk profile to return. The useful move is the no-path call: ask IP99 which address it actually received.

The exit is not always "you"

A few cases change the address, or change what it means, without anything being "wrong":

  • A VPN or proxy replaces the egress. While one is active, the lookup reports the exit's network and country, not your access line. That is usually why two "what is my IP" tabs disagree after you toggle a client.
  • Most home and mobile connections get an address by DHCP. A router reboot, a lease expiry, or a carrier re-addressing can move it. Query at decision time; do not cache a verdict overnight and treat it as still true.
  • IPv4 and IPv6 can disagree. A dual-stack connection has both, and a site may see whichever its DNS prefers. If two services report different addresses, check which protocol each one used.
  • Shared egress is normal. Carrier-grade NAT and some apartment or guest networks put many subscribers behind one public address (usage_type is often GTW). The address identifies a connection, not a person — official guidance is to step up (captcha, second factor, review), not to hard-ban a building.

IP geolocation is a separate database from the address itself. It cannot name a person, an account, or a street number. City-level accuracy is the realistic case for consumer addresses; a result that points at an ISP regional office or a CDN PoP is expected, not a fault. See how IP location works.

Why bother looking at your own exit

The same call is useful before you debug someone else's:

  • A CI runner, cloud function, or shared office gateway often sits on IDC / hosting space. If a vendor flags "datacenter," the no-path lookup tells you whether that is actually your pipeline's egress.
  • Before you assume a geo or risk decision is a false positive, confirm the address the remote side received — especially if a VPN, IPv6, or a corporate proxy is in the path.
  • In a browser, GET /v1/ip and GET /v1/ip/{ip} send Access-Control-Allow-Origin: * and answer OPTIONS preflight, so a page can call them directly. The anonymous allowance then counts against the visitor's own IP, not your origin server.

Anonymous quota is 500 lookups/day per client IP (60/min); a free logged-in key raises the daily cap to 5,000/day. Check remaining with GET https://ip99.com/v1/me or the X-Daily-* headers. OpenAPI: https://ip99.com/openapi.json. Pricing: https://ip99.com/en/pricing.

Do not treat IP99 scores as identical to other ThreatHunter datasets — this article only claims what free /v1/ip and the cited product pages document.

Try it

curl https://ip99.com/v1/ip curl https://ip99.com/v1/ip/8.8.8.8 curl https://ip99.com/v1/ip/192.168.1.1 curl https://ip99.com/v1/me 

IP99 is a ThreatHunter product. The address on your machine is not always the address the internet sees; start with the no-path lookup, and read evidence_state before you treat a 0 as "safe." Start at https://ip99.com; the field contract is on What is my IP address? and https://ip99.com/api.