Logo
新用户订阅 RPC,首月享 6.5 折优惠查看优惠
OnFinality Learn
集成与开发阅读约 11 分钟

Polymarket 地理封锁端点:测试、解读与访问检查执行

如何调用 Polymarket 地理封锁端点、解读其响应,并理解为何通过检查并不保证能下单。

TL;DR

Polymarket 地理封锁端点是位于 https://polymarket.com/api/geoblock 的公共 GET 路由,用于报告请求 IP 地址是否被国际平台封锁以及解析到的国家。它是一个轻量级预检查,而非授权令牌:CLOB 订单端点会应用自己的合规层,因此返回 blocked:false 并不保证 POST /order 会成功。本文解释请求和响应结构,展示 curl、Python 和 JavaScript 中的可运行检查,并描述如何构建两阶段验证流程,将 IP 级地理封锁与账户、签名和订单级故障区分开来。

地理封锁端点实际回答的问题

路由 GET https://polymarket.com/api/geoblock 是一个公开、无需认证的检查。它不需要 API 密钥、签名或请求体。其职责是告知调用方发起请求的 IP 地址是否被视为被国际 Polymarket 平台封锁,并回显平台与该 IP 关联的国家代码。

这一范围刻意保持狭窄。该端点描述的是请求 IP,而非你的钱包、API 凭证或订单簿的合规状态。它与前端用来决定是否显示交易界面的检查属于同一类。将其视为交易授权是最常见的混淆来源:开发者看到 blocked: false,然后在提交订单时收到 403,便断定端点有问题。端点并没有问题;它回答的是与他们假设不同的问题。

本指南涵盖请求机制、响应字段、可复现的两阶段测试流程,以及地理封锁检查与成功下单之间的故障模式。它不发布国家允许列表,因为这些列表会变化,而端点本身才是你所调用 IP 的权威实时信号。

  • 公开且无需认证:无需 API 密钥、HMAC 签名或钱包。
  • IP 范围:答案取决于发起调用的机器的出口 IP。
  • 对前端和预检查具有参考性;CLOB 订单路径单独执行。
  • 响应中的国家代码反映 IP 地理位置,而非账户 KYC 数据。

假设与前提条件

以下流程假设你可以从将提交订单的同一主机发出出站 HTTPS 请求。最后这一条很重要:如果你从笔记本电脑测试而从云服务器交易,你测试的是不同的 IP,可能也是不同的国家。请从生产出口路径运行每项检查,或至少从具有相同网络出口的主机运行。

你需要一个可用的 HTTP 客户端(curl、带 requests 的 Python 3,或带内置 fetch 的 Node 18+),并且对于订单阶段测试,你需要有效的 CLOB API 凭证和已注资、已授权的钱包。如果你只需要地理封锁答案,则完全不需要凭证。对于交易栈的区块链侧,用于 Polygon 读取和交易提交的 RPC 端点是一个独立依赖;请参阅多链 RPC 端点指南和RPC 端点指南了解如何选择和测试。

心智模型:两道门,而非一道

将 Polymarket 访问视为串联的两道门。第一道门是公共地理封锁检查,成本低、可缓存且基于 IP。第二道门是 CLOB 交易端点前的合规层,它评估订单请求本身。第二道门可能比第一道更严格:它可能使用更严格的司法管辖区集合、额外的 IP 情报(如托管与住宅分类或代理标志),以及与 API 密钥或钱包绑定的上下文。

一个有用的类比是一栋有大堂旋转门和上锁交易楼层的大楼。地理封锁端点告诉你旋转门是否对你的 IP 开放。它并不说明楼层门是否会对你的凭证和订单开放。两道门都必须通过,且失败症状不同:第一道门返回带布尔值的 JSON 体,第二道门通常返回 HTTP 403,并附带关于你所在地区交易受限的错误消息。

这就是为什么正确的架构是预检查加真实提交测试,而非仅预检查。预检查快速且免费,应纳入启动诊断和任何面向用户的可用性横幅。提交测试是唯一能证明完整路径可用的方法。

使用 curl 调用端点

最简单的调用是普通 GET,除 HTTP 客户端默认发送的标头外不添加任何标头。检查状态码和响应体,因为代理或强制门户可能返回 200 和 HTML,而非地理封锁 JSON。

-i 标志打印响应标头,以便确认内容类型,--max-time 防止挂起的连接阻塞启动脚本。如果你的基础设施通过 HTTP 代理路由,请显式添加 --proxy,以便请求从你打算测试的 IP 发出。

curl -sS -i --max-time 10 \
  -H 'Accept: application/json' \
  https://polymarket.com/api/geoblock

