GEO-Score
ServicesAboutLearnLeaderboardReportsPricingBlog

GEO-Score

The Best GEO Analysis Tool

Test your content for AI search engines like ChatGPT, Perplexity, and Claude. Get actionable insights to improve your visibility.

Get GEO content tips

Resources

  • Knowledge Base
  • What is GEO?
  • GEO Blog
  • GEO Score Checker
  • Leaderboard
  • AI Glossary
  • Case Studies
  • GEO Insights
  • Reports

GEO Tools

  • Complete Website GEO Audit
  • GEO Analysis
  • AI Visibility Checker
  • ROI Calculator
  • Schema Validator
  • Perplexity SEO Checker
  • ChatGPT SEO Checker
  • Google AI Mode Checker
  • AI Crawler Checker
  • Agent Readiness Checker
  • llms.txt Generator
  • Query Fan-Out Tool
  • AI Bot Log Analyzer
  • Competitor Comparison
  • Professional Services
  • All Tools

Analyze Your

  • Blog Posts
  • Product Pages
  • Landing Pages
  • Homepages
  • Service Pages

GEO-Score

  • About
  • Privacy Policy
  • Terms & Conditions
  • Contact
  • White Label
  • Build Your Success

Follow GEO-Score

AI Search Guides

AI Search OptimizationPerplexity SEOChatGPT SEOLLM SEOAI Visibility CheckerAll guides β†’
GDPR CompliantData Hosted in EUMade in the Netherlands
KVK: 61855111BTW: NL004509498B76Β© 2026 GEO-score.onlineGEO-Score is part of Be-Found.
Empower your blogging with Bloffee
  1. Home
  2. Guides
  3. AI bot log analysis

Technical GEO

