User agents lie
Any scraper can send "GPTBot" or "ClaudeBot". Blocking or allowing on the header alone rewards whoever copies it.
Use case — AI crawlers
Training crawlers, AI search fetchers and user-triggered agents announce themselves in a user-agent string that anyone can copy. The IP address is harder to fake. risk.is_ai tells you whether a request comes from address space an AI operator publishes as its own.
01 — The problem
Any scraper can send "GPTBot" or "ClaudeBot". Blocking or allowing on the header alone rewards whoever copies it.
Operators add and retire ranges. A hard-coded list in your firewall drifts out of date without anyone noticing.
Rate limit, serve a licence notice, log for analytics or let it through: you want one boolean at request time.
02 — How it works
{
// …
"country_code": "US",
"asn": "15169",
"risk": {
"is_ai": true,
"is_crawler": false,
"is_scanner": false
}
}
03 — Recipe
Call the API from your server, never from the browser, so your key stays private. Cache answers per IP on your side to save requests.
// Refuse requests from published AI crawler infrastructure.
// Needs a Pro key. Behind a proxy, set app.set('trust proxy', ...) so req.ip is the client.
const LOOKUP = 'https://fast.ipapi.gr/api/lookup/';
async function blockAiCrawlers(req, res, next) {
try {
const r = await fetch(LOOKUP + encodeURIComponent(req.ip) + '?key=' + process.env.IPAPI_KEY,
{ signal: AbortSignal.timeout(1500) });
if (r.ok) {
const { risk } = await r.json();
if (risk && risk.is_ai) return res.status(403).send('Automated AI access is not permitted.');
}
} catch {
// Fail open: a lookup error should never lock out real visitors.
}
next();
}
app.use(blockAiCrawlers);
04 — Honest limits
05 — Questions
Every operator listed on the bot signals coverage page, generated from the same source list the API uses. It includes published ranges for crawlers such as GPTBot, ClaudeBot and PerplexityBot.
No. The risk object with is_ai, is_crawler and is_scanner is part of the Pro plan. Free keys return geolocation and network data.
Yes. Call the lookup from your server or edge for the client IP and refuse, rate limit or tag the request when risk.is_ai is true. Many operators also honour robots.txt, which you can use alongside it.
From the blog
Pro: 40,000,000 requests a day with is_ai, is_crawler and is_scanner.