# Expected shape (values depend on your egress IP):
# HTTP/2 200
# content-type: application/json
#
# {"blocked": false, "country": "XX"}

Python 和 JavaScript 中的程序化检查

将调用包装在一个返回结构化结果而非原始字符串的小函数中。该函数应区分三种结果:有效的 JSON 答案、非 200 响应以及无法解析的响应体。将它们合并为单个布尔值恰好隐藏了你以后需要调试的故障。

下面的 Python 版本使用带超时的 requests 并验证 blocked 键的存在。JavaScript 版本使用 Node 18 及更高版本中可用的内置 fetch,因此没有依赖。两者都记录国家代码,以便确认出口 IP 在你认为的位置。

import requests

GEOBLOCK_URL = "https://polymarket.com/api/geoblock"

def check_geoblock(timeout=10):
    try:
        resp = requests.get(GEOBLOCK_URL, headers={"Accept": "application/json"}, timeout=timeout)
    except requests.RequestException as exc:
        return {"ok": False, "reason": f"transport error: {exc}"}

    if resp.status_code != 200:
        return {"ok": False, "reason": f"http {resp.status_code}", "body": resp.text[:200]}

    try:
        data = resp.json()
    except ValueError:
        return {"ok": False, "reason": "non-json body", "body": resp.text[:200]}

    if "blocked" not in data:
        return {"ok": False, "reason": "missing blocked field", "data": data}

    return {"ok": True, "blocked": bool(data["blocked"]), "country": data.get("country")}

if __name__ == "__main__":
    print(check_geoblock())

# --- JavaScript (Node 18+) ---
# const res = await fetch("https://polymarket.com/api/geoblock", {
#   headers: { Accept: "application/json" },
#   signal: AbortSignal.timeout(10000),
# });
# const data = await res.json();
# console.log({ status: res.status, blocked: data.blocked, country: data.country });

带结果表的两阶段验证流程

从生产出口主机运行以下流程,并将每一行记录到表中。不要凭记忆填写预期值;重点是捕获你的基础设施实际返回的内容,并将其与应用程序的假设进行比较。

第一阶段是地理封锁 GET。第二阶段是通过 CLOB 客户端进行经过认证的最小订单提交,使用故意很小的规模,以便成功下单后易于取消。如果第二阶段不适合你的环境,可替换为使用相同凭证的经过认证的读取,例如余额或未结订单查询,并在表中注明订单路径仍未验证。

下面的表格列是诊断不匹配所需的最低要求。出口 IP 列至关重要:如果两行显示不同的 IP,你比较的是不同环境,结果不可比。

  • | 检查 | 命令或调用 | 观察到的状态 | 观察到的响应体 | 出口 IP | 国家 | 解读 |
  • | 地理封锁 GET | curl 到 /api/geoblock | (记录) | (记录) | (记录) | (记录) | blocked:false 表示此 IP 通过了第一道门 |
  • | 认证读取 | CLOB 余额或未结订单 | (记录) | (记录) | (记录) | (记录) | 证明凭证和签名有效 |
  • | 最小订单 | CLOB POST /order,极小规模 | (记录) | (记录) | (记录) | (记录) | 证明此 IP 和账户通过了第二道门 |
  • | 从第二台主机重复 | 同样的三次调用 | (记录) | (记录) | (记录) | (记录) | 差异可隔离 IP 级影响 |

解读响应并确认出口 IP

健康的响应是 HTTP 200,包含一个 JSON 对象,其中有布尔值 blocked 字段和包含两个字母代码的 country 字段。国家值是平台对你 IP 的地理定位,因此也是检查网络路径的有用手段。如果你认为自己从一个地区出口而端点报告另一个地区,请先调查 NAT、代理或云提供商的路由,再调查 Polymarket。

验证很简单:在短时间内从同一主机重复调用时,blocked 值应保持一致,country 值应与云提供商分配给该 IP 范围的区域匹配。如果任一值不稳定,你可能有轮换的出口池或跨区域负载均衡的代理。这种不稳定也会影响订单提交,因此应在网络层修复,而非在应用代码中重试。

对于交易机器人附带的区块链读取,请独立确认你的 RPC 路径。来自 OnFinality 专用节点服务等提供商的专用 Polygon 端点可减少一个变量,你可以在 RPC 定价页面比较方案。

为何通过地理封锁检查仍可能以 403 结束

最常见的报告模式是 blocked: false 响应,随后在提交订单时收到 403,并附带调用方所在地区交易受限的消息。原因可归为四组,每组有不同的修复方法。