Find AI bots in your server logs (and check they're real)

Your analytics can't see AI crawlers. Your server logs can. Here are copy-paste commands, the official IP lists, and a privacy checklist.

Updated and fact-checked on October 19, 2026

Prefer not to use the command line?

Paste your log into our free AI Bot Log Analyzer. It runs in your browser, so your log is never uploaded.

Open the AI Bot Log Analyzer

Why your analytics doesn't show AI bots

Tools like Google Analytics count visits with a small script that runs in the browser. A crawler that only downloads your HTML never runs that script, so it never shows up.

Your web server writes down every request, from people and bots alike. That record is your access log.

Logs answer three questions: which bots visit, which pages they fetch, and whether they get the page or an error.

Where to find your logs

  • nginx: the standard β€œcombined” format already has everything you need. On Debian and Ubuntu the file is usually /var/log/nginx/access.log.
  • Apache: use the combined format too. The β€œcommon” format has no user agent, so you can't spot bots with it. Add %{User-agent}i to your LogFormat.
  • Behind a CDN or proxy? Then the first field may show your proxy's IP for every request. Set up your server's real-IP setting (or log the forwarded client IP) first, or every IP check below will fail.
  • No access to raw logs? Look in your host's dashboard, or put a CDN in front of your site. More on that below.

Sources

  • nginx log module docs (opens in a new tab)
  • Apache log file docs (opens in a new tab)

Read one log line

Here's one line in the combined format, with a made-up IP address. Each part answers a question.

Example log line (combined format)
203.0.113.7 - - [19/Oct/2026:08:01:02 +0000] "GET /pricing HTTP/1.1" 200 5123 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; GPTBot/1.4; +https://openai.com/gptbot"
  • IP address: where the request came from. You'll check this against the official lists.
  • Time: when it happened.
  • Request: the method and the page. Here GET /pricing.
  • Status code: 200 means served, 301/302 redirected, 403 blocked, 404 missing, 5xx a server error.
  • Bytes: how much was sent back.
  • User agent: who the visitor says it is. Here GPTBot. Anyone can type this, so it proves nothing on its own.

The AI bots to look for

This list comes from each company's own documentation, checked on 19 October 2026.

AI crawlers and fetchers, with their official IP lists
User agentCompanyWhat it doesFollows robots.txtIP list
OAI-SearchBotOpenAISearch indexYesOAI-SearchBot JSON (opens in a new tab)
GPTBotOpenAITrainingYesGPTBot JSON (opens in a new tab)
ChatGPT-UserOpenAIUser requestPartlyChatGPT-User JSON (opens in a new tab)
Claude-SearchBotAnthropicSearch indexYesClaude-SearchBot JSON (opens in a new tab)
ClaudeBotAnthropicTrainingYesClaudeBot JSON (opens in a new tab)
Claude-UserAnthropicUser requestYesClaude-User JSON (opens in a new tab)
PerplexityBotPerplexitySearch indexYesPerplexityBot JSON (opens in a new tab)
Perplexity-UserPerplexityUser requestNoPerplexity-User JSON (opens in a new tab)
GooglebotGoogleSearch engineYesGooglebot JSON (opens in a new tab)
Google-AgentGoogleUser requestNoGoogle-Agent JSON (opens in a new tab)Google-Agent JSON (opens in a new tab)Google-Agent JSON (opens in a new tab)
bingbotMicrosoftSearch engineYesbingbot JSON (opens in a new tab)
ApplebotAppleSearch engineYesApplebot JSON (opens in a new tab)
meta-externalagentMetaTrainingYesNone published
meta-webindexerMetaSearch indexYesNone published
meta-externalfetcherMetaUser requestPartlyNone published
AmazonbotAmazonTrainingYesNone published
Amzn-SearchBotAmazonSearch indexYesNone published
Amzn-UserAmazonUser requestPartlyNone published
DuckAssistBotDuckDuckGoSearch indexYesDuckAssistBot JSON (opens in a new tab)
MistralAI-UserMistral AIUser requestYesNone published
MistralAI-IndexMistral AISearch indexNot statedNone published
MistralAI-TrainingMistral AITrainingYesNone published
CCBotCommon CrawlTrainingYesCCBot JSON (opens in a new tab)

Google-Extended and Applebot-Extended are robots.txt tokens, not crawlers. They never appear in a log.

Anthropic doesn't publish full user agent strings. In logs they look like β€œcompatible; Claude-User/1.0; +claudebot@anthropic.com”.

Copy-paste commands

These work on a combined-format log. We tested them on 19 October 2026 with macOS grep and awk. Replace access.log with your file.

Count requests per AI bot
grep -oE 'GPTBot|OAI-SearchBot|ChatGPT-User|ClaudeBot|Claude-User|Claude-SearchBot|PerplexityBot|Perplexity-User|meta-externalagent|Amazonbot|Applebot|DuckAssistBot|MistralAI-User|CCBot' access.log | sort | uniq -c | sort -rn
Status codes per bot
awk -F'"' '{ split($3,a," "); if (match($6,/GPTBot|OAI-SearchBot|ChatGPT-User|ClaudeBot|Claude-User|Claude-SearchBot|PerplexityBot|Perplexity-User/)) print substr($6,RSTART,RLENGTH), a[1] }' access.log | sort | uniq -c
Top pages for one bot
grep 'OAI-SearchBot' access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head
Only errors (4xx and 5xx) for AI bots
awk -F'"' '$6 ~ /GPTBot|OAI-SearchBot|ChatGPT-User|ClaudeBot|Claude-User|Claude-SearchBot|PerplexityBot|Perplexity-User/ { split($3,a," "); if (a[1] >= 400) print a[1], $2 }' access.log
Search older, gzipped logs
zgrep -c 'GPTBot' /var/log/nginx/access.log.*.gz

Check every bot IP with Python

This script downloads the official IP lists and prints VERIFIED or NOT IN LIST for each bot line. It only uses Python's standard library.

verify_bots.py
# Usage: python3 verify_bots.py access.log
import ipaddress, json, re, sys, urllib.request

LISTS = {
    "GPTBot": "https://openai.com/gptbot.json",
    "OAI-SearchBot": "https://openai.com/searchbot.json",
    "ChatGPT-User": "https://openai.com/chatgpt-user.json",
    "ClaudeBot": "https://claude.com/crawling/bots.json",
    "Claude-User": "https://claude.com/crawling/bots.json",
    "Claude-SearchBot": "https://claude.com/crawling/bots.json",
    "PerplexityBot": "https://www.perplexity.com/perplexitybot.json",
    "Perplexity-User": "https://www.perplexity.com/perplexity-user.json",
    "Googlebot": "https://developers.google.com/static/crawling/ipranges/common-crawlers.json",
    "bingbot": "https://www.bing.com/toolbox/bingbot.json",
}
cache = {}

def networks(url):
    if url not in cache:
        req = urllib.request.Request(url, headers={"User-Agent": "log-check/1.0"})
        data = json.load(urllib.request.urlopen(req, timeout=20))
        cache[url] = [ipaddress.ip_network(p.get("ipv4Prefix") or p.get("ipv6Prefix"))
                      for p in data["prefixes"]]
    return cache[url]

bot = re.compile("|".join(sorted(map(re.escape, LISTS), key=len, reverse=True)))
for line in open(sys.argv[1], errors="replace"):
    ua = line.split('"')[5] if line.count('"') >= 6 else line
    match = bot.search(ua)
    if not match:
        continue
    try:
        ip = ipaddress.ip_address(line.split()[0])
    except ValueError:
        continue
    ok = any(ip in net for net in networks(LISTS[match.group(0)]))
    print("VERIFIED   " if ok else "NOT IN LIST", match.group(0), ip)

Is it really GPTBot? Check the IP

A user agent is just text. Anyone can send β€œGPTBot”. Perplexity itself recommends combining user agent matching with IP verification.

Way 1: the official IP lists

OpenAI, Anthropic, Perplexity, Google, Microsoft (Bing), Apple, DuckDuckGo and Common Crawl publish JSON lists of the IP ranges their bots use. If the IP is in the list, the request came from that company's network. The links are in the table above.

Way 2: reverse DNS

Google: look up the IP's hostname. It must end in googlebot.com, google.com or googleusercontent.com, and looking up that name must give the same IP back. Bing works the same way, with names ending in search.msn.com.

Reverse DNS check for Googlebot
host 66.249.66.1
# 1.66.249.66.in-addr.arpa domain name pointer crawl-66-249-66-1.googlebot.com.
host crawl-66-249-66-1.googlebot.com
# crawl-66-249-66-1.googlebot.com has address 66.249.66.1  ← same IP: real Googlebot

β€œNot in the list” doesn't always mean fake. Lists change, and Bing's JSON file was last generated in January 2024. Treat it as β€œcheck this”, not as proof.

Anthropic warns that blocking by IP β€œmay not work correctly or persistently guarantee an opt-out”. Use robots.txt to opt out.

Sources

  • Google: verify Googlebot (opens in a new tab)
  • Bing: verify bingbot (opens in a new tab)
  • Perplexity: bots (opens in a new tab)

What the numbers tell you

  • Training, search and user requests are different. GPTBot and ClaudeBot collect training data. OAI-SearchBot, Claude-SearchBot and PerplexityBot build search indexes. ChatGPT-User, Claude-User and Perplexity-User fetch a page because a person asked about it right now.
  • Lots of 403 or 5xx answers mean you're blocking or breaking AI access. Check your firewall, your CDN's bot settings and your robots.txt.
  • robots.txt and llms.txt requests show which bots read your rules. OpenAI says OAI-SearchBot and GPTBot may add a robots.txt marker to their user agent when they fetch that file.
  • User requests may skip robots.txt. OpenAI says robots.txt rules may not apply to ChatGPT-User, and Perplexity says Perplexity-User generally ignores them.
  • A visit isn't a citation. It means a bot read your page, not that any AI answer will quote it.
  • Set up robots.txt for AI crawlers
  • How to get your pages cited by AI

No server access? Use your CDN

Cloudflare's AI Crawl Control (formerly AI Audit) shows which AI services crawl your site and which crawlers ignore your rules. Cloudflare says it's available on all plans.

Cloudflare Logpush can export request logs with fields such as ClientIP, ClientRequestUserAgent, ClientRequestPath and EdgeResponseStatus. Our analyzer reads those JSON lines too.

Sources

  • Cloudflare AI Crawl Control (opens in a new tab)
  • Cloudflare Logpush fields (opens in a new tab)

Logs and privacy (GDPR)

IP addresses can be personal data. The EU Court of Justice said so for dynamic IP addresses in the Breyer case (C-582/14, 19 October 2016), and recital 30 of the GDPR names IP addresses as online identifiers.

Bot IPs belong to companies, but the same log also holds your visitors' IPs. A practical approach:

  • Filter out the bot lines first, and work with those.
  • Keep raw logs only as long as you need them, for example for security. The GDPR sets no fixed number of days; it says not to keep personal data longer than necessary.
  • Store totals (bot, day, page, status, verified or not) instead of IPs.
  • Shorten or hash an IP once you've checked it.
  • Don't upload raw logs to an outside tool without a data processing agreement. Our analyzer runs in your browser, so nothing is uploaded.

This is general information, not legal advice.

Sources

  • CJEU, case C-582/14 (Breyer) (opens in a new tab)
  • GDPR recital 30 (opens in a new tab)

Frequently asked questions

How do I see if ChatGPT visits my site?

Search your access log for OAI-SearchBot (ChatGPT search), ChatGPT-User (a user's request) and GPTBot (training). Then check the IPs against OpenAI's lists.

Why doesn't Google Analytics show GPTBot?

Google Analytics counts visits through a script in the browser. Crawlers that only download your HTML don't run it.

How do I know a GPTBot request is real?

Check its IP against openai.com/gptbot.json. If it isn't in the list, treat the request as unverified.

Which bots ignore robots.txt?

By their own documentation: bots that fetch a page because a user asked. OpenAI says robots.txt may not apply to ChatGPT-User, Perplexity says Perplexity-User generally ignores it, and Google says the same about its user-triggered fetchers.

What do 403 errors for AI bots mean?

Your server, firewall or CDN refused the request. If you want to be found in AI search, find the rule that blocks the bot and change it.

Am I allowed to log IP addresses?

Usually yes, for a clear purpose such as security, but IPs can be personal data. Keep logs for a short time, store totals instead of IPs, and mention logging in your privacy policy. This isn't legal advice.

Keep learning

  • Free AI Bot Log Analyzer (runs in your browser)
  • Configure robots.txt for AI crawlers
  • Reference: AI bot user agents
  • The llms.txt guide
  • Robots.txt generator for AI bots
  • Track visits from AI tools

Make sure bots find something worth reading

Crawled isn't cited. See how AI tools read your page, across 22 checks.

Analyze my page