{"openapi":"3.1.0","info":{"title":"Subnet.im API","version":"1.0.0","description":"IPv4 subnet arithmetic and BGP routing intelligence. No authentication required.","license":{"name":"CC BY 4.0","url":"https://creativecommons.org/licenses/by/4.0/"}},"servers":[{"url":"http://localhost:3000"}],"tags":[{"name":"Subnet calculator","description":"Pure arithmetic over the address you pass in. These endpoints hold no state, read no database, and answer identically whether the rest of the platform is up or not."},{"name":"Routing intelligence","description":"Built from RouteViews MRT archives ingested every six hours. Every response carries a `meta.snapshotAt` so you can see exactly how old the answer is."},{"name":"Service","description":"How current the data is, and the machine-readable description of everything above."}],"paths":{"/api/v1/subnet":{"get":{"operationId":"subnet","summary":"Calculate a subnet","description":"Network and broadcast addresses, usable host range, masks, and host counts for an IPv4 address and prefix length. Accepts either `?ip=10.0.0.0&cidr=24` or the combined `?ip=10.0.0.0/24`.","tags":["Subnet calculator"],"parameters":[{"name":"ip","in":"query","required":true,"description":"IPv4 address, optionally with the prefix length attached as `a.b.c.d/n`.","schema":{"type":"string"},"example":"10.0.0.0"},{"name":"cidr","in":"query","required":false,"description":"Prefix length, 0–32. Required unless it was supplied as part of `ip`.","schema":{"type":"integer"},"example":"24"}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"input":{"ip":"10.0.0.0","cidr":24},"network":{"networkAddress":"10.0.0.0","broadcastAddress":"10.0.0.255","firstUsableHost":"10.0.0.1","lastUsableHost":"10.0.0.254","subnetMask":"255.255.255.0","wildcardMask":"0.0.0.255","cidrNotation":"10.0.0.0/24"},"counts":{"totalHosts":256,"usableHosts":254,"networkBits":24,"hostBits":8},"classification":{"private":true,"special":{"cidr":"10.0.0.0/8","label":"Private use"}}}}}},"400":{"description":"invalid_request — `ip` is missing or not a valid IPv4 address, or `cidr` is outside 0–32.","content":{"application/json":{"example":{"error":{"code":"invalid_request","message":"`ip` is missing or not a valid IPv4 address, or `cidr` is outside 0–32."}}}}}}}},"/api/v1/cheat-sheet":{"get":{"operationId":"cheat-sheet","summary":"The full CIDR table","description":"Every prefix length from /0 to /32 with its mask, wildcard, address count and usable host count. The same data behind the site's cheat sheet.","tags":["Subnet calculator"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"rows":[{"cidr":32,"subnetMask":"255.255.255.255","wildcardMask":"0.0.0.0","totalIPs":1,"usableHosts":1,"networkBits":32,"hostBits":0},{"cidr":31,"subnetMask":"255.255.255.254","wildcardMask":"0.0.0.1","totalIPs":2,"usableHosts":2,"networkBits":31,"hostBits":1}]}}}}}}},"/api/v1/cidr/{length}":{"get":{"operationId":"cidr","summary":"One prefix length","description":"A single row of the CIDR table.","tags":["Subnet calculator"],"parameters":[{"name":"length","in":"path","required":true,"description":"Prefix length, 0–32.","schema":{"type":"integer"},"example":"24"}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"cidr":24,"subnetMask":"255.255.255.0","wildcardMask":"0.0.0.255","totalIPs":256,"usableHosts":254,"networkBits":24,"hostBits":8}}}},"400":{"description":"invalid_request — The length is not an integer between 0 and 32.","content":{"application/json":{"example":{"error":{"code":"invalid_request","message":"The length is not an integer between 0 and 32."}}}}}}}},"/api/v1/ip/{address}/info":{"get":{"operationId":"ip-info","summary":"Classify an address","description":"Whether an address is valid, which family it belongs to, and whether it falls in registry-reserved space (RFC 1918 private use, loopback, CGNAT, documentation, multicast and so on). Registry facts only — no routing data, so this never depends on the corpus.","tags":["Subnet calculator"],"parameters":[{"name":"address","in":"path","required":true,"description":"IPv4 or IPv6 address.","schema":{"type":"string"},"example":"100.64.0.1"}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"address":"100.64.0.1","family":4,"valid":true,"private":false,"special":{"cidr":"100.64.0.0/10","label":"Carrier-grade NAT","note":"RFC 6598 shared address space, used between a subscriber and their ISP's NAT. Not routed on the public internet."}}}}},"400":{"description":"invalid_request — The address or prefix could not be parsed.","content":{"application/json":{"example":{"error":{"code":"invalid_request","message":"The address or prefix could not be parsed."}}}}}}}},"/api/v1/ip/{address}":{"get":{"operationId":"ip","summary":"Look up an address","description":"The origin AS announcing the most specific prefix covering this address, its RPKI status, the registry allocation it sits in, and which collectors see it. Returns `origins: []` for public space nobody announces — that is a fact, not an error.","tags":["Routing intelligence"],"parameters":[{"name":"address","in":"path","required":true,"description":"IPv4 or IPv6 address.","schema":{"type":"string"},"example":"8.8.8.8"}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"address":"8.8.8.8","status":"routed","origins":[{"prefix":"8.8.8.0/24","asn":15169,"name":"GOOGLE","rpki":"valid","peersSeen":412,"peersTotal":419}],"allocation":{"prefix":"8.0.0.0/9","rir":"arin","country":"US"},"collectors":[{"name":"route-views2","location":"Eugene, OR","country":"US","peersSeen":41,"peersTotal":43}],"meta":{"snapshotAt":"2026-08-12T06:00:00.000Z"}}}}},"400":{"description":"invalid_request — The address or prefix could not be parsed.","content":{"application/json":{"example":{"error":{"code":"invalid_request","message":"The address or prefix could not be parsed."}}}}},"503":{"description":"data_unavailable — The routing corpus is unreachable or has never been populated.","content":{"application/json":{"example":{"error":{"code":"data_unavailable","message":"The routing corpus is unreachable or has never been populated."}}}}}}}},"/api/v1/prefix/{cidr}":{"get":{"operationId":"prefix","summary":"Prefix detail","description":"Origins for an exact prefix (more than one means a MOAS conflict), the covering announcement if the prefix itself is not announced, ROAs, registry allocation, parent/child/sibling prefixes, and announcement history. Pass the prefix with its slash intact: `/api/v1/prefix/8.8.8.0/24`.","tags":["Routing intelligence"],"parameters":[{"name":"cidr","in":"path","required":true,"description":"IPv4 or IPv6 prefix in CIDR notation.","schema":{"type":"string"},"example":"8.8.8.0/24"}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"requested":"8.8.8.0/24","origins":[{"prefix":"8.8.8.0/24","asn":15169,"name":"GOOGLE","rpki":"valid"}],"covering":[],"allocation":{"prefix":"8.0.0.0/9","rir":"arin","country":"US"},"roas":[{"asn":15169,"prefix":"8.8.8.0/24","maxLength":24}],"parents":[{"prefix":"8.8.0.0/19","asn":15169}],"children":[],"siblings":[{"prefix":"8.8.4.0/24","asn":15169}],"meta":{"snapshotAt":"2026-08-12T06:00:00.000Z"}}}}},"400":{"description":"invalid_request — The prefix could not be parsed.","content":{"application/json":{"example":{"error":{"code":"invalid_request","message":"The prefix could not be parsed."}}}}},"503":{"description":"data_unavailable — The routing corpus is unreachable or has never been populated.","content":{"application/json":{"example":{"error":{"code":"data_unavailable","message":"The routing corpus is unreachable or has never been populated."}}}}}}}},"/api/v1/as/{asn}":{"get":{"operationId":"as","summary":"AS overview","description":"Name, country, registry, prefix and address counts, and observed adjacencies split into upstreams, peers and downstreams.","tags":["Routing intelligence"],"parameters":[{"name":"asn","in":"path","required":true,"description":"Autonomous system number, 0–4294967295. A leading `AS` is accepted.","schema":{"type":"integer"},"example":"15169"}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"asn":15169,"name":"GOOGLE","description":"Google LLC","country":"US","rir":"arin","counts":{"v4Prefixes":1042,"v6Prefixes":214,"v4Addresses":"12058624","v6Slash64s":"4294967296","upstreams":96,"peers":3841,"downstreams":42},"upstreams":[{"asn":174,"name":"COGENT-174","pathsSeen":1204,"rel":"p2c"}],"meta":{"snapshotAt":"2026-08-12T06:00:00.000Z"}}}}},"400":{"description":"invalid_request — The ASN is not in range.","content":{"application/json":{"example":{"error":{"code":"invalid_request","message":"The ASN is not in range."}}}}},"404":{"description":"not_found — No such AS in the corpus.","content":{"application/json":{"example":{"error":{"code":"not_found","message":"No such AS in the corpus."}}}}},"503":{"description":"data_unavailable — The routing corpus is unreachable or has never been populated.","content":{"application/json":{"example":{"error":{"code":"data_unavailable","message":"The routing corpus is unreachable or has never been populated."}}}}}}}},"/api/v1/as/{asn}/prefixes":{"get":{"operationId":"as-prefixes","summary":"Prefixes originated by an AS","description":"Everything this AS is seen originating, paginated.","tags":["Routing intelligence"],"parameters":[{"name":"asn","in":"path","required":true,"description":"Autonomous system number.","schema":{"type":"integer"},"example":"15169"},{"name":"family","in":"query","required":false,"description":"Restrict to one address family: `4` or `6`. Omit for both.","schema":{"type":"integer"},"example":"4"},{"name":"limit","in":"query","required":false,"description":"Rows per page, 1–500. Defaults to 100.","schema":{"type":"integer"},"example":"100"},{"name":"offset","in":"query","required":false,"description":"Rows to skip. Defaults to 0.","schema":{"type":"integer"},"example":"0"}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"asn":15169,"prefixes":[{"prefix":"8.8.4.0/24","family":4,"rpki":"valid","peersSeen":410},{"prefix":"8.8.8.0/24","family":4,"rpki":"valid","peersSeen":412}],"page":{"limit":2,"offset":0,"returned":2},"meta":{"snapshotAt":"2026-08-12T06:00:00.000Z"}}}}},"400":{"description":"invalid_request — The ASN, family, limit or offset is out of range.","content":{"application/json":{"example":{"error":{"code":"invalid_request","message":"The ASN, family, limit or offset is out of range."}}}}},"404":{"description":"not_found — No such AS in the corpus.","content":{"application/json":{"example":{"error":{"code":"not_found","message":"No such AS in the corpus."}}}}},"503":{"description":"data_unavailable — The routing corpus is unreachable or has never been populated.","content":{"application/json":{"example":{"error":{"code":"data_unavailable","message":"The routing corpus is unreachable or has never been populated."}}}}}}}},"/api/v1/as/{asn}/paths":{"get":{"operationId":"as-paths","summary":"Observed AS adjacencies","description":"The upstream graph around an AS: oriented edges with how many paths, peers and collectors observed each one. `rel` is BGPKIT's inferred relationship for the pair and is null where it has none — an inference, never presented as equal to the observation.","tags":["Routing intelligence"],"parameters":[{"name":"asn","in":"path","required":true,"description":"Autonomous system number.","schema":{"type":"integer"},"example":"15169"},{"name":"depth","in":"query","required":false,"description":"How many hops out to walk, 1–3. Defaults to 2.","schema":{"type":"integer"},"example":"2"}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"asn":15169,"edges":[{"upstreamAsn":174,"downstreamAsn":15169,"pathsSeen":1204,"peersSeen":88,"collectorsSeen":14,"rel":"p2c"}],"names":{"174":"COGENT-174","15169":"GOOGLE"},"meta":{"snapshotAt":"2026-08-12T06:00:00.000Z"}}}}},"400":{"description":"invalid_request — The ASN or depth is out of range.","content":{"application/json":{"example":{"error":{"code":"invalid_request","message":"The ASN or depth is out of range."}}}}},"404":{"description":"not_found — No such AS in the corpus.","content":{"application/json":{"example":{"error":{"code":"not_found","message":"No such AS in the corpus."}}}}},"503":{"description":"data_unavailable — The routing corpus is unreachable or has never been populated.","content":{"application/json":{"example":{"error":{"code":"data_unavailable","message":"The routing corpus is unreachable or has never been populated."}}}}}}}},"/api/v1/unannounced":{"get":{"operationId":"unannounced","summary":"Allocated but unannounced space","description":"Registry allocations with no covering announcement in the latest snapshot — address space that exists on paper and is absent from the routing table.","tags":["Routing intelligence"],"parameters":[{"name":"rir","in":"query","required":false,"description":"Filter by registry: `arin`, `ripencc`, `apnic`, `lacnic`, `afrinic`.","schema":{"type":"string"},"example":"ripencc"},{"name":"country","in":"query","required":false,"description":"Filter by ISO 3166-1 alpha-2 country code.","schema":{"type":"string"},"example":"GB"},{"name":"limit","in":"query","required":false,"description":"Rows per page, 1–500. Defaults to 100.","schema":{"type":"integer"},"example":"100"},{"name":"offset","in":"query","required":false,"description":"Rows to skip. Defaults to 0.","schema":{"type":"integer"},"example":"0"}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"prefixes":[{"prefix":"5.44.128.0/18","rir":"ripencc","country":"GB","allocatedAt":"2012-03-14"},{"prefix":"5.62.0.0/19","rir":"ripencc","country":"NL","allocatedAt":"2012-05-02"}],"page":{"limit":2,"offset":0,"returned":2},"meta":{"snapshotAt":"2026-08-12T06:00:00.000Z"}}}}},"400":{"description":"invalid_request — A filter or page argument is invalid.","content":{"application/json":{"example":{"error":{"code":"invalid_request","message":"A filter or page argument is invalid."}}}}},"503":{"description":"data_unavailable — The routing corpus is unreachable or has never been populated.","content":{"application/json":{"example":{"error":{"code":"data_unavailable","message":"The routing corpus is unreachable or has never been populated."}}}}}}}},"/api/v1/status":{"get":{"operationId":"status","summary":"Data freshness","description":"Snapshot age, per-collector health and corpus size. Answers 200 even when the corpus is empty — `available: false` is the useful signal, and an endpoint whose job is to report an outage should not fail during one.","tags":["Service"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"available":true,"snapshotAt":"2026-08-12T06:00:00.000Z","ageSeconds":10800,"collectors":[{"name":"route-views2","lastSnapshotAt":"2026-08-12T06:00:00.000Z","v4Peers":43,"v6Peers":31}],"totals":{"ases":82914,"v4Prefixes":1024881,"v6Prefixes":214402}}}}}}}},"/api/v1/openapi.json":{"get":{"operationId":"openapi","summary":"OpenAPI 3.1 document","description":"Generated from the same definitions that render this page, so it cannot drift from the documentation above.","tags":["Service"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"openapi":"3.1.0","info":{"title":"Subnet.im API","version":"1.0.0"},"paths":{"/api/v1/subnet":{"get":{"operationId":"subnet"}}}}}}}}}}}}