Locate an IP address
An IP address alone tells you almost nothing useful until you resolve it. This endpoint turns a raw IP into two solid facts drawn from the regional internet registries: the country the block is registered in, and the network that holds it — its registered name, its address range and its allocation type — so pricing, compliance and fraud logic can run on registry facts instead of guesses.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
An address without a place is just a number
IP addresses are assigned in blocks to internet service providers, hosting companies and enterprises, and those blocks are registered with regional authorities that publish who holds what and, broadly, in which country. Resolution works by matching an IP against that registration data, producing a reliable read of the country and the organisation that holds the block, without ever contacting the visitor directly. It is a registry lookup, not a device-tracking technique.
What you get back
The response gives you the country the block is registered in, the registered name of the network that holds it, the address range that block spans, and its allocation type — the difference between a direct allocation to a large operator and a smaller sub-assignment. What it does not give you is a city, a region or a street: registry data resolves to the country and the holder of the block, not a pin on a map, and anyone promising rooftop-level accuracy from an IP alone is overselling what the data actually supports.
Why the network matters as much as the country
Two IPs can sit in the same country and mean very different things depending on who holds the block. One registered name might be a home broadband provider, another a cloud hosting company with thousands of unrelated tenants behind it. Surfacing the registered network name and type alongside the country lets you build rules a country field alone simply can't support, like distinguishing a real household from a rented server, without ever pretending to know the exact street the request came from.
From registries to a live lookup
The regional internet registries that allocate IP blocks have existed since the early internet, originally created to keep the finite address space from running out chaotically as networks multiplied. That same registration structure, queried live through RDAP at request time, is what makes automated resolution possible without a manual lookup against a static list — and it is why the country and holder are dependable while a precise physical location simply isn't part of the record.
Built to slot into existing pipelines
Call the endpoint, get a task_id, and receive the result on your signed webhook or a signed link valid 24 hours, depending on which fits your integration. It's meant to sit inline with signup flows, checkout, or logging pipelines without becoming the bottleneck in any of them, resolving in the background while the rest of the request continues normally.
What you can do with it
Localized pricing and currency
Show prices in the visitor's local currency and language by resolving the registered country before the page renders content.
Content and licensing restrictions
Enforce country-based access rules for content or offers that are only licensed in certain countries.
Fraud and risk context
Compare a shipping address country against the resolved IP country to flag orders worth a second look.
Traffic analytics by network
Segment analytics by the registered network name to separate residential ISPs from hosting or corporate ranges.
FAQ
How precise is the location?
It resolves to the country the block is registered in, which is generally reliable, plus the network that holds it — not a city, region or street. Registry data can lag reassignments and VPN or mobile ranges may be registered elsewhere, so treat the country and holder as the dependable fields.
Is this ip geolocation api free to use?
There's no free tier — free tiers get abused and slow everyone down. Access runs on a prepaid ForHosting KIT balance: top up from $10.00 (it never expires) and each request is charged at its published price, so a call with no balance returns HTTP 402. No subscription, no tokens, no invented credits, and a failed task is never charged.
Does it work for IPv6 addresses?
Yes, both IPv4 and IPv6 addresses are resolved through the same endpoint.
What does the network field tell me?
The registered name, address range and allocation type of the block's holder, which often reveals whether traffic is a home connection, a business network or a hosting provider — context a country alone doesn't give you. It is the registered holder, not a numeric routing identifier or a city name.
Can I geolocate many IPs in bulk?
Each call resolves one IP; for large batches, submit one request per IP and let the asynchronous model handle the volume in parallel.
How do I get the result back?
You get a task_id immediately, and the resolved country and network arrive via your signed webhook or a signed link valid for 24 hours.
Do you store the IPs I send?
No. Data is deleted after the retention period expires and is never used for training.
What happens if a lookup fails?
It's retried automatically up to three times before returning a clear error, and you're never charged for a request that didn't complete.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/verify/ip-geo \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"ip":"8.8.8.8"}'const res = await fetch("https://api.kit.forhosting.com/verify/ip-geo", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"ip": "8.8.8.8"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/verify/ip-geo",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"ip": "8.8.8.8"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/verify/ip-geo", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"ip":"8.8.8.8"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"ip":"8.8.8.8"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/verify/ip-geo", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"ip": "8.8.8.8"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "verify.ip_geo",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |