Skip to content
IP IPBot
Get Started

Changelog

All notable changes to IPBot are documented here. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

  • ASN hosting-role inheritance — a monthly offline inventory aggregates IP2Proxy datacenter evidence across each ASN’s IPv4 ranges (with PeeringDB access-network veto and contradiction-sample rejection) so hosting ASNs outside every keyword, overlay, and per-IP signal — notably their IPv6 space — now classify with is_datacenter, usage_type=datacenter, network.category=datacenter, and decision.role=datacenter. Inherited roles are classification evidence only and add zero risk-score weight. The IP2Proxy download now prefers the IPV6 BIN variant (IPv4+IPv6 coverage) with automatic fallback. Curated coverage added for Spartan Host, VirMach, Hosteons, GreenCloudVPS, and Crunchbits, including corrections where PeeringDB self-reported types were wrong; budget-hosting risk keywords extended accordingly (evidence-tiered, per existing Tier-3 semantics).

  • Programmable IP-quality parity — legacy / and /{ip} lookups now support deterministic plain-text output through ?format=text or Accept: text/plain, including a four-line detail=1 form for shell scripts. Canonical /v1 endpoints remain JSON-only.

  • Publisher-reviewed RFC 8805 corroboration — a new atomic geofeed update pipeline, reloadable longest-prefix index, readiness reporting, and conservative mapper truth table can raise classification.country_alignment.confidence to high only when a reviewed operator publication corroborates the estimated country. The current authority check is publisher-level rather than per-prefix; unreviewed rows are ignored, conflicts return unknown, and score_effect remains 0.

  • Reloadable operator directory — curated ASN/operator records can now overlay the built-in map and expose the optional display-only network.operator_domain; lookup and ASN pages render verified official hostnames as outbound links. Missing data falls back to built-ins and never changes scoring.

  • Local-only environment consistency checks — after an explicit Diagnose action, the dual-stack diagnostic compares the supplied IPv4/IPv6 countries with each other and with browser timezone/language hints. Those browser values stay in the page and are not added to the API request.

  • IP-quality guidance and documentation — lookup results include a collapsed, advisory use-case view derived from the existing scenario decisions, plus new Native IP and neutral IPBot-versus-Ping0 documentation pages.

  • Independent-label benchmark foundation — a standard-library runner now captures public API predictions against approved, time-bounded labels and reports per-task coverage, precision, recall, specificity, and false-positive rate without treating risk_score as a probability. It fails closed on expired labels, mixed builds, incomplete build metadata, IP mismatches, and unsupported provenance; reports remain claim_status=not_approved until separate human and license review.

  • Accuracy & Methodology page/accuracy now states which regression, safety, source-readiness, and shadow properties IPBot measures, which real-world accuracy and calibration properties remain unmeasured, and the evidence required before a public benchmark claim.

  • Privacy-safe product-use telemetry — Prometheus and Grafana now separate canonical product endpoints by bounded access tier, client class, and status family without IP, queried-address, user-agent, account, or API-key labels.

  • The lookup Country Alignment section now sits after Location and presents observed GeoIP country and registration country side by side with plain-language alignment labels, while preserving the five-state API status and its evidence-only semantics.
  • Application request logs now retain canonical route, status, timing, response size, bounded tier, and bounded client class instead of raw request paths, raw user agents, or client-IP hashes. Privacy and pricing copy now disclose request processing, account records, usage counters, sessions, and normalized RDAP caching instead of claiming the service is completely stateless.
  • Public positioning now describes estimated location and explainable risk evidence rather than promising fraud detection, a calibrated probability, fixed geolocation accuracy, or unmeasured response times. Structured data no longer includes a fabricated aggregate rating, an unimplemented site-search action, or invisible FAQ claims.
  • Solutions documentation links now use their real routes, and the sitemap excludes login, dashboard, and internal pages.
  • The stale free-ip-geolocation-apis-2026 article, whose quota, pricing, latency, and accuracy tables were not supported by a reproducible current methodology, is retired with a permanent redirect to the maintained comparison page.
  • Risk presentation aligned with decision semantics — the IP lookup risk color now follows the API verdict/band (allow → green, monitor → amber, challenge → orange, block → red), with numeric thresholds only as a fallback for older APIs, so visual severity matches the Decision Engine rather than a raw number. Sub-scores now show direction correctly: adverse scores (abuse, routing risk) escalate in color, Trust and Evidence Quality read as positive, and Infrastructure is neutral context. The Risk Score is now labeled an evidence-derived model score (not a fraud probability), to be read together with Threat Evidence and Decision. Lookup data copy is corrected accordingly (country/region/city as GeoIP estimates, ISP/ASN as network/routing identity).
  • The datacenter-IP “danger” alert and the Surfshark affiliate link have been removed from lookup results — a network-type observation is no longer presented as a threat, and product judgment is no longer mixed with a commercial call-to-action.
  • P4 continuity scoring shadow — an internal-only, non-selectable candidate now records a two-decimal exact score, a rounded hypothetical verdict preview, active/current deltas, model versions, and explicit calibration_status=not_measured in the admin score trace. Independent low-cardinality metrics and a reproducible fixed-corpus report support a 7–14 day shadow evaluation. It does not change any public response, score, verdict, action, or Decision Engine output.
  • Special-use threat suppression across source-tier scoring — a threat-feed match suppressed by the routability guard for special-use/bogon addresses can no longer be resurrected by the source-tier community-threat floor. The floor now requires an actual unsuppressed threat:* scoring input.
  • Public score documentation no longer describes the evidence-derived 0–100 model value as an outcome-calibrated abuse probability; real calibration remains unmeasured without independently defined outcome labels.
  • Five-axis lookup results — the IP lookup tool (and the compact demo on the homepage and What Is My IP) now presents results along five independent axes so source, network, anonymity, evidence, and risk can no longer be conflated: IP Source (the country_alignment tendency with fixed help copy explaining that “native” only compares registration and estimated GeoIP countries), Network (location + network + the former “Security” card, renamed Network Profile, minus risk/proxy/threat rows that belonged elsewhere), Anonymity (proxy/VPN/Tor/residential-proxy/privacy-relay in one place), Threat Evidence (direct-record vs prefix-context vs no-record state from evidence.summary, the sampled /24 context, threat level, main risk reasons, and threat/context signals), and Risk & Decision (score verdict and recommended action now live with the Decision Engine output). Cross-region (“non-native”) tendency renders in an amber warning tone, never the danger tone. On older API versions without the new fields, the Source and Threat Evidence states hide instead of guessing.
  • Contract tighteningclassification.country_alignment and evidence.summary are now documented as always present (non-null) on v1 IP responses, matching runtime behavior since 1.12.0.
  • The lookup UI’s never-populated ASN Insights/Services/Users-by-Location/Related-ASNs sections (driven by the removed network.radar field) are gone from the IP lookup results.
  • Decision proxy precedence — ISP/residential context can no longer hide generic proxy (CPN, EPN, PROXY, or subtype-less proxy) or known-abuser evidence. Generic proxies now use role=proxy, profile=anonymizing_network, the proxy expected-loss class, and a minimum monitor guardrail; verified crawlers, public DNS resolvers, and private relays remain protected from conflicting proxy evidence. The public Decision Engine policy identifier is now decision-v1-2026-07.1.
  • Classification and alignment edge cases — CDN/operator overrides now clear heuristic DCH labels and flags together; malformed or unknown country-code sentinels no longer produce an alignment verdict; dynamic bogons report bogon_address instead of special_use_address.
  • Evidence summary semantics — documentation now states that risk_score=0 can result from suppression, trust offsets, or rounding even when a direct threat record exists. Clients should use evidence.summary.direct_threat_match to answer that question.
  • Radar public boundary and ASN fallback — the default-off IPBOT_RADAR_PUBLIC_ENABLED gate now covers both the ASN radar block and Radar-derived public IP operator/category fields. Internal Radar shadow telemetry remains independent. ASN pages always show local ASN identity when optional enrichment is absent and no longer suggest retrying a stable radar: null response.
  • Range-reputation scoring prototype retired — the dormant scoring flag, score input, metrics, staging configuration, and active monitoring instructions have been removed. evidence.prefix_threat_context remains available, but it is now evidence-only by code construction: score_effect=0 and no path into riskProbs.
  • Public score.risk_score, score.verdict, and score.recommended_action remain unchanged; the Decision Engine’s role, profile, scenarios, and advisory action intentionally change for the corrected proxy/known-abuser combinations.
  • classification.country_alignment — an explainable answer to the “native IP” question. Instead of a bare is_native boolean, v1 IP responses now compare the estimated GeoIP country with the registration countries (RDAP allocation first, RIR delegation as fallback) and report status (aligned / mismatch / multi_region / unknown / not_applicable), the input countries, basis, machine-readable reason_codes, and a confidence capped at medium (GeoIP estimates usage location — it cannot prove physical server location; high is reserved for publisher-reviewed operator geofeeds, RFC 8805). Anycast and public-resolver services report multi_region; a contested BGP origin or an RDAP-vs-RIR country conflict reports unknown. Descriptive only: score_effect is always 0.
  • evidence.summary + evidence.prefix_threat_context — v1 IP responses now separate “this exact IP has a direct threat record” (direct_threat_match) from “only the surrounding /24 shows threat-list coverage” (prefix_context_only). For IPv4, prefix_threat_context reports sampled threat-list coverage of the surrounding /24 (sampled_hosts, matched_hosts, method sampled_hosts_v1), plus a Prefix Threat Context evidence signal when only the neighborhood matches. Evidence-only: score_effect is always 0, it never enters scoring and never flips a verdict. A risk_score of 0 is not an assertion that no direct record exists; suppression, trust offsets, and rounding can also produce zero, so clients should read direct_threat_match explicitly.
  • Residential decision role — residential IPs (usage type ISP / residential operator category) now reach their dedicated Decision Engine role (role=residential, profile=ordinary_residential) instead of falling through to unknown_low_confidence. More specific roles (proxy, mobile, datacenter…) still take precedence.
  • Classification coherence — ASN/operator-tier context can no longer erase IP-level evidence or leave contradictory output such as usage_type=datacenter with is_datacenter=false. Per-IP datacenter evidence (IP2Proxy) always survives the operator tier; heuristic ASN-keyword classifications may be overridden by the operator classification, but the flag and the usage label now always change together.
  • Cloudflare Radar public redistribution is now opt-in and off by default (IPBOT_RADAR_PUBLIC_ENABLED). Radar API data is licensed CC BY-NC 4.0, so the radar block on GET /v1/asn/{asn} (and the legacy alias) returns null unless public redistribution is explicitly enabled under a separate license. Internal shadow telemetry remains independently controlled; 1.12.1 also places Radar-derived public operator fields behind this gate. The never-populated network.radar field on IP responses has been removed from the contract, and documentation examples that referenced it now use network.operator_type.
  • Public score.risk_score, score.verdict, and score.recommended_action are unchanged by all of the above (shadow scoring report byte-identical before/after).
  • GET /v1/asn/{asn} — the ASN context endpoint now has a canonical v1 path (the legacy /asn/{asn} stays as a compatibility alias). The response adds a top-level name that prefers IPBot’s local ASN database over Radar, and an evidence-only asndrop block when the ASN is on Spamhaus ASN-DROP. Cloudflare Radar enrichment is now optional: if Radar is unavailable or the lookup fails, the endpoint returns 200 with local fields and radar: null instead of an error.
  • evidence.threatfox metadata — when the optional ThreatFox sidecar dataset is present and the IP already matched the ThreatFox C2 threat feed, v1 IP responses add the malware family, first/last-seen timestamps, and IOC confidence level, plus a ThreatFox IOC Context evidence signal. This is metadata only — it adds no score beyond the existing THREAT_LIST:threatfox hit. ThreatFox data © abuse.ch, CC0.
  • Hot reload (SIGHUP) is now resilient and observable: one failing data module no longer skips the remaining modules, failures are logged and aggregated, and the runtime exposes ipbot_reload_last_success_timestamp_seconds with a stale-reload alert. The nightly data-refresh chain now triggers a single reload at the end instead of one per update step.
  • The fields projection parameter documentation now lists all twelve supported top-level fields, including decision, scores, scenarios, and explanation.
  • Public score.risk_score, score.verdict, and score.recommended_action are unchanged by all of the above.
  • Spamhaus ASN-DROP evidence — when the announcing ASN appears in the Spamhaus ASN-DROP list, responses include a Spamhaus ASN-DROP evidence signal and a legacy ASN_DROP:spamhaus risk reason. This is ASN-level reputation evidence only — it does not change the IP risk score by itself. ASN-DROP data © Spamhaus Project, used with attribution.
  • ASN threat density — an offline-precomputed measure of how much of an ASN’s announced IPv4 space appears on loaded threat lists. Surfaces as an ASN Threat Density evidence signal on IP lookups (when significant) and as an additive threat_density block on GET /asn/{asn} (ratio, percent, threat_network_count, threat_ipv4_addresses, total_ipv4_addresses, significant). Evidence only; computed from threat lists + IPtoASN, refreshed on data reload.
  • Recently Allocated Network signal — when RDAP registration data shows the network was allocated within the last 90 days, responses include a Recently Allocated Network evidence signal (REGISTRATION_RECENT:<90d reason). Evidence only.
  • Spamhaus eDROP retired — Spamhaus merged eDROP into DROP upstream, so the standalone eDROP feed is no longer fetched or tracked; IP/CIDR coverage continues via DROP. The new ASN-DROP feed replaces it in the data stack with ASN-level evidence.
  • PeeringDB operator enrichment now auto-refreshes when the cached snapshot is older than 7 days (previously it was only downloaded once).
  • GET /health and the X-IPBot-Build header now always carry the real git_sha and build_time for production deploys.
  • Public score.risk_score, score.verdict, and score.recommended_action are unchanged by all of the above.
  • POST /v1/crawler/verify — a narrow crawler-verification endpoint for site-owner workflows. Given an ip and optional user_agent, it returns a verification_status of verified, known_unverified, or not_known, plus crawler classification (crawler_provider, crawler_type, crawler_verified_by, crawler_hostname), public network owner/allocation context, and an explanation with a machine-stable reason_code. DNS-verifiable families (Googlebot, Bingbot) can reach verified from the IP alone via reverse+forward DNS; OpenAI-family crawlers require both official range membership and a matching crawler user-agent token, otherwise they stay known_unverified (reason_code: user_agent_mismatch). Documented in docs/openapi.v1.yaml.
  • Crawler verification tool and hub on the site: a /crawler-verify interactive tool (URL round-tripping, presets, accessible status), a /crawlers hub, and per-crawler /crawlers/{slug} detail pages backed by a versioned crawler catalog.
  • The main IP lookup and the new endpoint share crawler range/DNS resolution, but intentionally have different caller-context boundaries. Cacheable third-party GET /v1/ip/{ip} ignores the caller User-Agent; POST /v1/crawler/verify accepts the explicitly supplied User-Agent and always returns Cache-Control: no-store. Current/self lookup retains caller telemetry. Public score.risk_score, score.verdict, and score.recommended_action are unchanged.
  • Decision-engine scenarios.*.action is now chosen by expected loss (§8) instead of a static role×scenario table: each surface (content, seo_crawler, login, signup, payment, api) picks the action with the lowest combined cost of being wrong, given the IP’s evidence and that scenario’s stakes. Friction is now evidence-driven and proportionate — a clean IP gets no friction on any surface, while anonymizing/abusive IPs get graduated friction that rises on higher-stakes surfaces. Role floors are also enforced as true minimums (e.g. a Tor exit is at least challenge on every scenario).
  • scenarios.*.confidence is now computed per scenario (from each scenario’s expected-loss margin) rather than reusing the top-level decision.confidence.
  • These are additive decision-engine fields. Public score.risk_score, score.verdict, and score.recommended_action are unchanged.
  • Public risk_score is now computed by the source-tier scoring model. It weights each piece of evidence by the authority of its source (official > registry/routing > commercial > community > heuristic). In practice this reduces false positives on trusted infrastructure — public DNS resolvers, verified crawlers, CDN/edge nodes, and Apple Private Relay sitting on generic datacenter ASNs now score lower (e.g. 8.8.8.8 30 → 12, 1.1.1.1 25 → 10) — and dampens heuristic-only signals, while strong threat, Tor, routing-conflict, and commercial-fraud signals are preserved or strengthened (e.g. a Tor exit stays at its full score; a BGP origin conflict scores higher).
  • score.verdict thresholds are unchanged; most affected IPs move lower within the same verdict band, and any verdict shifts are toward less friction (e.g. monitorallow) on genuinely trusted infrastructure. Two IPs with identical evidence still receive an identical score.
  • This was validated against a promotion gate (zero regressions, zero needs-review cases) before rollout and is reversible. Clients reading score.risk_score/score.verdict should expect slightly lower scores for trusted-infrastructure IPs.
  • decision.confidence is now calculated from a multi-factor model — evidence quality, decision margin (how far the score sits from an action boundary), source authority, contradiction between trust and adverse risk signals, and guardrail stability — instead of a single evidence-quality threshold. Infrastructure context is not treated as adverse by itself. Same schema and low/medium/high values; the levels are simply more accurate.
  • The decision policy identifier is now decision-v1-2026-06.2. Admin-only GET /v1/internal/score/{ip} responses include trace.decision_confidence with the confidence score and component breakdown; public /v1/ip/* responses continue to expose only the low / medium / high confidence enum.
  • At the 1.7.1 release point, scenarios.*.confidence still mirrored the top-level decision.confidence; 1.8.1 later replaced that with per-scenario computed confidence.
  • explanation.drivers[].impact_score is now a true leave-one-out counterfactual (each signal’s marginal effect), so redundant signals in an already-saturated group correctly show a small impact instead of their raw probability.

These remain purely advisory. Public score.risk_score, score.verdict, and score.recommended_action are unchanged.

  • Decision Engine v1: four additive, optional top-level objects on v1 IP lookup responses — decision (profile/role/action/risk_level/confidence/policy_version/allowed_actions/blocked_actions/guardrails_applied), scores (eight 0-100 component sub-scores: risk, base risk, abuse, anonymity, trust, infrastructure, routing risk, evidence quality), scenarios (per-scenario action/risk_level/confidence/reason for content, seo_crawler, login, signup, payment, api), and explanation (summary, key_reason, drivers with direction and impact, guardrails_applied, reason_chain).
  • decision, scores, scenarios, and explanation projection support via fields=.
  • Decision panel in the web IP Lookup tool surfacing role, action, sub-scores, scenarios, and explanation.
  • These fields are purely advisory. Public score.risk_score, score.verdict, and score.recommended_action are unchanged, and clients that ignore the new fields keep working exactly as before.
  • score.risk_score now combines signals with a bounded noisy-OR (probabilistic OR) instead of an additive sum-and-clamp. Multiple risk signals no longer pile up at exactly 100, single-signal scores are unchanged, and two IPs with identical evidence still receive an identical score by design. The value is evidence-derived, not an outcome-calibrated abuse probability.
  • score.verdict thresholds are re-aligned to the public bands so the verdict never contradicts the displayed band: block at risk_score ≥ 61 (danger), challenge at ≥ 41 (poor), monitor at ≥ 31 (fair), otherwise allow.
  • Commercial IP2Proxy fraud scores fold into risk_score as a continuous, bounded probability (replacing fixed buckets); no effect on lite data.
  • GET /health returns a build block (git_sha, build_time, risk_model_version, verdict_threshold_version, rules_version, data_edition), and every response carries an X-IPBot-Build header, so a deployed build is machine-verifiable.
  • Prometheus ipbot_scoring_risk_score histogram and ipbot_scoring_verdicts_total{verdict,band} counter for score-distribution and verdict-mix drift detection.
  • Admin-only GET /v1/internal/score/{ip} scoring trace: every contributing signal with its probability, suppressions, trust dampening, and the noisy-OR result. Never exposed in public or legacy responses.
  • Experimental range-reputation scoring signal: a bounded /24 neighbor-abuse-density estimate computed from existing threat data. It was never enabled in production and was retired in 1.12.1.
  • Pro-only include=rdap_contacts for GET /v1/ip/current and GET /v1/ip/{ip}, returning normalized RDAP network/contact data only after Pro API key authentication.
  • fields=rdap projection support when the Pro RDAP include is accepted.
  • Normalized RDAP contacts, addresses, phones, emails, notices, remarks, and redaction metadata in the ownership cache without storing raw RDAP JSON or raw WHOIS text.
  • Free and anonymous lookup responses continue to expose only network.owner and network.allocation; RDAP contact details remain hidden unless explicitly requested by a Pro key.
  • Evidence-first IP intelligence stack with public proxy, provider, Apple Private Relay, verified crawler, threat, and ASN context.
  • /v1/data/status endpoint for public service and capability readiness.
  • Internal Prometheus counters for lookup volume, signal hit rate, proxy type distribution, residential hits, commercial-field coverage, and conflict/shadow-diff tracking.
  • Tracked OpenAPI v1 contract at docs/openapi.v1.yaml.
  • OpenClaw release smoke support for API Docker smoke and API + Astro preview validation.
  • Proxy detection is now presented as evidence fusion rather than a single-vendor wrapper.
  • Conservative confidence is used when residential/provider/fraud-score evidence is not strong enough for public claims.
  • Verified crawler and Apple Private Relay evidence protect those classes from being treated as ordinary high-risk proxy abuse.
  • Data update scripts preserve last-known-good files on download failure and avoid replacing netintel-ranges.jsonl until normalization succeeds.
  • ASN Insights enrichment data integrated into IP lookup responses
  • Skeleton loader for improved perceived loading performance on web tools
  • Rebranded Radar feature to ASN Insights across all documentation and UI
  • Cache metadata hidden from user-facing responses for cleaner output
  • API key authentication system for enhanced access control
  • Rate limiting with configurable tiers per API key
  • ASN context from Radar-backed enrichment in IP lookup responses
  • Migrated documentation to standalone pages for better SEO
  • Updated branding across all web pages
  • API response parsing for nested ASN structure in Radar data
  • ASN-based risk scoring layer with keyword matching
  • Redis-backed L2 cache for Radar enrichment data
  • Blog infrastructure for content publishing
  • Enhanced landing page with interactive demos
  • Improved documentation with code examples
  • Enhanced frontend performance and UX
  • Initial release of IPBot IP Intelligence API
  • IP geolocation with country, region, city, and coordinates
  • ASN and organization lookup
  • Threat intelligence with risk scoring
  • Explainable risk reasons for auditability
  • CORS-enabled endpoints for browser usage
  • No API key required for free tier
  • Health check endpoint with data version info
  • Hot-reload support for configuration updates