The Landlord Is Not the Tenant

Every big AI vendor answers the question is this crawler really yours? the same way: here is a list of our IP addresses, check against it. This page resolves every one of those published addresses to the network that actually announces it, and measures what the answer is worth when all you can see is the network.

Measured · published prefixes · files · vendors

A user agent is a string the client chooses. Anything can send a request calling itself GPTBot, and plenty of things do: this project recorded thirty-six credential-probe requests in a fortnight wearing the names of Google, OpenAI, Perplexity, Amazon and Common Crawl, hunting for .env files and AWS keys. Google's crawler does not hunt AWS keys.

So the vendors publish IP ranges. Anthropic's help page puts the promise plainly: if a crawler has a source IP on this list, it is coming from Anthropic. OpenAI, Apple, Amazon, Perplexity, DuckDuckGo, Bing and Common Crawl publish equivalent files. Google publishes five, and also documents reverse DNS as a co-equal method.

This site cannot use any of it directly, and the reason is a promise it made: the visit counter stores no per-reader data, and an IP address is per-reader data. What it stores instead is the network a request arrived from, which is public routing information about an organisation rather than a fact about a person. That constraint turns out to be the interesting question rather than a limitation, because it is the same question a privacy-preserving check anywhere would face: if you know only which network a request came from, how much of the vendor's promise survives?

To answer it you need something nobody publishes: the mapping from those published address ranges to the networks that announce them. So that got built. All published prefixes were resolved against the global routing table, of them successfully. They land in just networks, held by organisations.

What a network tells you, drawn to scale

Pick a vendor. The bar is the network its addresses live in, drawn at true linear scale. The lit part is what the vendor actually published inside it.

For most vendors the lit part is not there. It is not a rendering failure: at true scale the published range is a fraction of one pixel wide, so the bar draws it at a one-pixel floor and says by how much it is cheating. That is the finding in its plainest form. Knowing a request came from OpenAI's network narrows it to addresses, of which (across published prefixes) are OpenAI's: the network is times larger than the range.

OpenAI is the good case. Perplexity publishes addresses in the Amazon networks it uses, a dilution of to one. Common Crawl publishes , a dilution of to one. Taking the Microsoft network as a whole, everything published inside it by every vendor together still leaves it times larger than all of them combined.

Four crawlers, one network

The dilution has a second consequence, and it is worse than the first. These are general purpose clouds, so the co-tenants are not only other AI vendors, they are everyone who rents there. But the other AI vendors are there too. of the crawler operators in this study publish their verification addresses into , which belongs to : . A check that can see only the network cannot tell those four apart, in either direction.

Across the vendors there are possible pairs, and of them share at least one network. Red is a pair no network-level check can separate.

Can a network-level check tell these two apart?

   separable    shares a network, not separable    same vendor

Most of them are renting

Of the operators, publish addresses inside a network their own company holds () and publish addresses that belong to somebody else's network (). Anthropic's twenty-three prefixes are spread across Amazon, Google and Microsoft. Not one of them sits in a network Anthropic holds.

vendorprefixesaddressesnetworksown?dilution

The one network where the check is exact

There is a single exception in the whole set, and it points at the fix. Google's () announces addresses, and the range Google publishes inside it is addresses: the same number. Its dilution factor is . Google appears to have given user-triggered agent traffic a network of its own, containing nothing else, and in that one case knowing the network is exactly as strong as knowing the address.

Nothing prevents any other vendor doing the same. It is the difference between renting a desk in a tower and putting your name on the building.

The lists themselves

These files are the entire verification story for most of these vendors, so their condition matters. Bing's is dated , which is days before this page was built. It also contains a prefix announced not by Microsoft but by a Shanghai company, which is what Azure's China region looks like from the routing table.

Google moved these files to a new path in March 2026 and kept the old ones serving. Three of the four pairs are byte-identical. The fourth is not: the legacy copy of the user-triggered-agents list carries prefixes where the current one carries , and is days behind. An operator who allow-listed from the older documented URL is allow-listing four of twenty.

published fileage (days)prefixes

What actually knocked

Applying the map to this site's own door, since : requests that named a vendor. arrived from a network that vendor does publish into. arrived from a network the vendor does not. cannot be judged at all, because they claim to be , which publishes no list.

claimsnetworkhitsverdictdilution

What this cannot say

One day is not a measurement. The evidence table above covers a single day, because that is when the counter started recording networks. It is a worked example of the method, not a result about AI crawler traffic. A fortnight would be a result.

Consistent is not verified. Every green row above means only that the request came from a network the claimed vendor also uses, and the dilution column says how little that narrows things. At to one, it narrows almost nothing.

One row is ours. The counter's very first record was a spoof this project fired at itself, by hand, to prove the write path worked: one request calling itself GPTBot from an Australian consumer ISP, hit. It is excluded here and labelled control in the table, and it was written down in the lab README on the day it was fired rather than left for someone to find later and misread as an attack. It is also the only row in the table that a network check would have caught, which is the honest shape of this whole exercise: the one costume in the data is the one we put on ourselves.

The direction of the evidence is asymmetric. A network match is weak evidence of innocence. A network mismatch is strong evidence of a costume. This study found mismatches, which is not the same as finding none exist.

The check

Every published range file was fetched after checking the host's robots.txt, and each is snapshotted under research/vendor-network-checks/snapshots/ with the sha256 of the bytes received.

Prefixes were resolved to networks with Team Cymru's IP-to-ASN service, then a random sample of 150 was re-read with a second instrument run by a different organisation, RIPE NCC's RIPEstat. They agree on the exact network for and on the organisation holding it for . Every one of the disagreements is Amazon's AS16509 against Amazon's AS14618, so the two instruments never disagreed about who, only about which of one company's two networks. That is why the adjudication above leans on the organisation.

Address counts are exact integer arithmetic on merged, de-overlapped ranges, IPv4 and IPv6 kept separate throughout (a single IPv6 /48 holds more addresses than the whole IPv4 internet, so any combined total is the v6 number wearing a misleading label). Announced network sizes come from RIPEstat's announced-prefixes data. published addresses had no covering announcement and are excluded, and counted here rather than dropped quietly.

Every number on this page is machine-filled at load from data.json, which is derived from findings.json. No figure in this prose was typed by hand, and the verifier re-derives the register from the raw snapshots and fails if any rendered figure differs.