Developer IP intelligence

The IP fraud API that shows its work.

VPN, proxy, datacenter, Tor and verified-crawler signals — plus a transparent risk score, geolocation and ASN. Flat pricing, no per-query metering, and a published accuracy benchmark. No card to start.

Works in 7 lines

$ curl "https://api.geoq.io/v1/check?ip=8.8.8.8" \
    -H "x-api-key: $GEOQ_API_KEY"
import { GeoQ } from "@geoq/sdk";

const geoq = new GeoQ(process.env.GEOQ_API_KEY);
const r = await geoq.check("8.8.8.8");

if (r.risk.level === "high") {
  console.log("step up:", r.risk.reasons);
}

Migrating from IPinfo? ?format=ipinfo returns compatible responses — your parsing keeps working. Migration guide →

1,000 lookups/day free · every signal · EU + US regions · GDPR-aware

api.geoq.io/v1/check
try:
response
{
  "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"
  },
  "signals": {
    "is_datacenter": true,
    "datacenter_provider": "gcp",
    "is_tor": false,
    "is_vpn": false,
    "is_proxy": false,
    "is_verified_bot": false,
    "verified_bot_name": null
  },
  "evidence": {
    "datacenter": "authoritative",
    "tor": "authoritative",
    "vpn": "inferred",
    "proxy": "beta",
    "verified_bot": "authoritative"
  },
  "risk": {
    "score": 35,
    "level": "medium",
    "reasons": [
      "is_datacenter"
    ]
  },
  "attribution": "https://geoq.io/attributions"
}

Sample shown until you run a lookup. Calls https://api.geoq.io/v1/check directly from your browser.

Why GeoQ

Three honest reasons to switch.

No "most accurate" claims. Just transparency, predictable pricing, and honesty about what each signal can and can't do.

Shows its work

A published, reproducible accuracy benchmark with our methodology — and a risk score with a documented formula, not a black box. You can see exactly why an IP scored what it did.

Flat, honest pricing

$0, $29, $99, $299. Daily lookup quotas, no per-query metering, no surprise overage invoices. The free tier needs no credit card.

Honest about limits

Signals are probabilistic, not facts — and each one ships with an evidence label (authoritative / inferred / beta) so you see how directly we observe it. We tell you what's solid and what's maturing, so you weight it correctly.

Coverage

Every signal in one call.

A single GET /v1/check returns abuse signals, geolocation, network data and a risk score.

is_vpn

VPN

Traffic from a known commercial VPN range.

is_proxy beta

Proxy

Open or anonymising proxy. Residential-proxy detection is beta.

is_datacenter

Datacenter

Hosting/cloud IP with provider attribution (AWS, GCP, Azure, …).

is_tor

Tor

Tor exit node from the public exit list.

is_verified_bot

Verified crawler

A verified good crawler (Googlebot, Bing) from the operator's published ranges — the bot you must NOT block. Not bad-bot detection.

geo · network · risk

Context, included

Country, region, city, lat/long, timezone, ASN and AS org — and a 0–100 risk score with reasons. No extra endpoints, no extra plans.

Transparent scoring

The risk score has a formula.

We sum the weight of every triggered signal and cap at 100. That's the whole formula. low < 30, medium 30–59, high ≥ 60. Tune the threshold to your own tolerance. Every response carries reasons[] — the exact signals that fired.

Read the methodology
signalweight
is_tor +45
is_proxy +40
is_datacenter +35
is_vpn +30

score = min(100, Σ weights of triggered signals)

Integrate in minutes

Four lines, any stack.

Official SDKs for JavaScript, Python and Go — or just hit the REST endpoint with cURL.

$ curl "https://api.geoq.io/v1/check?ip=8.8.8.8" \
    -H "x-api-key: geoq_live_***"
import { GeoQ } from "@geoq/sdk";

const geoq = new GeoQ(process.env.GEOQ_API_KEY);
const r = await geoq.check("8.8.8.8");

if (r.risk.score >= 60) {
  // step up: require MFA, hold the order, etc.
  console.log("high risk", r.risk.reasons);
}
from geoq import GeoQ

geoq = GeoQ(api_key="geoq_live_***")
r = geoq.check("8.8.8.8")

if r.signals.is_datacenter:
    print("hosting IP from", r.signals.datacenter_provider)
package main

import "github.com/Evercay/geoq-go"

func main() {
    c := geoq.New("geoq_live_***")
    r, _ := c.Check("8.8.8.8")
    if r.Risk.Level == "high" {
        // block or challenge
    }
}

Pricing

Flat plans. No metering.

Pick a daily lookup quota. That's it. Full pricing details →

Free

$0 forever

1,000 lookups / day

No credit card required

Get your free API key
  • All signals incl. risk score
  • 1,000 lookups / day
  • Community support
  • Attribution required

Starter

$29 / month

750,000 lookups / month

For side-projects going live

Start Starter
  • Everything in Free
  • 750,000 lookups / month
  • Email support
  • No attribution requirement

Scale

$299 / month

10,000,000 lookups / month

High-volume, predictable

Start Scale
  • Everything in Growth
  • 10,000,000 lookups / month
  • Slack support channel
  • 99.99% uptime SLA
  • Volume pricing beyond 10M — talk to us

FAQ

Frequently asked questions

Is there really a free tier with no credit card?
Yes. Sign up, get an API key, run 1,000 lookups a day with every signal — no card, no trial timer. Upgrade only when you outgrow it.
How accurate is GeoQ?
We will publish a reproducible accuracy benchmark with our methodology and refresh it over time. We do not claim to be the most accurate provider — we'd rather show our work. See the benchmark methodology.
What counts as a lookup?
One lookup is one successful /v1/check response for one IP. Cached repeats within your app are your call — we bill on requests to our API, on a flat daily quota, never per-query overage. See pricing.
Are the signals guaranteed facts?
No. Every signal is probabilistic and should be treated as one input among several. GeoQ must not be the sole basis of an automated decision about a person. See our acceptable use policy.
Do you detect bad bots?
Not yet — that's on the roadmap. Today we detect verified good crawlers (is_verified_bot + verified_bot_name) like Googlebot and Bing, matched against the operators' published ranges — the bots you must not block. It's not behavioural bad-bot detection, and a verified crawler carries zero risk weight.
Which signals are beta?
Residential-proxy detection is marked beta. Every signal also carries an evidence label (authoritative / inferred / beta) so you can see how directly we observe it — that's a transparency label, not a probability claim.

Start with the free tier. No card.

1,000 lookups a day, every signal, the same transparent risk score. Upgrade only when you outgrow it.