第一,不同的司法管辖区集合。交易合规层可能限制公共检查未标记的国家,或可能应用仅允许平仓的语义,允许读取但不允许新订单。第二,IP 情报。托管提供商范围、VPN 出口和代理标志可能与住宅 IP 区别对待,即使国家匹配。第三,账户和密钥上下文。在一个地区创建的 API 密钥,或与受限地区有关联历史的钱包,可能带有 IP 检查看不到的标志。第四,订单本身。签名类型、出资地址和授权问题产生的错误在日志中看起来相似,但并非地理封锁失败。

诊断纪律是一次只改变一个变量。确认出口 IP,然后通过认证读取确认凭证,再提交最小订单。如果读取成功而订单因地区消息失败,问题在第二道门,而非你的签名代码。

  • POST /order 出现地区消息而 GET 成功:怀疑交易合规层,而非认证。
  • 间歇性失败:怀疑轮换出口 IP 或跨区域的代理池。
  • 持续 401 或签名错误:在重新测试地理封锁前修复凭证。
  • 无代码部署的突然变化:重新运行表格;司法管辖区列表和 IP 分类会变化。

在你自己的应用程序中执行检查

如果你正在构建展示 Polymarket 交易的集成,请模仿平台的模式:从与订单提交相同的出口在服务器端调用地理封锁端点,并根据结果控制交易界面。不要从浏览器调用,因为浏览器的 IP 是用户的,而非你的服务器的,两者可能以产生混淆行为的方式不同。

短暂缓存结果,以分钟为单位,按出口 IP 键控。检查成本低但并非免费,每请求调用会增加每次页面加载的延迟。更重要的是,将缓存值视为参考:始终让订单提交作为最终权威,并向用户显示平台的错误消息,而非通用失败。

Polymarket 自己的工具发布的参考集成模式遵循这种形式,安全钱包集成参考对于周围的钱包和审批流程是有用的阅读材料。对于其下的 RPC 层,OnFinality API 服务和支持的网络列表描述了可用内容,而无需在此承诺特定端点。

// Server-side gate. Run on the same egress as order submission.
const GEOBLOCK_URL = "https://polymarket.com/api/geoblock";
const cache = new Map(); // key: egress label, value: { at, result }

async function geoblockFor(egressLabel, ttlMs = 120_000) {
  const hit = cache.get(egressLabel);
  if (hit && Date.now() - hit.at < ttlMs) return hit.result;

  const res = await fetch(GEOBLOCK_URL, {
    headers: { Accept: "application/json" },
    signal: AbortSignal.timeout(10_000),
  });
  if (!res.ok) throw new Error(`geoblock http ${res.status}`);

  const data = await res.json();
  const result = { blocked: Boolean(data.blocked), country: data.country ?? null };
  cache.set(egressLabel, { at: Date.now(), result });
  return result;
}

// Usage: gate the UI, but never treat this as order authorization.
const gate = await geoblockFor("prod-egress-a");
console.log(gate.blocked ? "show read-only view" : "allow trading UI");

局限性与权衡

地理封锁端点是一种便利信号,而非契约。其响应结构可能变化,其国家映射源自 IP 地理位置,因此继承该数据的错误,且无法看到账户级或订单级限制。仅基于此端点构建合规决策将产生假阳性(阻止交易层会接受的用户)和假阴性(允许交易层会拒绝的用户)。

在每个请求上调用它还存在延迟和可靠性权衡。短缓存减少负载但扩大了显示过时答案的窗口。对于交易界面,更安全的模式是缓存参考横幅加上提交时的权威错误路径。最后,该端点对美国监管平台只字未提,后者是独立产品,有自己的文档和认证模型;不要假设国际地理封锁答案适用于那里。

如果你的应用程序依赖低延迟 Polygon 访问以支持周围的钱包和结算流程,端点选择比地理封锁调用本身更重要。Hyperliquid 低延迟提供商比较说明了延迟敏感交易基础设施的测量方法,同样的方法适用于你使用的任何链。

生产集成的后续步骤

将两阶段流程转化为启动自检,在每次部署时运行,并将结果连同出口 IP 写入日志。这一习惯将大多数地区相关事件从数小时的调试会话转变为一行日志查询。如果稳定出口的地理封锁答案发生变化,请配合警报,因为这通常表明你侧的网络变化或平台侧的司法管辖区变化。

对于交易栈背后 RPC 端点的具体选择,请使用 RPC Assistant,而非从文章中硬编码提供商;最佳以太坊 RPC API 比较和Web3 项目提供商指南描述了评估标准,RPC 端点指南涵盖你将重复使用的请求模式。将地理封锁检查、认证读取和最小订单测试保持为三个独立记录信号,你就能始终知道哪道门失败了。

永远不用担心基础设施

OnFinality 消除了 DevOps 的繁重工作,让您能够更聪明、更快地构建。

开始