Docs

Response schema

Every successful /v1/check call returns this structure. Fields are stable; new fields may be added over time but existing ones won't change meaning without a version bump.

More signals, fewer false positives. The response now carries eight additional signals: three that catch more abuse (drop-list, bogon, RPKI), three that reduce false positives by recognising benign networks (relay, satellite, public resolver), and two of network context (routing health and RIR allocation). Every signal is one input, not a verdict — read each with its evidence label and combine them yourself.

Breaking change (0.8.0): signals.is_datacenter is gone. A datacenter IP is now signals.connection_type === "datacenter", which also distinguishes "satellite" (e.g. Starlink) and "unknown". The corresponding evidence key is evidence.connection_type (was evidence.datacenter). See the changelog.
{
  "ip": "8.8.8.8",
  "version": 4,
  "geo": {
    "country": "United States",
    "country_code": "US",
    "region": "California",
    "city": "Mountain View",
    "latitude": 37.4,
    "longitude": -122.1,
    "timezone": "America/Los_Angeles"
  },
  "network": {
    "asn": 15169,
    "as_org": "Google LLC",
    "is_announced": true,
    "is_bogon": false,
    "rpki": "valid",
    "allocation_date": "2000-03-30",
    "allocation_age_days": 9566,
    "registration_country": "US"
  },
  "signals": {
    "connection_type": "datacenter",
    "datacenter_provider": "gcp",
    "relay_provider": null,
    "is_relay": false,
    "is_tor": false,
    "is_vpn": false,
    "is_proxy": false,
    "is_public_resolver": true,
    "is_drop_listed": false,
    "recent_abuse": false,
    "is_verified_bot": false,
    "verified_bot_name": null
  },
  "evidence": {
    "connection_type": "authoritative",
    "tor": "authoritative",
    "vpn": "inferred",
    "proxy": "beta",
    "verified_bot": "authoritative",
    "relay": "authoritative",
    "routing": "authoritative",
    "allocation": "authoritative",
    "drop_listed": "authoritative",
    "recent_abuse": "beta",
    "public_resolver": "authoritative"
  },
  "risk": {
    "score": 20,
    "level": "low",
    "reasons": [
      "connection_type:datacenter",
      "benign_network_kind"
    ]
  },
  "attribution": "https://geoq.io/attributions"
}

Fields

