ipctl API Reference

Version 1.0.0 - base URL https://api.ipctl.io/v1 - OpenAPI spec: openapi.yaml

IP, ASN, and prefix intelligence API. Provides geolocation, BGP routing data, threat intelligence, WHOIS/RDAP registration info, and search across all network resources.

Authentication

Public endpoints are available without authentication, subject to the anonymous rate limits. Sending an API key raises the limits to those of your plan.

Authenticated endpoints (/bulk, /mcp) require an API key (prefix nq_), sent either as X-API-Key: nq_... or as Authorization: Bearer nq_.... Create one for free at ipctl.io/dashboard.

An invalid, revoked or expired key is rejected with 401 (codes INVALID_API_KEY, API_KEY_EXPIRED) on every endpoint; requests do not fall back to anonymous access.

Credits

With an API key, /ip/{ip}, /asn/{asn}, /asn/{asn}/risk, /prefix/{cidr} and /intel/{ip} cost 1 credit per request and /bulk 1 credit per unique valid IP. All other endpoints are free. Anonymous requests only count against the rate limits. Each operation states its cost in x-credits.

Rate Limits

Rate-limited endpoints (all except /health and /mcp) return these headers:

  • X-RateLimit-Limit / X-RateLimit-Remaining / X-RateLimit-Reset (per-minute window; X-RateLimit-Reset is the Unix time the current window ends)
  • X-RateLimit-Limit-Day / X-RateLimit-Remaining-Day (per UTC day)

Credit-consuming endpoints called with an API key also return X-RateLimit-Credits-Remaining / X-RateLimit-Credits-Reset. A 429 carries Retry-After (seconds until the window ends). MCP tool calls are limited and billed like the REST requests they make.

Rate limits depend on your plan. See pricing for details.

Errors

Errors use the error object of the response envelope with a machine-readable code (see APIError).

Endpoints

IP

IP address lookups and bulk operations

Look up an IP address

GEThttps://api.ipctl.io/v1/ip/{ip}

Returns comprehensive data for an IP including network registration, ASN, BGP routes, geolocation, and threat score. With an API key on a paid plan (Starter and above) the result also says whether the IP belongs to an AI service (is_ai_service, ai_service); these fields are omitted for anonymous requests and Free plan keys, and such responses are sent with Cache-Control private. Costs 1 credit with an API key; anonymous requests only count against the rate limits. Requests to /ip without an IP parameter return 400 MISSING_PARAM.

Works without an API key; a key raises the rate limits. Credits: 1.

Parameters

NameInTypeDescription
ip *pathstringExample: 1.1.1.1
formatqueryjson | texttext returns a human-readable WHOIS-style plain-text summary for shell scripts, chat unfurls or terminals. Lines with empty values are omitted.Example: json

Example response (data, abridged)

{
  "data": {
    "ip": "1.1.1.1",
    "ip_version": 4,
    "reverse_dns": "one.one.one.one",
    "prefix": {
      "prefix": "1.1.1.0/24",
      "ip_version": 4,
      "rpki_status": "valid"
    },
    "asn": {
      "asn": 13335,
      "name": "CLOUDFLARENET",
      "country_code": "US",
      "rir": "arin"
    },
    "ai_service": {
      "provider": "openai",
      "name": "OpenAI",
      "kinds": [
        "crawler"
      ],
      "network": "20.171.206.0/24"
    }
  }
}

Look up your own IP

GEThttps://api.ipctl.io/v1/me/ip

Returns IP information for the caller's IP address. Free (no credits). is_ai_service and ai_service are included for API keys on paid plans only, as on /ip.

Works without an API key; a key raises the rate limits. Credits: free.

Example response (data, abridged)

{
  "data": {
    "ip": "1.1.1.1",
    "ip_version": 4,
    "reverse_dns": "one.one.one.one",
    "prefix": {
      "prefix": "1.1.1.0/24",
      "ip_version": 4,
      "rpki_status": "valid"
    },
    "asn": {
      "asn": 13335,
      "name": "CLOUDFLARENET",
      "country_code": "US",
      "rir": "arin"
    },
    "ai_service": {
      "provider": "openai",
      "name": "OpenAI",
      "kinds": [
        "crawler"
      ],
      "network": "20.171.206.0/24"
    }
  }
}

Bulk IP lookup

POSThttps://api.ipctl.io/v1/bulk

