跳到主要内容
IPOK

开发者 API

免费、无需鉴权、支持跨域(CORS)。直接 GET 调用即可,返回 JSON。

接口列表

GET/check?ip={ip}

终端即时检测 (ANSI):curl -sL https://ipok.io/check 快速在终端输出格式化彩色/纯文本诊断报告(支持 ?ip=、?plain=1、?lang=zh)

GET/sh

一键 Shell 脚本:curl -fsSL https://ipok.io/sh | bash 在 Linux/macOS 终端单行执行完整检测(支持参数传 IP、--json、--plain)

GET/api/ip?ip={ip}

IP 全量检测:归属地、ASN、IP 层风险证据、原生标签、场景参考、AI 地区快照等

GET/api/ip?ip={ip}&format=text

终端即时检测 (ANSI):curl -sL https://ipok.io/check 快速在终端输出格式化彩色/纯文本诊断报告(支持 ?ip=、?plain=1、?lang=zh)

GET/api/bgp?asn={asn}&ip={ip}

BGP 路由关系:公告前缀、上游/下游 ASN(数据源 RIPEstat)

GET/api/reverse-ip?ip={ip}

IP 反查域名:同 IP 上托管的域名

GET/api/batch?q={ips|cidr}

批量快速估算:用 ip-api + IPOK 离线库查询多个 IP / IPv4 CIDR;不等同单 IP 多源评分

GET/api/cidr?q={cidr}

段级信誉摘要:离线库扫描 IPv4 CIDR(单段≤/16、单请求合计≤65,536个地址),输出 VPN/Tor/滥用占比与连坐判定(零额外上游请求)

GET/api/badge?ip={ip}

SVG 风险徽章:按分档着色,可嵌入 README / 论坛;为保护上游额度,徽章不调用 Scamalytics,同一目标的分数可能与主动 /api/ip 查询略有差异。若使用超过 72 小时、最多 7 天的故障降级数据,徽章会标注“降级缓存”并改为琥珀色。超额或查询失败时以 HTTP 200 返回灰色 n/a,成功缓存 5 分钟、n/a 缓存 1 分钟

调用示例

# 终端即时检测 (ANSI):curl -sL https://ipok.io/check 快速在终端输出格式化彩色/纯文本诊断报告(支持 ?ip=、?plain=1、?lang=zh)
curl -sL "https://ipok.io/check"
curl -sL "https://ipok.io/check?ip=1.1.1.1"

# 一键 Shell 脚本:curl -fsSL https://ipok.io/sh | bash 在 Linux/macOS 终端单行执行完整检测(支持参数传 IP、--json、--plain)
curl -fsSL "https://ipok.io/sh" | bash
curl -fsSL "https://ipok.io/sh" | bash -s 1.1.1.1

# IP 全量检测:归属地、ASN、IP 层风险证据、原生标签、场景参考、AI 地区快照等
curl "https://ipok.io/api/ip?ip=1.1.1.1"
curl "https://ipok.io/api/ip?ip=1.1.1.1&format=text&plain=1"

# BGP 路由关系:公告前缀、上游/下游 ASN(数据源 RIPEstat)
curl "https://ipok.io/api/bgp?asn=AS13335&ip=1.1.1.1"

# IP 反查域名:同 IP 上托管的域名
curl "https://ipok.io/api/reverse-ip?ip=1.1.1.1"

# 批量快速估算:用 ip-api + IPOK 离线库查询多个 IP / IPv4 CIDR;不等同单 IP 多源评分
curl "https://ipok.io/api/batch?q=1.1.1.1,8.8.8.8"

# 段级信誉摘要:离线库扫描 IPv4 CIDR(单段≤/16、单请求合计≤65,536个地址),输出 VPN/Tor/滥用占比与连坐判定(零额外上游请求)
curl "https://ipok.io/api/cidr?q=146.70.50.0/24"

