How to block AI crawlers on your own site
A number of AI companies run automated crawlers that fetch pages to train models, to answer search queries, or to fetch a page on a user's behalf. Each one announces itself with a User-Agent string, documented by its own operator. Below are copyable rules to block the announced list at your server, your CDN, or in robots.txt.
Two things worth knowing before you use any of this. A User-Agent header is whatever the sender chose to send, so a rule matches what a request claimed to be, not who actually sent it; a rule here can be worked around by anything willing to lie about its identity. And robots.txt is a request, not a lock: a crawler that honours it stops, and nothing stops the rest. Want to see which of these, if any, actually reach your site before you block anything? Try the free log checker.
The list this covers
Tokens below are the announced crawler user agents, read from each operator's own documentation: OpenAI (GPTBot, OAI-SearchBot, ChatGPT-User); Anthropic (ClaudeBot, Claude-SearchBot, Claude-User, anthropic-ai, claude-web); Common Crawl (CCBot); Perplexity (PerplexityBot, Perplexity-User); ByteDance (Bytespider); Amazon (Amazonbot); Meta (Meta-ExternalAgent, Meta-ExternalFetcher, FacebookBot); Apple (Applebot-Extended); Google (Google-Extended); Cohere (cohere-ai, cohere-training-data-crawler); Mistral AI (MistralAI-User); DuckDuckGo (DuckAssistBot); You.com (YouBot); Allen Institute for AI (AI2Bot); Diffbot (Diffbot); Timpi (Timpibot); Webz.io (omgili); ImageSift (ImagesiftBot). A user agent can be forged, so this says what a request claims to be, not who sent it. Source list and citations: src/aicrawlers.js in this site's repository.
nginx
Inside the server { } block for your site. Reload nginx after adding it (nginx -t, then nginx -s reload). Matched requests get a 403.
# Inside the server { } block for your site
if ($http_user_agent ~* "(GPTBot|OAI-SearchBot|ChatGPT-User|ClaudeBot|Claude-SearchBot|Claude-User|anthropic-ai|claude-web|CCBot|PerplexityBot|Perplexity-User|Bytespider|Amazonbot|Meta-ExternalAgent|Meta-ExternalFetcher|FacebookBot|cohere-ai|cohere-training-data-crawler|MistralAI-User|DuckAssistBot|YouBot|AI2Bot|Diffbot|Timpibot|omgili|ImagesiftBot)") {
return 403;
}
Apache
In the virtual host, or in .htaccess when AllowOverride permits rewrites. Needs mod_rewrite. Matched requests get a 403.
# In the virtual host or .htaccess (needs mod_rewrite)
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} (GPTBot|OAI-SearchBot|ChatGPT-User|ClaudeBot|Claude-SearchBot|Claude-User|anthropic-ai|claude-web|CCBot|PerplexityBot|Perplexity-User|Bytespider|Amazonbot|Meta-ExternalAgent|Meta-ExternalFetcher|FacebookBot|cohere-ai|cohere-training-data-crawler|MistralAI-User|DuckAssistBot|YouBot|AI2Bot|Diffbot|Timpibot|omgili|ImagesiftBot) [NC]
RewriteRule ^ - [F,L]
</IfModule>
Cloudflare (WAF rule)
Security → WAF → Custom rules → Create rule → Edit expression: paste this and choose Block.
(lower(http.user_agent) contains "gptbot") or (lower(http.user_agent) contains "oai-searchbot") or (lower(http.user_agent) contains "chatgpt-user") or (lower(http.user_agent) contains "claudebot") or (lower(http.user_agent) contains "claude-searchbot") or (lower(http.user_agent) contains "claude-user") or (lower(http.user_agent) contains "anthropic-ai") or (lower(http.user_agent) contains "claude-web") or (lower(http.user_agent) contains "ccbot") or (lower(http.user_agent) contains "perplexitybot") or (lower(http.user_agent) contains "perplexity-user") or (lower(http.user_agent) contains "bytespider") or (lower(http.user_agent) contains "amazonbot") or (lower(http.user_agent) contains "meta-externalagent") or (lower(http.user_agent) contains "meta-externalfetcher") or (lower(http.user_agent) contains "facebookbot") or (lower(http.user_agent) contains "cohere-ai") or (lower(http.user_agent) contains "cohere-training-data-crawler") or (lower(http.user_agent) contains "mistralai-user") or (lower(http.user_agent) contains "duckassistbot") or (lower(http.user_agent) contains "youbot") or (lower(http.user_agent) contains "ai2bot") or (lower(http.user_agent) contains "diffbot") or (lower(http.user_agent) contains "timpibot") or (lower(http.user_agent) contains "omgili") or (lower(http.user_agent) contains "imagesiftbot")
robots.txt
Put this at the root of your site as /robots.txt. It only asks; see the note above on which crawlers actually stop for it.
# robots.txt is a request, not a lock: crawlers that honour it stop, others do not. User-agent: GPTBot User-agent: OAI-SearchBot User-agent: ChatGPT-User User-agent: ClaudeBot User-agent: Claude-SearchBot User-agent: Claude-User User-agent: anthropic-ai User-agent: claude-web User-agent: CCBot User-agent: PerplexityBot User-agent: Perplexity-User User-agent: Bytespider User-agent: Amazonbot User-agent: Meta-ExternalAgent User-agent: Meta-ExternalFetcher User-agent: FacebookBot User-agent: cohere-ai User-agent: cohere-training-data-crawler User-agent: MistralAI-User User-agent: DuckAssistBot User-agent: YouBot User-agent: AI2Bot User-agent: Diffbot User-agent: Timpibot User-agent: omgili User-agent: ImagesiftBot User-agent: Applebot-Extended User-agent: Google-Extended Disallow: /
Check it worked
A rule you cannot verify is a guess. Paste your access log into the free log checker to see which of these, if any, hit your site before and after you apply a rule; the log is read in your browser and never uploaded. If you would rather not do this yourself, Signal Nodus applies rules like these to your site and checks they hold for 350 USD: the done-for-you service.