Look up multiple IPs in a single request. Requires an API key on a paid plan; the maximum number of IPs per request depends on the plan (see https://ipctl.io/pricing). Duplicates are removed first. Costs 1 credit per unique, valid IP; invalid IPs are listed in errors and not charged. Results include is_ai_service and ai_service (all plans with bulk access include them).

Requires an API key. Credits: per unique valid IP.

Request body (example)

{
  "ips": [
    "1.1.1.1",
    "8.8.8.8"
  ]
}

ASN

Autonomous System Number lookups

Look up an ASN

GEThttps://api.ipctl.io/v1/asn/{asn}

Returns ASN details, registered prefixes (at most 500), routing statistics and ASPA status. Announced prefixes are listed by /asn/{asn}/prefixes (limit/offset). Accepts numeric ASN or "AS" prefix (e.g., AS13335). Costs 1 credit with an API key.

Works without an API key; a key raises the rate limits. Credits: 1.

Parameters

NameInTypeDescription
asn *pathstring
formatqueryjson | texttext returns a human-readable WHOIS-style plain-text summary for shell scripts, chat unfurls or terminals. Lines with empty values are omitted.Example: json

Example response (data, abridged)

{
  "data": {
    "asn": {
      "asn": 13335,
      "name": "CLOUDFLARENET",
      "country_code": "US",
      "rir": "arin"
    },
    "prefixes": [
      {
        "prefix": "1.1.1.0/24",
        "ip_version": 4,
        "rpki_status": "valid"
      }
    ]
  }
}

Get announced prefixes for an ASN

GEThttps://api.ipctl.io/v1/asn/{asn}/prefixes

Returns BGP-announced prefixes for the given ASN. Loaded lazily to keep the main ASN endpoint fast. Free (no credits).

The list is paginated: one response holds at most limit prefixes (default 100, maximum 1000). pagination.total is the number of announced prefixes of the ASN. To get all of them, repeat the request with offset increased by limit until offset reaches pagination.total, e.g. ?limit=1000&offset=0, then offset=1000, offset=2000 and so on.

This endpoint lists announced (BGP) prefixes. The prefixes field of /asn/{asn} holds registered (RIR) prefixes instead and is capped at 500.

Works without an API key; a key raises the rate limits. Credits: free.

Parameters

NameInTypeDescription
asn *pathstringAS number (with or without "AS" prefix)
limitqueryintegerPrefixes per response (default 100, maximum 1000; larger values are clamped to 1000)Example: 100
offsetqueryintegerNumber of prefixes to skip; increase by limit to fetch the next pageExample: 0

Example response (data, abridged)

{
  "pagination": {
    "total": 1542,
    "limit": 100,
    "offset": 0
  }
}

Get ASPA upstream providers for an ASN

GEThttps://api.ipctl.io/v1/asn/{asn}/upstreams

Returns the list of upstream provider ASNs that this ASN has authorized via an ASPA object (draft-ietf-sidrops-aspa-profile). Includes provider name and country. Returns an empty array when the ASN has published no ASPA object. Free (no credits).

Works without an API key; a key raises the rate limits. Credits: free.

Parameters

NameInTypeDescription
asn *pathstringAS number (with or without "AS" prefix)

Get ASPA downstream customers for an ASN

GEThttps://api.ipctl.io/v1/asn/{asn}/downstreams

Returns ASNs that have published ASPA objects listing this ASN as an authorized upstream provider. Includes customer name and country. Returns an empty array when no ASN lists it. Free (no credits).

Works without an API key; a key raises the rate limits. Credits: free.

Parameters

NameInTypeDescription
asn *pathstringAS number (with or without "AS" prefix)

Get the routing-risk score of an ASN

GEThttps://api.ipctl.io/v1/asn/{asn}/risk

Routing hygiene score of an ASN (0-100, higher is riskier) with level, reasons and the component metrics: RPKI ROA coverage, IRR route object coverage and origin mismatches, prefixes announced against other networks' ROAs or announced by others against its ROAs, and upstream count and diversity. Recomputed once a day; see the ASNRoutingRisk schema for the method. Returns 404 (NOT_FOUND) when the ASN announces no prefixes. Costs 1 credit with an API key.

Works without an API key; a key raises the rate limits. Credits: 1.

Parameters

NameInTypeDescription
asn *pathstringAS number (with or without "AS" prefix)

Example response (data, abridged)

{
  "data": {
    "asn": 64500,
    "prefix_count": 12,
    "rpki_coverage_pct": 75,
    "rpki_invalid_count": 0,
    "irr_coverage_pct": 91.7,
    "irr_mismatch_count": 1,
    "hijack_victim_count": 0,
    "hijack_origin_count": 0,
    "upstream_count": 1,
    "upstream_diversity_score": 0,
    "routing_risk_score": 19,
    "level": "low",
    "reasons": [
      "Only one upstream seen in the AS paths of its routes",
      "25% of announced prefixes (3 of 12) have no valid ROA"
    ],
    "computed_at": "2026-10-09T09:25:41Z"
  }
}

Prefix

CIDR prefix and BGP route lookups

Look up a prefix

GEThttps://api.ipctl.io/v1/prefix/{cidr}

Returns prefix registration data, BGP routes, more-specific prefixes, IRR route objects and ROAs. Accepts CIDR notation in the path (e.g., /prefix/1.1.1.0/24). Costs 1 credit with an API key.

Smart resolution: If the exact prefix is not found, the API will return a redirect field pointing to a better match:

  • Host routes (/32 for IPv4, /128 for IPv6) redirect to the IP lookup endpoint.
  • Non-exact prefixes (e.g., /24 when the allocation is /23) redirect to the covering prefix.

List fields are always arrays (empty when there is nothing to list).

Works without an API key; a key raises the rate limits. Credits: 1.

Parameters

NameInTypeDescription
cidr *pathstringCIDR prefix. The slash may be sent literally (/prefix/1.1.1.0/24) or percent-encoded (/prefix/1.1.1.0%2F24); do not encode it twice.Example: 1.1.1.0/24
formatqueryjson | texttext returns a human-readable WHOIS-style plain-text summary for shell scripts, chat unfurls or terminals. Lines with empty values are omitted.Example: json

Example response (data, abridged)

{
  "data": {
    "prefix": {
      "prefix": "1.1.1.0/24",
      "ip_version": 4,
      "rpki_status": "valid"
    },
    "more_specifics": [
      {
        "prefix": "1.1.1.0/24",
        "ip_version": 4,
        "rpki_status": "valid"
      }
    ],
    "redirect": "/ip/46.4.224.114"
  }
}

Intel

Threat intelligence

Get threat intelligence for an IP

GEThttps://api.ipctl.io/v1/intel/{ip}

Returns the aggregated threat score and the individual findings (tag and severity). Costs 1 credit with an API key.

Works without an API key; a key raises the rate limits. Credits: 1.

Parameters

NameInTypeDescription
ip *pathstringExample: 1.2.3.4

Example response (data, abridged)

{
  "data": {
    "intel": [
      {
        "tag": "botnet",
        "severity": "critical"
      }
    ]
  }
}

Search

Search ASNs and prefixes by name, ASN, IP or prefix

WHOIS

Normalized WHOIS/RDAP data

WHOIS/RDAP lookup for an IP

GEThttps://api.ipctl.io/v1/whois/{ip}

Returns normalized registration data aggregated from RIR delegations, ASN records, and prefix allocations. Fields without a value are omitted. Free (no credits).

Works without an API key; a key raises the rate limits. Credits: free.

Parameters

NameInTypeDescription
ip *pathstringExample: 8.8.8.8

MCP

Model Context Protocol server for AI agents

MCP server for AI agents

POSThttps://api.ipctl.io/v1/mcp

Model Context Protocol endpoint (Streamable HTTP, stateless, JSON responses) for AI agents and assistants such as Claude, Cursor or VS Code. Requires an API key, sent as Authorization: Bearer nq_... or X-API-Key; free keys work.

Tools: lookup_ip, check_ip_reputation, bulk_ip_lookup (paid plans), lookup_asn, list_asn_prefixes, asn_routing_risk, lookup_prefix, aspa_lookup, whois, search. Each tool call is billed and rate-limited like the REST request(s) it makes; aspa_lookup makes two requests (upstreams and downstreams) and list_asn_prefixes returns the first 500 announced prefixes. MCP protocol messages themselves are limited to 120 per minute per key (429 with Retry-After); MCP responses carry no X-RateLimit headers.

GET and DELETE return 405 (stateless server, no sessions or server-sent events).

Setup instructions: https://ipctl.io/integrations

Requires an API key. Credits: like the REST requests made by each tool call.

System

Service health

Health check

GEThttps://api.ipctl.io/v1/health

Returns service health status. No authentication and no rate limit. Returns 200 when healthy, 503 when the database is unreachable.

Works without an API key; a key raises the rate limits. Credits: free.

Example response (data, abridged)

{
  "status": "ok"
}