# SVG 风险徽章:按分档着色,可嵌入 README / 论坛;为保护上游额度,徽章不调用 Scamalytics,同一目标的分数可能与主动 /api/ip 查询略有差异。若使用超过 72 小时、最多 7 天的故障降级数据,徽章会标注“降级缓存”并改为琥珀色。超额或查询失败时以 HTTP 200 返回灰色 n/a,成功缓存 5 分钟、n/a 缓存 1 分钟
![IP risk](https://ipok.io/api/badge?ip=1.1.1.1)

主要响应字段

{
  "apiVersion": "1",                       // response contract version (see Versioning below)
  "geo":   { "ip", "version", "country", "city", "asn", "asName", "isp", "lat", "lon" },
  "ipType":    "residential | hosting | mobile | business | unknown",
  "usageType": "isp | dual_isp | business | hosting | mobile | education | government | unknown",
  "risk":      0,                         // compatibility value; display only if scoreAvailable=true
  "riskAssessment": {
    "version": 1,
    "status": "insufficient | limited | current",
    "scoreAvailable": false,
    "safeConclusion": false,
    "independence": "unverified",
    "currentSources": [], "staleSources": [], "undatedSources": [], "invalidSources": [],
    "reasons": [], "assessedAt": "2026-10-20T05:00:00Z"
  },
  "riskBreakdown": {                       // how the score was computed (see /methodology)
    "contributors": [{ "source", "risk", "weight" }],
    "weightedAvg": 0,
    "floors": [{ "key": "tor", "floor": 90 }],
    "final": 0
  },
  "signals":   ["proxy", "hosting", ...],
  "blocklist": { "listed": ["SpamCop"], "checked": 5, "total": 5 },  // valid DNSBL results / planned lists, IPv4 only
  "anonAsn?":  { "asn", "name", "type" },                // known VPN/proxy provider ASN
  "nativeType": "native | broadcast | unknown", // legacy enum: registration/location agreement only
  "sharedUsers": { "range": "1-5", "quality": "good | ok | poor | unknown" },
  "scenarios?": [{ "key": "tiktok", "stars": 3, "verdict": "try" }], // omitted when evidence is insufficient
  "services":   [{ "key": "chatgpt", "status": "available" }],
  "media":      [{ "key": "netflix", "status": "unknown" }],     // known-region restriction reference, not a live unlock test
  "sources":    [{ "source": "ip-api", "risk": 10, "flags": {}, "observedAt": "2026-09-23T04:15:00Z" }],
  "sourceAttempts?": [{ "source": "IPQS", "status": "not_called", "reason": "dormant", "elapsedMs": 0, "upstream": "not_called" }],
  "diagnostics?": { "timings": { "totalMs": 600, "geoMs": 100, "sourcesMs": 400, "cacheMs": 10, "admissionMs": 50, "quotaReadMs": 10, "requestMs": 660 } },
                                           // observedAt = when this source was read: the time of this
                                           // request on a live fetch, or the time the cache entry was written
  "evidence?":  {                          // why the verdict landed where it did
    "dedicatedVotes", "voters": [], "floors": [], "directSources": [],
    "confidence": "none | single | multi", "singleSource?"
  },
  "attribution?": { "provider?", "datacenter?", "company?", "asnOrg?" },   // who the address belongs to
  "intel?":     { "asn", "company", "datacenter", "abuse" },     // ipapi.is enrichment
  "asnHistory?": [{ "asn", "firstSeen", "lastSeen" }],
  "rdap?":      { "registry", "country", "registered", "org" },  // "?" = optional, omitted when unavailable
  "quota?":     {                          // your remaining fair-use budget (see Quota below)
    "apiVersion": "1",
    "selfLookup?":      { "used", "limit", "remaining", "resetsInSeconds" },
    "arbitraryLookup?": { "used", "limit", "remaining", "resetsInSeconds" },
    "note"
  }
}

终端报告需显式指定 format=text;仅有 HTML Accept 不改变 JSON。文本与 stream=1 或 event-stream 协商冲突时,在额度准入前返回 JSON 400。/check 复用相同准入与额度规则;fast=1 或 quick=1 仍需准入,然后使用已有缓存/免费证据,不调用商业源。/api/ip 错误保持既有 JSON 契约。

riskAssessment 在响应时重新评估。scoreAvailable=false 时应隐藏总分及场景星级;旧 risk 数字为接口兼容保留,不代表当前结论。逐源分数、阳性信号及其日期继续展示。风险源 72 小时时限沿用既有缓存保留期,离线快照时限为 10 天;两者都不是准确率保证。不同厂商名字不能证明底层采集独立;缺失证据不等于安全,也没有凭空设定四源门槛。

IPOK-DB 的 raw.sourceStatus 按来源与地址族给出 coverage、freshness、match、fetchedAt、publishedAt、version。unsupported/unavailable/unknown 不表示无风险,no_match 仅表示该快照未命中。云段和 Apple 中继归属属于网络背景,不是滥用证据。Cloudflare Anycast 网络归属不能识别 WARP 出口、具体产品或物理位置。nativeType 是保留的国家一致性枚举,不是原生出口证明。

归属地主源为 ip-api,不可用时依次回退到 IPinfo Lite、ipapi.is。IPinfo Lite 仅提供国家与 ASN 资料,不产生风险判定、不进入评分或共识投票;城市、经纬度等详细字段可能缺省。

sourceAttempts 列出全部注册源,包括未投票的源。status 为 success、unavailable 或 not_called;reason 区分休眠、策略跳过、额度闸、只读缓存、缓存未命中、缺配置、上游错误与无证据。缺席不等于清白;适配器未暴露具体原因时,upstream_error 不冒充超时。

cache 为 l1、l2、stale 或 miss,与本次回源原因分开。成功读取过期缓存仍可附 reason=quota。elapsedMs、cacheElapsedMs、upstreamElapsedMs 是本次实测毫秒数,topup 表示进入过补票。diagnostics.timings 与 Server-Timing 提供服务端计时;cacheMs 是并发缓存操作累计值,不能与各阶段墙钟耗时相加。requestMs 不含客户端网络/边缘传输与响应序列化,需与客户端总耗时对照。

App、扩展和公开 API 无需验证码。未证明客户端除来源 IP、分类和厂商限额外,还共用小时池,换请求头不会增加共同池。额度基础设施异常时禁止商业回源,自查仍保留免费源与缓存。供应商账户余额属于私有运维元数据,已从 raw 移除;公开风险、flags 与来源结论字段保持不变。

状态码 / 错误

200成功
400请求参数错误:无效/私有 IP、缺少 ip/asn 等
429分钟或每日额度已用尽;按 Retry-After 重试
503额度服务或批量上游暂时不可用
502上游数据源不可用或超时

限流与缓存

额度按来源 IP(IPv6 按 /64)计算:仅 /api/ip 另有每个 Worker 实例内 30 次/分钟的突发闸;MCP、/api/ip 与 /api/badge 共用自查 20 次/UTC 日、指定目标 IP 15 次/日的日桶。诚实 curl/CLI 直接调用 /api/ip 查目标超出日桶后,商业源降为只读缓存、免费源继续;MCP 与其他调用方维持日限额。Badge 超额时返回灰色 n/a 而非 429。Batch 每日最多消耗 25 个上游分块(每块最多 100 个目标);reverse-ip、whois、BGP 各 25 次/UTC 日,CIDR 10 次/日,DNS 泄露代理 40 个 HTTP 请求/日(约 20 次完整检测)。CIDR 单请求最多展开 65,536 个地址。Scamalytics 仅在显式查询且缓存未命中时尝试,受每来源 5 次/UTC 日、全站 6 次/UTC 小时及上游月额度三层约束;额度不足时若有旧缓存会明确标为降级,否则暂缺该源,整次查询仍继续。商业源(AbuseIPDB / proxycheck / ipapi.is / Scamalytics)的回源按调用方类别分池、按 UTC 小时计,自查与指定目标各一个池:指定目标且通过 Cloudflare Turnstile 静默验证的页面查询不进池;已验证自查(Turnstile 或 PoW,无目标或目标等于来源 IP)改走单独的全站商业源日桶(默认 4000 次/UTC 日,与分类池分开,用尽后 cached-only);未验证自查仍进分类池;只带 PoW 的目标查询仍进入 120 / 30 的池;官方 App 120 / 60,浏览器扩展 120 / 30,诚实的程序化客户端(curl、脚本、MCP)100 / 30,第三方网页跨站调用 60 / 30,浏览器地址栏直接打开 30 / 10,自称浏览器却缺少浏览器必发头的请求 20 / 5;这类请求查询非本 IP 时,还须提供有效 PoW 或会话,否则返回 403 与 x-ipok-pow-required: 1。所有未通过 Turnstile 的类别还共用自查 120 / 目标 60 的小时池。池满不拒绝:商业源只用缓存或明确标记的降级值、不再回源,其余免费源照常参与,响应带 upstream:"cached-only"、x-ipok-upstream 与 x-ipok-client 头。带着真实浏览器不可能组合的请求头(导航却带 XHR 头、页面 fetch 却带导航专属头、UA 与 client hints 的操作系统不一致)的请求直接 403——用诚实的 HTTP 客户端即可。共享缓存命中不扣对应辅助额度。除上述 CLI/Badge 降级情形外,超额返回 429;生产环境额度服务不可用时返回 503。高频或商用请自建缓存并联系我们。

额度块

成功的 /api/ip 响应带一个 quota 块,让你不必等到撞上 429 才知道本来源 IP 还剩几次。selfLookup 是查自己(不带 ?ip=),arbitraryLookup 是显式查询指定 IP(带 ?ip=)。两者各有 used、limit、remaining、resetsInSeconds,按来源 IP 计数,UTC 日界线重置。IPv6 按 /64 归并计数,不按单个地址。

同样两个数字也放在 X-IPOK-Quota-Self-Remaining 与 X-IPOK-Quota-Lookup-Remaining 响应头里,不解析响应体也能读到。计数是在本次请求已经扣费之后读的,所以 used 已经包含这一次。诚实 HTTP 客户端在目标日额度耗尽后仍可得到商业源缓存结果,这类超额请求不再增加该计数。

某个子块读不到计数时会被省略。这表示未知,不表示无限——额度照常生效。

per-IP 额度不是唯一的闸。几个商业风险源另有一个全站小时池;池满时请求照常完成,但那几个源只提供缓存或近期值,结果会标 upstream: "cached-only"(响应头 x-ipok-upstream)。零配额的源不受影响,照常参与。

版本协商

发 Accept-Version: 1 可以把响应契约钉在某一版。实际服务的版本会回显在 X-IPOK-API-Version 响应头,并在响应体里重复一次(apiVersion)。我们不认识的版本不算错误:仍然按 v1 服务,并在 X-IPOK-API-Warning 里说明。不带这个头同样是 v1。

策略只有两条。新增可选字段不升版,所以请按「忽略不认识的字段」来解析。改动既有字段的含义或删掉字段才升版,届时老版本对明确要求它的调用方继续提供。

新增字段

以下都是可选的新增字段,因此版本仍为 1。按「忽略不认识的字段」解析的老客户端不受影响。

evidence —— 判定依据:dedicatedVotes(有几个专门的代理/VPN 源标记了这个地址)、voters(是哪几个)、floors(触发了哪些分数下限)、directSources,以及 confidence——取值 none / single / multi。为 single 时,singleSource 给出唯一标记它的那个源;一票的证据强度不如多票,这个字段就是为了让你能区别对待。

attribution —— 这个地址归属于谁(以我们能查到的为准):provider、datacenter、company、asnOrg。只有源给出了对应信息时才出现。

sources[i].observedAt —— 该源的读取时间,ISO 格式:回源时是本次请求的时间,缓存命中时是写入缓存的时间。配合上面的 cached-only 标记,可以据此区分新鲜读数与陈旧读数。

数据引用条款

我们的接口向公众和开发者免费开放,且无需注册。但当您在网站、公开产品、应用程序或研究报告中引用或展示本站的检测数据(包括 IP 纯净度、风险得分、机房判定等)时,您必须在合适的位置明确标注数据来源为 IPOK,并提供一个指向 https://ipok.io 的可访问超链接(回链)。

请合理使用;高频或商用请自建缓存,避免对上游数据源造成压力。