Verifying that a request really is GPTBot means fetching twelve different endpoints from six operators and parsing each one. This mirrors all of them into one schema, on one fetch, with the upstream timestamp and a SHA-256 of the bytes we received kept per source.
curl -s https://www.pathwren.workers.dev/ip-ranges/all.txt # 2943 CIDRs, one per line curl -s https://www.pathwren.workers.dev/ip-ranges/all.json # same, grouped by source, with provenance
| Endpoint | Operator | IPv4 | IPv6 | Operator timestamp | Last fetch |
|---|---|---|---|---|---|
| GPTBot | OpenAI | 21 | 0 | 2025-10-30 | ok |
| OAI-SearchBot | OpenAI | 35 | 0 | 2026-01-02 | ok |
| ChatGPT-User | OpenAI | 204 | 0 | 2026-08-14 | ok |
| Googlebot | 169 | 146 | 2026-08-31 | ok | |
| Google special-purpose crawlers | 135 | 135 | 2026-08-31 | ok | |
| Google user-triggered fetchers | 528 | 528 | 2026-08-31 | ok | |
| Google user-triggered fetchers (Google-owned ranges) | 247 | 247 | 2026-08-31 | ok | |
| bingbot | Microsoft | 28 | 0 | 2024-01-03 | ok |
| Applebot | Apple | 33 | 0 | 2026-07-31 | ok |
| DuckDuckBot | DuckDuckGo | 481 | 0 | 2026-07-03 | ok |
| PerplexityBot | Perplexity | 8 | 0 | 2025-02-07 | ok |
| Perplexity-User | Perplexity | 4 | 0 | 2025-10-17 | ok |
Operators that publish nothing (Anthropic, Common Crawl, Meta, ByteDance and most of the long tail) are absent by necessity — for those, user-agent is the only signal there is, and it is trivially spoofable. See /status.html for freshness.