Classify an IP by ASN Type: Hosting, Business, ISP
An IP address does not tell you what kind of network it belongs to. The autonomous system behind it does. Every routable IP sits inside an ASN, and that ASN has a type : hosting, business, education, government, or a consumer ISP. One lookup returns it, and that single field sorts almost any address into datacenter traffic, an organization, or a real person on a home connection. Almost. There are a few cases where ASN type alone points you toward the wrong conclusion, including one that matters particularly for fraud and abuse work. We'll get to them. TL;DR - Every public IP belongs to an ASN, and the ASN carries a type field:ISP ,HOSTING ,BUSINESS ,EDUCATION , orGOVERNMENT . - HOSTING means a datacenter or cloud provider.ISP means a consumer access network.BUSINESS ,EDUCATION , andGOVERNMENT are organizations on their own address space. - A single call to the dedicated ASN endpoint returns the type and can also include routing data such as routes, upstreams, downstreams, and peers for additional context. - The type describes the network operator. When a business runs on rented cloud space, the operator is a hosting company but the tenant is a business. Reading only the ASN type mislabels them. The rest of this is the matrix, a classifier you can paste in, and the four places the type field stops being enough. The ASN-type classification matrix Here is the whole idea in one table. Look up the ASN for an address, read type , map it to a bucket. asn.type | What it is | Example ASN | Treat traffic as | |---|---|---|---| HOSTING | Cloud/datacenter provider. Servers live here. | AS24940 (Hetzner) | Datacenter. Bots, scrapers, and VPN exits cluster here. | ISP | Primarily an end-user access network, including fixed-line and mobile ISP space. | AS1257 (Tele2) | Consumer/access network. Lower baseline infrastructure suspicion, but not proof of a human user. | BUSINESS | A company operating its own address space. | AS1 (Level 3) | Organization. Office egress, corporate VPNs, SaaS backends. | EDUCATION | Universities and research networks. | AS12 (New York University) | Organization. Campus and lab traffic. | GOVERNMENT | Public-sector networks. | (varies by RIR) | Organization. | The three buckets developers usually care about, hosting, business, and consumer, come straight out of this. HOSTING is your datacenter bucket. ISP is your consumer bucket. BUSINESS , EDUCATION , and GOVERNMENT are three flavors of the same "this is an organization, not a home user and not a rented server" bucket, and you can collapse them if your logic doesn't need the distinction. What makes this reliable is that ASN type is a property of the network operator, not a guess from the IP number. You cannot look at 49.12.0.0 and know it's a datacenter. You look up its ASN, see AS24940 Hetzner tagged HOSTING , and now you know. One ASN lookup, one classification The ASN type field is available on the dedicated ASN endpoint and in the main geolocation response. The dedicated ASN API is the cleaner choice when classification is all you want, because it returns the ASN record and nothing else, and it takes either an IP or an AS number. The response and the type field A lookup by IP returns the ASN that announces it: curl -X GET 'https://api.ipgeolocation.io/v3/asn?apiKey=API_KEY&ip=49.12.0.0' { "ip": "49.12.0.0", "asn": { "as_number": "AS24940", "organization": "Hetzner Online GmbH", "country": "DE", "type": "HOSTING", "domain": "hetzner.com", "date_allocated": "2002-06-03", "asn_name": "HETZNER-AS", "allocation_status": "ASSIGNED", "num_of_ipv4_routes": "84", "num_of_ipv6_routes": "6", "rir": "RIPE" } } type is HOSTING , so 49.12.0.0 is datacenter space. The type field requires a paid plan; the free tier returns the AS number, organization, and country but not the classification. Everything else in this guide keys off type , so that's the field to check your plan for. Lookup by IP or by AS number You can classify a single address, or a whole network. Passing an AS number instead of an IP skips the IP-to-ASN step and returns the same record: curl -X GET 'https://api.ipgeolocation.io/v3/asn?apiKey=API_KEY&asn=1' That returns AS1 (Level 3) as BUSINESS . This is useful when you already have the ASN from your logs or your CDN and just want its classification, or when you're building a static allowlist of, say, every ASN a partner operates. When you look up by asn , the response drops the top-level ip field, since there's no single address to report. A classifier you can copy Here's the logic wrapped so it returns a bucket and never throws on a bad response. import os import requests IPGEO_API_KEY = os.environ.get("IPGEO_API_KEY") # ASN type values that mean "an organization runs this," not a home user # and not a rented server. Collapse them if your logic doesn't need the split. ORG_TYPES = {"BUSINESS", "EDUCATION", "GOVERNMENT"} def classify_ip(ip): """Return 'hosting', 'consumer', 'organization', or 'unknown' for an IP. Never raises on a network or parse error; callers get 'unknown' and can decide their own fallback (fail-open vs fail-closed) from there. """ try: resp = requests.get( "https://api.ipgeolocation.io/v3/asn", params={"apiKey": IPGEO_API_KEY, "ip": ip}, # Short timeouts: a classification call should never hang a request path. timeout=(1.0, 1.5), ) resp.raise_for_status() except requests.RequestException as exc: # Log and fall back. Don't let an IP lookup take down the caller. print(f"ASN lookup failed for {ip}: {exc}") return "unknown" # .get() the whole way down: any field can be absent or empty. try: data = resp.json() except ValueError as exc: print(f"Invalid ASN response for {ip}: {exc}") return "unknown" asn_type = (data.get("asn") or {}).get("type") or "" if asn_type == "HOSTING": return "hosting" if asn_type == "ISP": return "consumer" if asn_type in ORG_TYPES: return "organization" return "unknown" # empty type, unrecognized value, or bogon range if name == "main": for ip in ("49.12.0.0", "8.8.8.8", "91.128.103.196"): print(ip, "->", classify_ip(ip)) Two decisions worth calling out. The timeout is deliberately tight because an ASN lookup usually sits on a request path (a signup, a login, a checkout), and a slow classifier is worse than no classifier. And an empty or unrecognized type returns unknown rather than a guess, so your downstream rules can treat "we don't know" differently from "we know it's a home user." The same shape in JavaScript, using fetch with an abort timeout: const IPGEO_API_KEY = process.env.IPGEO_API_KEY; // Organization ASN types, kept separate from hosting and consumer. const ORG_TYPES = new Set(["BUSINESS", "EDUCATION", "GOVERNMENT"]); async function classifyIp(ip) { const url = https://api.ipgeolocation.io/v3/asn + ?apiKey=${IPGEO_API_KEY}&ip=${encodeURIComponent(ip)}; try { const resp = await fetch(url, { // Abort before this ever stalls a login or checkout flow. signal: AbortSignal.timeout(1500), }); if (!resp.ok) throw new Error(HTTP ${resp.status}); const data = await resp.json(); // Optional chaining the whole way: asn or type may be missing. const asnType = data?.asn?.type ?? ""; if (asnType === "HOSTING") return "hosting"; if (asnType === "ISP") return "consumer"; if (ORG_TYPES.has(asnType)) return "organization"; return "unknown"; } catch (err) { // Network error, timeout, or bad JSON: fall back, don't throw. console.error(ASN lookup failed for ${ip}: ${err.message}); return "unknown"; } } Both return one of four strings. What you do with them is your policy, not the classifier's job: most teams pass consumer , add friction to hosting , and treat organization as low-risk-but-log. The point is that the branching lives in one place, keyed on one field. One operational note: If your logs or edge provider already give you the ASN, cache classification by AS number. If all you have is an IP, you still need an IP-to-ASN mapping first, so in a higher-volume implementation cache both the IP/prefix-to-ASN mapping and the ASN-to-type classification. When ASN type is not enough The matrix handles the large majority of addresses. Then there are four cases where reading type alone can give you an incomplete or misleading answer. These are the parts most guides skip, and they're the reason the classification isn't a one-liner. Subleased cloud: the operator is hosting, the tenant is a business This is the important one. A company rents servers or address space from a cloud provider and runs its own service on it. The ASN belongs to the hosting company, so asn.type reads HOSTING , but the actual occupant is a business. If you classify on ASN type alone, you file a legitimate company under "datacenter" and treat its traffic as suspect. This is exactly why the company object in the main geolocation response is worth pulling alongside the ASN. The company object can identify a more specific organization associated with the IP range than the ASN operator, and it carries its own type . Look at 2.56.188.34 : curl -X GET 'https://api.ipgeolocation.io/v3/ipgeo?apiKey=API_KEY&ip=2.56.188.34' { "asn": { "as_number": "AS62240", "organization": "Clouvider Limited", "type": "HOSTING", "domain": "clouvider.net" }, "company": { "name": "Packethub S.A.", "type": "BUSINESS", "domain": "packethub.com" } } The ASN registrant is Clouvider, a hosting provider, tagged HOSTING . The company mapped to this address is Packethub, tagged BUSINESS . Same IP, two different answers, and the company result gives you more specific context for "who is associated with this IP". When company.type and asn.type differ, the company field can give you useful context about who is associated with that particular address range, while the ASN still tells you about the underlying network. Reading both, and knowing which to trust when they split, is the difference between a classifier that works on cloud-hosted businesses and one that flags every startup running on a VPS. Corporate VPN: hosting-looking, entirely legitimate An employee connecti
Comments
No comments yet. Start the discussion.