Rightshold™ Sign up

Answers · AI crawlers

How do I tell ChatGPT-User and other AI assistant fetches apart from AI training crawlers in my server logs?

Last updated

TL;DR: Sort each AI request by the job its user-agent token names, then check the source IP against the operator's published list, because a user-agent string is just text anyone can send. The big operators split their bots by purpose. OpenAI: GPTBot crawls for model training, OAI-SearchBot crawls for ChatGPT search, and ChatGPT-User fetches a page when a person asks ChatGPT something; OpenAI says ChatGPT-User doesn't crawl automatically and, because a user started the action, robots.txt rules may not apply to it. Anthropic: ClaudeBot (training), Claude-SearchBot (search) and Claude-User (fetches at a user's request). Perplexity: PerplexityBot (search, not training) and Perplexity-User, which Perplexity says generally ignores robots.txt since a user asked. Google: Googlebot crawls, Google-Extended is only a robots.txt token with no user agent of its own, and Google-Agent is used by agents acting on a user's request. A ChatGPT-User or Claude-User hit usually means someone's assistant read that page for a question just now, which is the closest thing to a human visit these logs show.

What should I check, step by step?

1. Log enough to decide: the full user-agent, source IP, timestamp, path and status code. If your host or CDN strips query strings or user-agents from logs, fix that first.

  1. Bucket by token, not by vendor: training (GPTBot, ClaudeBot, CCBot, Applebot-Extended and Google-Extended as robots.txt controls), search indexing (OAI-SearchBot, Claude-SearchBot, PerplexityBot, Googlebot), and user-triggered fetches (ChatGPT-User, Claude-User, Perplexity-User, Google-Agent).
  2. Verify the IP for each claimed bot: OpenAI publishes separate lists (openai.com/gptbot.json, searchbot.json, chatgpt-user.json), Perplexity publishes perplexitybot.json and perplexity-user.json, Anthropic links a bots.json list from its crawler help article, and Google publishes common-crawlers, user-triggered-fetchers and user-triggered-agents JSON files.
  3. For Google, the reverse-then-forward DNS check also works: the IP's hostname must end in googlebot.com, google.com or googleusercontent.com, and that hostname must resolve back to the same IP.
  4. Match each token against its own IP list. A ChatGPT-User string from a GPTBot range, or any AI token from a residential or random cloud IP, is mislabeled or spoofed; count it as unknown.
  5. Read the pattern: crawlers walk many URLs, fetch robots.txt and sitemaps, and come back on a schedule. User fetches hit one or a few pages, often seconds after someone could have asked about them, and often don't load your CSS, images or scripts.
  6. Expect signed agents: ChatGPT's cloud browser signs requests with HTTP Message Signatures (RFC 9421), sending Signature, Signature-Input and Signature-Agent: "https://chatgpt.com"; verify against the keys at chatgpt.com/.well-known/http-message-signatures-directory, or let a CDN that checks them do it. Google says it is experimenting with Web Bot Auth for Google-Agent.
  7. Decide policy per bucket in robots.txt (training and search tokens honor it), and check each user-triggered fetcher's own rule: Anthropic says disallowing Claude-User stops those fetches, while OpenAI says robots.txt may not apply to ChatGPT-User and Perplexity and Google say their user-triggered fetchers generally ignore it, so blocking those takes a firewall rule.

Why the buckets matter

They answer different questions. Training crawls decide whether your content may end up in future models; search crawls decide whether you can be cited in AI search; user fetches are a person's assistant reading you right now. Blocking GPTBot doesn't remove you from ChatGPT search, and allowing OAI-SearchBot doesn't let GPTBot train on you; OpenAI says each setting is independent.

Common mistakes

Trusting the user-agent alone. Scrapers copy GPTBot and Googlebot strings to get past rules; only the IP list, DNS check or a verified signature confirms it.

How do I ask Rightshold about this (free, no key)?

Add the MCP server https://www.rightshold.com/mcp to Claude, Cursor, ChatGPT, Grok or VS Code, then ask: “What does my site's robots.txt tell GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-User and the other AI crawlers? Is AI training opted out?”

One-click setup

{
  "tool": "read_ai_policy",
  "arguments": {
    "domain": "example.com"
  }
}

Rightshold reads a site's public AI and crawl signals on request. It does not see your traffic, classify your logs or enforce robots.txt. Not legal advice.

What are the sources?

Related

Not legal advice. JSON · Markdown · All answers

Get a free API key in one call

No card and no email needed. 100 free credits; the license and policy checks stay free without a key.

curl -s -X POST https://www.rightshold.com/v1/accounts/signup -H "Content-Type: application/json" -d '{"accept_terms":true}'
export RIGHTSHOLD_API_KEY=rs_...   # the api_key from the reply (shown once)
curl -s https://www.rightshold.com/v1/licenses/check -H "Authorization: Bearer $RIGHTSHOLD_API_KEY" \
  -H "Content-Type: application/json" -d '{"license":"MIT","intended_use":{"commercial_use":true}}'