{
 "swagger": "2.0",
 "info": {
  "title": "AI Crawler Index",
  "version": "2026-09-01",
  "description": "Every AI crawler on the web, what it is for, what blocking it costs you, and the IP ranges its operator publishes — as JSON, CSV, robots.txt and regex.\n\nA read-only, static, keyless index of 56 web crawlers operated by 30 companies and projects: what each one is for, the exact robots.txt token and user-agent substring, whether the operator says it obeys robots.txt, how to verify it is genuine, and — the part nobody else publishes — what you lose by blocking it.\n\nEvery path below is a static file. There is no key, no rate limit and no state; `Access-Control-Allow-Origin: *` is set, so it is callable from a browser. Data is CC0.\n\nThe IP-range mirrors are refreshed from 12 operator-published endpoints; /status.json reports when each was last fetched and whether it changed.\n\nMechanically converted from https://www.pathwren.workers.dev/openapi.json (OpenAPI 3.1) by the same build, in the same run, from the same object — this is not a second hand-maintained description and cannot drift from the first. Every operation is a keyless GET of a static file, which 2.0 describes as completely as 3.1 does. One 3.1 construct has no 2.0 equivalent and is rendered with the usual extension instead: Crawler.published_ip_ranges_url is `type: string` with `x-nullable: true` (2.0 has no null type). It is null when the operator publishes no IP ranges. The 3.1 original is canonical and is what /apis.json, /.well-known/api-catalog and the MCP server point at.",
  "license": {
   "name": "CC0-1.0",
   "url": "https://creativecommons.org/publicdomain/zero/1.0/"
  },
  "termsOfService": "https://www.pathwren.workers.dev/terms.html",
  "contact": {
   "url": "https://www.pathwren.workers.dev/about.html"
  }
 },
 "host": "www.pathwren.workers.dev",
 "basePath": "/",
 "schemes": [
  "https"
 ],
 "produces": [
  "application/json"
 ],
 "paths": {
  "/data/agents.json": {
   "get": {
    "tags": [
     "bulk"
    ],
    "summary": "Every crawler record, plus categories and an endpoint map",
    "operationId": "listCrawlers",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "56 records",
      "schema": {
       "type": "object",
       "properties": {
        "count": {
         "type": "integer"
        },
        "generated_at": {
         "type": "string",
         "format": "date-time"
        },
        "crawlers": {
         "type": "array",
         "items": {
          "$ref": "#/definitions/Crawler"
         }
        }
       }
      },
      "examples": {
       "application/json": {
        "count": 56,
        "generated_at": "2026-09-01T19:26:24+00:00",
        "crawlers": [
         {
          "slug": "oai-searchbot",
          "name": "OAI-SearchBot",
          "operator": "OpenAI",
          "operator_slug": "openai",
          "category": "ai-search",
          "category_label": "AI search crawlers",
          "robots_token": "OAI-SearchBot",
          "user_agent_substring": "OAI-SearchBot",
          "user_agent_example": "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; OAI-SearchBot/1.0; +https://openai.com/searchbot",
          "respects_robots_txt": "documented",
          "respects_robots_txt_label": "obeys robots.txt (documented)",
          "verification_method": "published-ranges",
          "verification_label": "published IP ranges",
          "published_ip_ranges_url": "https://openai.com/searchbot.json",
          "ip_ranges_endpoint": "https://www.pathwren.workers.dev/ip-ranges/openai-searchbot.json",
          "ipv4_prefix_count": 35,
          "ipv6_prefix_count": 0,
          "what_it_is": "Builds the index ChatGPT search answers from. Content it collects is used for retrieval and citation, not for model training.",
          "cost_of_blocking": "High. Blocking this removes you from ChatGPT search results and from the source links ChatGPT shows. This is the single most expensive block on this list for anyone who wants to be cited by an assistant.",
          "operator_docs": "https://platform.openai.com/docs/bots",
          "html_url": "https://www.pathwren.workers.dev/crawler/oai-searchbot.html",
          "json_url": "https://www.pathwren.workers.dev/crawler/oai-searchbot.json",
          "last_reviewed": "2026-09-01"
         }
        ]
       }
      }
     }
    }
   }
  },
  "/crawler/{slug}.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "One crawler record by slug",
    "description": "The same records as /data/agents.json, one file each, so a client can fetch exactly the one it needs.",
    "operationId": "getCrawler",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "description": "Crawler slug, from /data/agents.json",
      "type": "string",
      "enum": [
       "gptbot",
       "oai-searchbot",
       "chatgpt-user",
       "claudebot",
       "claude-searchbot",
       "claude-user",
       "anthropic-ai",
       "claude-web",
       "google-extended",
       "googlebot",
       "googleother",
       "google-cloudvertexbot",
       "google-inspectiontool",
       "googlebot-image",
       "googlebot-news",
       "storebot-google",
       "bingbot",
       "applebot",
       "applebot-extended",
       "perplexitybot",
       "perplexity-user",
       "ccbot",
       "bytespider",
       "tiktokspider",
       "meta-externalagent",
       "meta-externalfetcher",
       "facebookexternalhit",
       "facebookbot",
       "amazonbot",
       "duckassistbot",
       "duckduckbot",
       "ai2bot",
       "ai2bot-dolma",
       "cohere-ai",
       "cohere-training-data-crawler",
       "mistralai-user",
       "youbot",
       "diffbot",
       "omgilibot",
       "omgili",
       "webzio-extended",
       "imagesiftbot",
       "timpibot",
       "semrushbot",
       "semrushbot-ocob",
       "ahrefsbot",
       "archive-org-bot",
       "ia-archiver",
       "yandexbot",
       "baiduspider",
       "seznambot",
       "yeti",
       "petalbot",
       "firecrawlagent",
       "scrapy",
       "img2dataset"
      ]
     }
    ],
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      },
      "examples": {
       "application/json": {
        "slug": "gptbot",
        "name": "GPTBot",
        "operator": "OpenAI",
        "operator_slug": "openai",
        "category": "ai-training",
        "category_label": "AI training crawlers",
        "robots_token": "GPTBot",
        "user_agent_substring": "GPTBot",
        "user_agent_example": "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; GPTBot/1.2; +https://openai.com/gptbot",
        "respects_robots_txt": "documented",
        "respects_robots_txt_label": "obeys robots.txt (documented)",
        "verification_method": "published-ranges",
        "verification_label": "published IP ranges",
        "published_ip_ranges_url": "https://openai.com/gptbot.json",
        "ip_ranges_endpoint": "https://www.pathwren.workers.dev/ip-ranges/openai-gptbot.json",
        "ipv4_prefix_count": 21,
        "ipv6_prefix_count": 0,
        "what_it_is": "OpenAI's bulk crawler. Pages it fetches may be used to train future OpenAI foundation models. It is not the bot that puts you in ChatGPT's search results, and blocking it does not remove you from them.",
        "cost_of_blocking": "Your content is excluded from training data for future OpenAI models. No effect on ChatGPT search visibility, on citations, or on links a user pastes into ChatGPT.",
        "operator_docs": "https://platform.openai.com/docs/bots",
        "html_url": "https://www.pathwren.workers.dev/crawler/gptbot.html",
        "json_url": "https://www.pathwren.workers.dev/crawler/gptbot.json",
        "last_reviewed": "2026-09-01"
       }
      }
     },
     "404": {
      "description": "No such crawler"
     }
    }
   }
  },
  "/data/agents.csv": {
   "get": {
    "tags": [
     "bulk"
    ],
    "summary": "The same table as CSV",
    "operationId": "listCrawlersCsv",
    "produces": [
     "text/csv"
    ],
    "responses": {
     "200": {
      "description": "CSV with a header row",
      "schema": {
       "type": "string"
      }
     }
    }
   }
  },
  "/data/ua-regex.json": {
   "get": {
    "tags": [
     "bulk"
    ],
    "summary": "Pre-escaped user-agent regexes, whole-list and per category",
    "operationId": "getUserAgentRegex",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "Regex alternations",
      "schema": {
       "type": "object",
       "properties": {
        "all": {
         "type": "string"
        },
        "ai_only": {
         "type": "string"
        },
        "by_category": {
         "type": "object",
         "additionalProperties": {
          "type": "string"
         }
        }
       }
      }
     }
    }
   }
  },
  "/data/ip-sources.json": {
   "get": {
    "tags": [
     "ip-ranges"
    ],
    "summary": "Which operators publish verifiable IP ranges, and where",
    "operationId": "listIpSources",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "Source list"
     }
    }
   }
  },
  "/ip-ranges/all.json": {
   "get": {
    "tags": [
     "ip-ranges"
    ],
    "summary": "Union of every operator-published prefix, grouped by source",
    "operationId": "getAllIpRanges",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "1887 IPv4 and 1056 IPv6 prefixes"
     }
    }
   }
  },
  "/ip-ranges/all.txt": {
   "get": {
    "tags": [
     "ip-ranges"
    ],
    "summary": "The same prefixes, one CIDR per line",
    "operationId": "getAllIpRangesText",
    "produces": [
     "text/plain"
    ],
    "responses": {
     "200": {
      "description": "Plain text, # comments",
      "schema": {
       "type": "string"
      }
     }
    }
   }
  },
  "/ip-ranges/{source}.json": {
   "get": {
    "tags": [
     "ip-ranges"
    ],
    "summary": "One operator's published prefix list, normalised",
    "operationId": "getIpRangeSource",
    "parameters": [
     {
      "name": "source",
      "in": "path",
      "required": true,
      "description": "Source slug, from /data/ip-sources.json",
      "type": "string",
      "enum": [
       "openai-gptbot",
       "openai-searchbot",
       "openai-chatgpt-user",
       "google-googlebot",
       "google-special",
       "google-user-triggered",
       "google-user-triggered-google",
       "bing-bingbot",
       "apple-applebot",
       "duckduckgo-duckduckbot",
       "perplexity-bot",
       "perplexity-user"
      ]
     }
    ],
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "Prefixes with provenance"
     },
     "404": {
      "description": "No such source"
     }
    }
   }
  },
  "/robots/{policy}.txt": {
   "get": {
    "tags": [
     "robots"
    ],
    "summary": "A ready-made robots.txt policy file",
    "operationId": "getRobotsPolicy",
    "parameters": [
     {
      "name": "policy",
      "in": "path",
      "required": true,
      "type": "string",
      "enum": [
       "allow-all",
       "block-ai-training",
       "block-all-ai",
       "block-datasets",
       "allow-ai-search-only",
       "block-seo-tools",
       "block-disputed",
       "maximum-ai-visibility"
      ]
     }
    ],
    "produces": [
     "text/plain"
    ],
    "responses": {
     "200": {
      "description": "robots.txt fragment, ready to append",
      "schema": {
       "type": "string"
      }
     }
    }
   }
  },
  "/policy/{policy}.json": {
   "get": {
    "tags": [
     "robots"
    ],
    "summary": "A policy with its rationale and the crawlers it names",
    "operationId": "getPolicy",
    "parameters": [
     {
      "name": "policy",
      "in": "path",
      "required": true,
      "type": "string",
      "enum": [
       "allow-all",
       "block-ai-training",
       "block-all-ai",
       "block-datasets",
       "allow-ai-search-only",
       "block-seo-tools",
       "block-disputed",
       "maximum-ai-visibility"
      ]
     }
    ],
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "Policy record"
     }
    }
   }
  },
  "/status.json": {
   "get": {
    "tags": [
     "status"
    ],
    "summary": "Freshness and health of every upstream IP-range endpoint",
    "operationId": "getStatus",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "Per-source fetch state",
      "schema": {
       "type": "object",
       "properties": {
        "sources_ok": {
         "type": "integer"
        },
        "sources_failed": {
         "type": "integer"
        },
        "generated_at": {
         "type": "string",
         "format": "date-time"
        }
       }
      }
     }
    }
   }
  },
  "/feed.json": {
   "get": {
    "tags": [
     "status"
    ],
    "summary": "JSON Feed 1.1 of what changed",
    "operationId": "getFeed",
    "produces": [
     "application/feed+json"
    ],
    "responses": {
     "200": {
      "description": "JSON Feed"
     }
    }
   }
  },
  "/crawler/gptbot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for GPTBot",
    "description": "OpenAI's bulk crawler. Pages it fetches may be used to train future OpenAI foundation models. It is not the bot that puts you in ChatGPT's search results, and blocking it does not remove you from them.",
    "operationId": "crawler_gptbot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/oai-searchbot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for OAI-SearchBot",
    "description": "Builds the index ChatGPT search answers from. Content it collects is used for retrieval and citation, not for model training.",
    "operationId": "crawler_oai_searchbot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/chatgpt-user.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for ChatGPT-User",
    "description": "Fetches a single page at the moment a user or a ChatGPT agent asks for it — a pasted link, a browsing step, an Operator task. One human intent, one request. OpenAI states these fetches are not used for training.",
    "operationId": "crawler_chatgpt_user",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/claudebot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for ClaudeBot",
    "description": "Anthropic's bulk crawler, gathering pages that may be used to train Claude models.",
    "operationId": "crawler_claudebot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/claude-searchbot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Claude-SearchBot",
    "description": "Indexes pages so Claude's web search can find and cite them. Separate token from the training crawler, so search visibility and training consent are independent decisions.",
    "operationId": "crawler_claude_searchbot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/claude-user.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Claude-User",
    "description": "Fetches a page because a Claude user asked Claude to read it, at that moment.",
    "operationId": "crawler_claude_user",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/anthropic-ai.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for anthropic-ai",
    "description": "A legacy robots.txt token from before Anthropic consolidated on ClaudeBot. It is still widely present in robots.txt files and costs nothing to keep, but it is a control token rather than a bot you will see in logs.",
    "operationId": "crawler_anthropic_ai",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/claude-web.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Claude-Web",
    "description": "An earlier Anthropic token for user-facing web access, superseded by Claude-User and Claude-SearchBot. Kept here because it appears in most published robots.txt templates.",
    "operationId": "crawler_claude_web",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/google-extended.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Google-Extended",
    "description": "Not a crawler. A robots.txt token that tells Google whether pages Googlebot already fetched may be used to train and ground Gemini. You will never see it in an access log; disallowing it changes what Google does with content it fetched under a different name.",
    "operationId": "crawler_google_extended",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/googlebot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Googlebot",
    "description": "The classic search crawler. It is also the crawler behind AI Overviews: Google does not run a separate bot for them, which is why the only AI opt-out is the Google-Extended token and not a Googlebot block.",
    "operationId": "crawler_googlebot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/googleother.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for GoogleOther",
    "description": "A generic fetcher used by Google product teams for one-off crawls and research, including data collection that does not belong to Search.",
    "operationId": "crawler_googleother",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/google-cloudvertexbot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Google-CloudVertexBot",
    "description": "Crawls a site on behalf of a Vertex AI Agent Builder customer who is building an agent over that site. It only visits sites the customer has asked it to.",
    "operationId": "crawler_google_cloudvertexbot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/google-inspectiontool.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Google-InspectionTool",
    "description": "The fetcher behind Search Console's URL Inspection and the Rich Results Test. It runs when a site owner clicks a button.",
    "operationId": "crawler_google_inspectiontool",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/googlebot-image.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Googlebot-Image",
    "description": "Image indexing for Google Images. A separate token so you can leave images out of search without leaving search.",
    "operationId": "crawler_googlebot_image",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/googlebot-news.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Googlebot-News",
    "description": "A robots.txt token controlling inclusion in Google News. It does not have its own user-agent string; the fetch arrives as Googlebot.",
    "operationId": "crawler_googlebot_news",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/storebot-google.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Storebot-Google",
    "description": "Checks shopping and checkout flows for Google's shopping surfaces.",
    "operationId": "crawler_storebot_google",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/bingbot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for bingbot",
    "description": "Bing's only crawler, and therefore also the crawler behind Microsoft Copilot's grounding. Microsoft's documented way to keep search indexing while refusing generative reuse is the nocache / noarchive robots meta directive, not a separate user-agent.",
    "operationId": "crawler_bingbot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/applebot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Applebot",
    "description": "Powers Siri, Spotlight and Safari suggestions. Blocking it is a search decision, not an AI decision — the AI decision has its own token.",
    "operationId": "crawler_applebot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/applebot-extended.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Applebot-Extended",
    "description": "Apple's counterpart to Google-Extended: a robots.txt token that withdraws consent for Apple Intelligence and Apple foundation-model training, without touching Applebot's search crawl.",
    "operationId": "crawler_applebot_extended",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/perplexitybot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for PerplexityBot",
    "description": "Builds Perplexity's search index. Perplexity is citation-heavy by product design, so inclusion here converts to referral traffic more directly than most AI surfaces.",
    "operationId": "crawler_perplexitybot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/perplexity-user.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Perplexity-User",
    "description": "Fetches a page because a Perplexity user asked for it. Perplexity documents that this fetch is user-initiated and is therefore not governed by robots.txt — a robots rule will not stop it, by stated policy.",
    "operationId": "crawler_perplexity_user",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/ccbot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for CCBot",
    "description": "Common Crawl's corpus builder. It trains nothing itself, but its archive is an input to most open and many closed LLM training sets, which makes it the highest-leverage single entry on this list.",
    "operationId": "crawler_ccbot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/bytespider.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Bytespider",
    "description": "ByteDance's crawler, associated with training data collection for Doubao and related models. Repeatedly reported by CDNs and site operators as the highest-volume AI crawler on the web and as inconsistent about robots.txt.",
    "operationId": "crawler_bytespider",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/tiktokspider.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for TikTokSpider",
    "description": "A second ByteDance crawler identifying with TikTok, collecting page content for the same family of models.",
    "operationId": "crawler_tiktokspider",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/meta-externalagent.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for meta-externalagent",
    "description": "Meta's AI crawler, gathering training data for Llama and Meta AI. It replaced the older FacebookBot name for this purpose.",
    "operationId": "crawler_meta_externalagent",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/meta-externalfetcher.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for meta-externalfetcher",
    "description": "Fetches a page when a Meta AI user asks about a specific link.",
    "operationId": "crawler_meta_externalfetcher",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/facebookexternalhit.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for facebookexternalhit",
    "description": "The link unfurler: it reads your Open Graph tags when somebody shares your URL on a Meta property.",
    "operationId": "crawler_facebookexternalhit",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/facebookbot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for FacebookBot",
    "description": "Meta's older speech- and language-corpus crawler, largely superseded by meta-externalagent but still listed as a valid robots token.",
    "operationId": "crawler_facebookbot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/amazonbot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Amazonbot",
    "description": "Amazon's crawler, feeding Alexa's ability to answer questions from the web and Amazon's own search and assistant products.",
    "operationId": "crawler_amazonbot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/duckassistbot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for DuckAssistBot",
    "description": "Fetches pages so DuckAssist can generate and cite answers inside DuckDuckGo.",
    "operationId": "crawler_duckassistbot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/duckduckbot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for DuckDuckBot",
    "description": "DuckDuckGo's own crawler. Note that the bulk of DuckDuckGo's web results come from Bing, so blocking bingbot removes you from DuckDuckGo whether or not you allow this one.",
    "operationId": "crawler_duckduckbot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/ai2bot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for AI2Bot",
    "description": "The Allen Institute's crawler, gathering pages for open research corpora such as Dolma that underpin fully open models like OLMo.",
    "operationId": "crawler_ai2bot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/ai2bot-dolma.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Ai2Bot-Dolma",
    "description": "The variant of AI2's crawler named for the Dolma corpus specifically.",
    "operationId": "crawler_ai2bot_dolma",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/cohere-ai.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for cohere-ai",
    "description": "Cohere's fetcher, used when its assistant products need a page.",
    "operationId": "crawler_cohere_ai",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/cohere-training-data-crawler.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for cohere-training-data-crawler",
    "description": "Cohere's separately-named bulk crawler for model training data, split out so consent for training and consent for retrieval can differ.",
    "operationId": "crawler_cohere_training_data_crawler",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/mistralai-user.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for MistralAI-User",
    "description": "Fetches a page when a Le Chat user asks Mistral's assistant to read it.",
    "operationId": "crawler_mistralai_user",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/youbot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for YouBot",
    "description": "You.com's crawler, feeding its AI search product and its search API.",
    "operationId": "crawler_youbot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/diffbot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Diffbot",
    "description": "Extracts structured records from pages to build a commercial knowledge graph that is resold and used for retrieval and training.",
    "operationId": "crawler_diffbot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/omgilibot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for omgilibot",
    "description": "Webz.io's crawler, collecting web and forum text sold as datasets, including to model builders.",
    "operationId": "crawler_omgilibot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/omgili.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for omgili",
    "description": "The older robots token for the same Webz.io collection, still honoured and still worth listing.",
    "operationId": "crawler_omgili",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/webzio-extended.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Webzio-Extended",
    "description": "Webz.io's opt-out token specifically for AI training reuse, in the pattern Google and Apple established.",
    "operationId": "crawler_webzio_extended",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/imagesiftbot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for ImagesiftBot",
    "description": "Crawls images for Hive AI's reverse-image and dataset products. Image-heavy sites see this one long before they see the text crawlers.",
    "operationId": "crawler_imagesiftbot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/timpibot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Timpibot",
    "description": "A distributed crawler building an independent search index outside the Google/Bing duopoly.",
    "operationId": "crawler_timpibot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/semrushbot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for SemrushBot",
    "description": "Semrush's backlink and keyword crawler. It is not an AI crawler, but it is usually in the top three by volume on any site, and it is the cheapest block on this list.",
    "operationId": "crawler_semrushbot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/semrushbot-ocob.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for SemrushBot-OCOB",
    "description": "Semrush's separately-tokenised crawler for its AI content tooling, split out so SEO crawling and AI reuse can be answered differently.",
    "operationId": "crawler_semrushbot_ocob",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/ahrefsbot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for AhrefsBot",
    "description": "Ahrefs' backlink crawler, and one of the largest non-search crawlers on the web by request volume.",
    "operationId": "crawler_ahrefsbot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/archive-org-bot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for archive.org_bot",
    "description": "The Wayback Machine's crawler. Preservation rather than AI, but it lands in the same 'is this bot welcome' decision and its output is a public corpus.",
    "operationId": "crawler_archive_org_bot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/ia-archiver.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for ia_archiver",
    "description": "The legacy Alexa/Internet Archive token, still present in most robots.txt files and still occasionally honoured.",
    "operationId": "crawler_ia_archiver",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/yandexbot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for YandexBot",
    "description": "Yandex's search crawler, which also feeds Alice and Yandex's generative answers.",
    "operationId": "crawler_yandexbot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/baiduspider.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Baiduspider",
    "description": "Baidu's search crawler, and the ingest path for Baidu's Ernie-backed answers.",
    "operationId": "crawler_baiduspider",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/seznambot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for SeznamBot",
    "description": "Seznam's crawler — the dominant search engine in the Czech Republic and one of the few national engines with its own index.",
    "operationId": "crawler_seznambot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/yeti.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Yeti",
    "description": "Naver's crawler. Naver is South Korea's largest search portal and runs its own index and its own generative answers.",
    "operationId": "crawler_yeti",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/petalbot.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for PetalBot",
    "description": "Huawei's crawler for Petal Search, shipped as the default search on Huawei devices.",
    "operationId": "crawler_petalbot",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/firecrawlagent.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for FirecrawlAgent",
    "description": "A hosted scrape-to-markdown service that LLM applications call to read pages. The requester is whoever is building on it, not Firecrawl itself, so volume and intent vary wildly.",
    "operationId": "crawler_firecrawlagent",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/scrapy.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for Scrapy",
    "description": "Not an operator: the default user-agent of the most common Python crawling framework. Anyone can be behind it. Modern Scrapy obeys robots.txt by default, which is why the default UA is still worth a rule.",
    "operationId": "crawler_scrapy",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  },
  "/crawler/img2dataset.json": {
   "get": {
    "tags": [
     "crawlers"
    ],
    "summary": "Record for img2dataset",
    "description": "The tool used to turn image-URL lists such as LAION's into downloaded training sets. It is run by whoever is building a dataset, not by a single operator.",
    "operationId": "crawler_img2dataset",
    "produces": [
     "application/json"
    ],
    "responses": {
     "200": {
      "description": "The crawler record",
      "schema": {
       "$ref": "#/definitions/Crawler"
      }
     }
    }
   }
  }
 },
 "tags": [
  {
   "name": "crawlers",
   "description": "One record per crawler."
  },
  {
   "name": "bulk",
   "description": "The whole dataset in several shapes."
  },
  {
   "name": "ip-ranges",
   "description": "Operator-published prefixes, normalised."
  },
  {
   "name": "robots",
   "description": "Ready-made robots.txt policy files."
  },
  {
   "name": "status",
   "description": "Freshness of the upstream sources."
  }
 ],
 "definitions": {
  "Crawler": {
   "type": "object",
   "required": [
    "slug",
    "name",
    "operator",
    "category",
    "robots_token"
   ],
   "properties": {
    "slug": {
     "type": "string",
     "description": "Stable identifier used in URLs."
    },
    "name": {
     "type": "string"
    },
    "operator": {
     "type": "string"
    },
    "operator_slug": {
     "type": "string"
    },
    "category": {
     "type": "string",
     "enum": [
      "ai-search",
      "ai-training",
      "archive",
      "dataset",
      "preview",
      "search",
      "seo",
      "tool",
      "user-fetch"
     ]
    },
    "robots_token": {
     "type": "string",
     "description": "Exact User-agent value for robots.txt."
    },
    "user_agent_substring": {
     "type": "string",
     "description": "Substring that reliably identifies it in a UA header. A match is a claim, not a proof."
    },
    "user_agent_example": {
     "type": "string"
    },
    "respects_robots_txt": {
     "type": "string",
     "enum": [
      "documented",
      "by-design-no",
      "disputed",
      "n-a"
     ]
    },
    "verification_method": {
     "type": "string",
     "enum": [
      "published-ranges",
      "reverse-dns",
      "none"
     ]
    },
    "published_ip_ranges_url": {
     "type": "string",
     "x-nullable": true,
     "format": "uri"
    },
    "ipv4_prefix_count": {
     "type": "integer"
    },
    "ipv6_prefix_count": {
     "type": "integer"
    },
    "what_it_is": {
     "type": "string"
    },
    "cost_of_blocking": {
     "type": "string",
     "description": "What you lose by disallowing it. This index's own assessment, not the operator's."
    },
    "operator_docs": {
     "type": "string",
     "format": "uri"
    },
    "last_reviewed": {
     "type": "string",
     "format": "date"
    }
   }
  }
 }
}