FieldTypeDescription
ipstringThe IP address that was checked.
versionnumberIP version: 4 or 6.
geo.countrystringCountry name.
geo.country_codestringISO 3166-1 alpha-2 country code.
geo.regionstringRegion / state (best-effort).
geo.citystringCity (best-effort).
geo.latitudenumberApproximate latitude of the network.
geo.longitudenumberApproximate longitude of the network.
geo.timezonestringIANA timezone, e.g. America/Los_Angeles.
network.asnnumberAutonomous System Number.
network.as_orgstringAS organisation name.
network.is_announcedbooleanWhether a route for this IP is seen in public BGP tables.
network.is_bogonbooleanIP is a bogon — unallocated or reserved space that should never source traffic.
network.rpkistringRoute origin validation state: valid / invalid / unknown.
network.allocation_datestring|nullWhen the RIR delegated this range (ISO date), or null.
network.allocation_age_daysnumber|nullDays since allocation_date, or null.
network.registration_countrystring|nullISO country code the range is registered to (may differ from geo).
signals.connection_typestringNetwork kind: "datacenter" | "satellite" | "unknown". Replaces is_datacenter.
signals.datacenter_providerstring|nullProvider code (aws, gcp, azure, …) when connection_type is datacenter, else null.
signals.relay_providerstring|nullPrivacy-relay operator (e.g. "icloud") when is_relay is true, else null.
signals.is_relaybooleanIP is a privacy-relay exit (e.g. Apple iCloud Private Relay) — a benign network kind.
signals.is_vpnbooleanIP is in a known commercial VPN range.
signals.is_proxybooleanOpen/anonymising proxy (residential detection beta).
signals.is_torbooleanIP is a current Tor exit node.
signals.is_public_resolverbooleanIP is a public DNS resolver (e.g. 8.8.8.8, 1.1.1.1) — benign infrastructure.
signals.is_drop_listedbooleanIP is on the Spamhaus DROP list — a do-not-route range of known hostile networks.
signals.recent_abusebooleanIP appears on recent abuse feeds (Emerging Threats / CINS). Beta — scores zero today.
signals.is_verified_botbooleanIP is a verified good crawler from a search/AI operator's published ranges (the bot you must NOT block). NOT bad-bot detection.
signals.verified_bot_namestring|nullThe verified crawler's name (e.g. "googlebot", "bingbot") when is_verified_bot is true, else null.
evidence.connection_typestringHow directly we observe the connection-type signal: authoritative / inferred / beta.
evidence.torstringEvidence label for the Tor signal.
evidence.vpnstringEvidence label for the VPN signal.
evidence.proxystringEvidence label for the proxy signal.
evidence.verified_botstringEvidence label for the verified-bot signal.
evidence.relaystringEvidence label for the relay signal (authoritative).
evidence.routingstringEvidence label for the routing signals — is_announced / is_bogon / rpki (authoritative).
evidence.allocationstringEvidence label for the allocation fields (authoritative).
evidence.drop_listedstringEvidence label for the drop-list signal (authoritative).
evidence.recent_abusestringEvidence label for recent-abuse (beta).
evidence.public_resolverstringEvidence label for the public-resolver signal (authoritative).
risk.scorenumber0–100 capped sum of triggered signal weights (after the benign-network suppressor).
risk.levelstringlow (<30), medium (30–59), high (≥60).
risk.reasonsstring[]The signal keys that contributed to the score (plus benign_network_kind when the score was suppressed).
attributionstringURL to the required attribution page.

The evidence object

For each signal we tell you how directly we observe it — not how likely it is to be correct. This is a transparency label, not a probability or accuracy claim.

LabelMeaning
authoritativeDrawn from operator-published ranges or lists (e.g. cloud provider CIDRs, the Tor exit list, Googlebot's published ranges). The most direct observation we have.
inferredDerived at the ASN level rather than from a published list — a reasoned attribution, not a direct one.
betaHeuristic and partial; still maturing. Weight it accordingly.

The new signal groups

The eight signals added in 0.8.0 fall into three groups:

  • False-positive reducersis_relay (with relay_provider), connection_type === "satellite" and is_public_resolver. These describe benign network kinds. When any of them is true, the risk score is capped at 20 and benign_network_kind appears in reasons[] — so an Apple iCloud Private Relay or Starlink user isn't scored like a hostile datacenter. See the risk-score methodology.
  • Precision signalsis_drop_listed (Spamhaus DROP), is_bogon and rpki routing validation. These add weight where the network itself is hostile or malformed.
  • Network context — routing (is_announced) and RIR allocation (allocation_date, allocation_age_days, registration_country). Context to reason with, not scored on their own.

recent_abuse is beta and carries zero weight today — treat it as a hint, weighted by its evidence label.

About is_verified_bot

is_verified_bot identifies a verified good crawler — Googlebot, Bingbot and similar, matched against the operator's own published ranges. It is the bot you must not block. It is not behavioural bad-bot detection (that's on the roadmap). Because a verified Googlebot is not fraud, it carries zero risk weight and never appears in risk.reasons.

Notes on honesty

  • geo is approximate and locates the network, not the device.
  • signals.is_proxy is beta (residential-proxy detection in particular) — see its evidence label.
  • The evidence labels describe observation directness, not accuracy or probability.
  • connection_type, tor and verified_bot signals cover both IPv4 and IPv6; geo and ASN always have.
  • connection_type only ever emits datacenter, satellite or unknown — we never guess "residential" or "mobile".
  • All signals are probabilistic. risk.reasons shows exactly what fired so you can audit any score.
  • attribution must be honoured on the Free tier — see attributions.