Use case — Scanners

Filter internet-wide scanners out of your signal.

Research and attack-surface scanners probe every public address, all the time. They fill logs, trip alerts and skew analytics. risk.is_scanner flags addresses that scanning projects publish or verifiably identify as their own.

risk.is_scanner Pro 66 sources covered →

01 — The problem

Why it's harder than it looks.

01

Noisy alerts

Port and vulnerability scans from known research projects look like attacks and drown out the ones that matter.

02

Skewed metrics

Scanner hits on login and API endpoints inflate error rates and traffic counts.

03

Many projects, many formats

Some publish IP feeds, some register dedicated networks, some only set reverse DNS. Keeping up by hand doesn't scale.

02 — How it works

One lookup, one answer.

  1. Scanner projects' own publications (IP feeds, published ranges and registry assignments for dedicated networks) are imported and refreshed.
  2. Projects that identify themselves through reverse DNS are verified with a forward-confirmed lookup.
  3. Addresses first seen in a lookup can be verified in the background, so they may become flagged shortly after the first request.
GET /api/lookup/{ip}Pro response (abridged)
{
  // …
  "country_code": "US",
  "asn": "15169",
  "risk": {
    "is_ai": false,
    "is_crawler": false,
    "is_scanner": true
  }
}

03 — Recipe

Drop-in example.

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.

JavaScript (Node.js)
// Tag internet-scanner traffic so it can be filtered out of alerts and analytics.
const LOOKUP = 'https://fast.ipapi.gr/api/lookup/';
const seen = new Map(); // cache per IP: scanners hit you repeatedly

async function isScanner(ip) {
  if (seen.has(ip)) return seen.get(ip);
  const r = await fetch(LOOKUP + encodeURIComponent(ip) + '?key=' + process.env.IPAPI_KEY,
    { signal: AbortSignal.timeout(1500) });
  if (!r.ok) return false;
  const { risk } = await r.json();
  const flag = Boolean(risk && risk.is_scanner);
  seen.set(ip, flag);
  return flag;
}

// e.g. in your request logger
if (await isScanner(req.ip)) logEntry.tags.push('internet-scanner');

04 — Honest limits

What it won't tell you.

  • is_scanner covers known, self-identifying scanning projects. Attackers who don't publish their addresses are not in it.
  • false means no current match, not that the address is safe.
  • Blocking well-behaved research scanners hides you from their reports. Many teams log or tag instead of blocking.

05 — Questions

Good to know.

More in the FAQ and the docs.

Which scanners are detected?

The bot signals coverage page lists every scanning project, generated from the same catalogue the API uses, with how each one is identified.

Should I block scanners?

It depends. Tagging scanner traffic keeps alerts and analytics clean. Blocking it also stops research projects from reporting exposures to you.

Is scanner detection on the free plan?

No. risk.is_scanner is part of the Pro plan.

Add bot signals to every lookup.

Pro: 40,000,000 requests a day with is_ai, is_crawler and is_scanner.