跳到正文
开发者

Wardog Servers API

本站背后的数据以免费、只读的 JSON API 形式开放:游戏内浏览器列出的每个 WARDOGS 服务器,大约每分钟刷新一次;另有用于绘制图表的玩家历史,以及按加入码查询的单个服务器历史。

概览

基础 URL 为 https://api.wardogservers.com。所有响应均为 JSON,读取无需 API 密钥。

完整的接口规范以 OpenAPI 3.1 文档的形式发布在 https://api.wardogservers.com/openapi.json ↗。该文档是权威来源;本页只是便于阅读的摘要。

  • 采集器大约每分钟轮询一次各地区的游戏内服务器浏览器。当前间隔会在每个响应的 meta.refreshSeconds 中给出。
  • 只接受来自 wardogservers.com 的浏览器请求。请从你自己的服务器、机器人或脚本调用 API,不要从其他域名的网页调用。
  • 未知、重复或格式错误的查询参数会被拒绝并返回 400,而不是被忽略,这样拼写错误会直接报错,而不会悄悄返回全部数据。

快速上手

三个请求就能覆盖大多数用途:当前总数、符合筛选条件的最热门服务器,以及按实例 ID 查询单个服务器。

# 当前总数
curl https://api.wardogservers.com/v1/stats

# 欧洲西部还有空位的社区服务器,人最多的在前
curl "https://api.wardogservers.com/v1/servers?region=eu-west&type=community&hideFull=true&limit=10"

# 按实例 ID 查询单个服务器
curl https://api.wardogservers.com/v1/servers/$ID

/v1/stats 的精简响应如下:

{
  "data": {
    "serverCount": 3544,
    "playerCount": 252109,
    "officialServerCount": 2765,
    "communityServerCount": 779
  },
  "meta": {
    "fetchedAt": "2026-09-13T12:54:57.302Z",
    "snapshotId": "95635cb938811a34…",
    "refreshSeconds": 60,
    "stale": false,
    "requestedRegions": ["asia-east", "asia-southeast", "…"],
    "observedRegions": ["asia-east", "asia-west", "…"]
  }
}

接口

所有读取接口都接受 GET 和 HEAD,支持 If-None-Match,并使用下文所述的响应封装。

接口返回
GET /v1/servers服务器列表,支持筛选、排序和分页。
GET /v1/servers/{id}单个服务器,带额外的详情字段:原始属性、版本、等级和资金限制。
GET /v1/snapshot当前快照中的所有服务器,按实例 ID 排序,不带筛选和分页。适合在本地保存完整列表并自行筛选的客户端。
GET /v1/regions每个地区的服务器和玩家数量,以及上次轮询中各地区是否被请求、是否被观测到。
GET /v1/stats总数:在线服务器和玩家,分为官方和社区。
GET /v1/history/players用于图表的玩家和服务器时间序列。
GET /v1/history/heatmap过去 28 天某项指标按 UTC 星期和小时的平均值。
GET /v1/history/peaks历史和每日玩家峰值,包括总体和各服务器类型。
GET /v1/history/servers采集器记录过的服务器,按加入码区分,最近出现的在前。可以找到当前离线的服务器。
GET /v1/history/servers/ranking按在线时间乘以玩家人数排名的服务器:过去一天、一周或一个月的平均玩家人数,离线时间按零计算。
GET /v1/history/servers/{serverId}单个服务器(按加入码)每个时间桶的玩家人数、峰值、人数上限、在线率和地图。
GET /v1/history/servers/{serverId}/events单个服务器的变更日志,最新的在前:上线、下线、重启、版本、地图、修饰项和限制变更。
GET /readyz有新鲜快照时返回 200,快照缺失或过期时返回 503。
GET /openapi.jsonOpenAPI 3.1 文档。

筛选服务器列表

/v1/servers 的所有参数都是可选的。除 q 外,取值均区分大小写。

参数取值含义
q文本,最多 200 个字符不区分大小写的搜索,范围包括实例 ID、加入码、名称、地区、服务器编号、地图和模式。
regioneu-west,eu-central一个或多个地区 ID,用逗号分隔。当前列表见 /v1/regions。
typeall · official · community, 默认 all官方服务器、社区服务器,或两者都要。
hideEmptytrue · false排除没有玩家的服务器。
hideFulltrue · false排除已满的服务器,包括 0/0。
passwordProtectedtrue · false只看上锁的或只看未上锁的服务器。不传则两者都包括。
sort-players · players · name · region-players 表示人最多的在前,为默认值。
limit1–500, 默认 100每页数量。
offset0–100000, 默认 0在筛选、排序后的结果中从零开始的偏移量。

响应封装

每个成功的响应都包含 data 和 meta。列表接口还会加上 pagination;历史接口会加上一个 history 对象,描述时间范围、分组、指标和时间桶大小。

在把数字当作当前数据展示之前,先检查 meta.stale。当采集暂停,或快照比 refreshSeconds 加 60 秒还旧时,它为 true。过期的响应还会带上 Cache-Control: no-store 和 X-Data-Stale: true。

字段含义
meta.fetchedAt采集器获取此快照的时间。
meta.snapshotId快照标识符;每当有新数据进来就会改变。也会通过 X-Snapshot-Id 响应头发送。
meta.refreshSeconds采集器的轮询间隔。不要比这个更频繁地轮询。
meta.stale当数据不应作为实时数据展示时为 true。
meta.requestedRegions采集器向游戏请求的地区。
meta.observedRegions在此快照中至少返回了一个服务器的地区。

服务器对象

这是 /v1/servers 和 /v1/snapshot 返回的摘要结构。/v1/servers/{id} 返回相同的字段,外加 attributes、build、level 和 cash。

{
  "id": "001ab36e-9985-4a9c-8dff-9dc137826dfe",
  "serverId": "756872",
  "serverIdUpdatedAt": "2026-09-13T11:14:32.995Z",
  "name": "Official #4",
  "nativeName": "f14859cce268",
  "type": "official",
  "region": "eu-south",
  "players": 100,
  "maxPlayers": 100,
  "reservedPlayers": 0,
  "passwordProtected": false,
  "serverNumber": 4,
  "map": { "variant": "Bakurani", "base": "Europe" },
  "mode": { "experience": "Bakurani_KOTH_01", "gameMode": "GM_Session_C", "modifiers": [] },
  "rulesets": ["standard"]
}
字段含义
id游戏实例的实时 ID。服务器重启后会改变,所以不要把它当作永久键。
serverId游戏内加入码,字符串类型:官方服务器为保留前导零的十进制数字;自游戏补丁 0.11 起,社区服务器为 UUID。尚未采集时为 null。
serverIdUpdatedAt上次查询加入码的时间。serverId 为 null 时它也为 null。
name官方服务器为 Official #N,其他为解码后的服务器名称。可能为空。
nativeName游戏报告的原始服务器名称。
typeofficial 或 community。
region地区 ID,例如 eu-west。
players · maxPlayers · reservedPlayers当前、最大和预留的玩家数。
passwordProtected加入时是否需要密码。
serverNumber官方服务器编号;社区服务器为 0。
map地图变体和基础地图。两者都可能为 null。
mode体验名称和游戏模式名称,以及 experience 字符串中原始的 + 修饰项,按原有顺序排列。
rulesetsstandard、hardcore 或 infantry-only,由修饰项推导而来。无法识别任何规则集时,恰好为 ["standard"]。

历史

/v1/history/players 返回列式序列:一个以 Unix 秒表示的时间桶起始时间数组,以及每个分组键各一个数值数组,按索引对齐。null 值表示该时间桶没有任何记录,通常是因为采集器暂停了。请显示为空缺,不要插值。

从历史记录功能开启起,每个快照记录一次时间桶,不会回填。分钟级时间桶保留 7 天,五分钟级保留 90 天,小时级永久保留。

参数取值含义
window24h · 7d · 30d · 90d · 1y, 默认 24h截至当前的时间范围。时间桶步长:24h 为 60 秒,7d 为 300 秒,30d 和 90d 为 3600 秒,1y 为 21600 秒。
grouptotal · type · region · regionType · map · ruleset, 默认 total每个键对应一条序列:total;official 和 community;地区;region|type;地图变体;或主要规则集。
metricplayers · servers · full · empty · capacity · free, 默认 playersplayers、servers、full(已满)、empty、capacity(maxPlayers 之和)或 free(capacity 减去 players)。每个值是该时间桶内各快照的平均值。
GET /v1/history/players?window=24h&group=type

{
  "data": {
    "t": [1789217880, 1789217940, 1789218000, "…"],
    "series": {
      "official": [248112, 248390, null, "…"],
      "community": [3902, 3911, null, "…"]
    },
    "peak": { "official": ["…"], "community": ["…"] }
  },
  "history": {
    "window": "24h", "group": "type", "metric": "players",
    "step": 60, "from": 1789217880, "to": 1789304280, "since": 1789257600
  },
  "meta": { "…": "…" }
}

当 metric=players 时,响应还会带一个 peak 对象,给出每个时间桶内单个快照的最高值。热力图接口按 UTC 星期和小时计算某项指标在过去 28 个完整天内的平均值,可选只看一个地区。峰值接口报告单个快照的最高玩家人数,包括总体和各类型,涵盖历史最高以及过去 30 个 UTC 日中的每一天。

单个服务器历史

单个服务器历史以加入码为键;与实例 ID 不同,加入码在重启和换图后保持不变。/v1/history/servers/{serverId} 返回对齐的数组:服务器在列期间的平均玩家人数和单次轮询最高值、人数上限、该时间桶内列出它的轮询所占比例(即在线率,0 到 1),以及时间桶结束时的地图,因此连续的地图值就构成了轮换。第一次看到某个加入码时才开始记录,不会回填,在此之前该路由返回 404。

参数取值含义
window24h · 7d · 30d · 90d, 默认 24h24h 和 7d 使用保留 7 天的五分钟级时间桶;30d 和 90d 使用保留 90 天的小时级时间桶。
GET /v1/history/servers/756872?window=24h

{
  "data": {
    "server": {
      "serverId": "756872",
      "name": "Official #4",
      "type": "official",
      "region": "eu-south",
      "instanceId": "001ab36e-9985-4a9c-8dff-9dc137826dfe",
      "firstSeen": "2026-09-13T00:00:39.000Z",
      "lastSeen": "2026-09-14T11:53:22.000Z",
      "samples": 2132,
      "live": true
    },
    "t": [1789300800, 1789301100, 1789301400, "…"],
    "players": [100, 98, null, "…"],
    "peak": [100, 100, null, "…"],
    "capacity": [100, 100, null, "…"],
    "online": [1, 0.8, null, "…"],
    "map": ["Bakurani", "Bakurani", null, "…"]
  },
  "history": {
    "window": "24h", "step": 300,
    "from": 1789300800, "to": 1789387200, "since": 1789257600
  },
  "meta": { "…": "…" }
}

/v1/history/servers/{serverId}/events 根据连续的轮询推算出变更日志,最新的在前:tracking_started、online、offline、restart(实例改变且没有空缺)、build(changelist)、map(变体、世界或天空)、modifiers 和 limits(等级和资金范围、密码和人数上限)。每个事件带有 at、kind,以及只包含定义该类型的字段的 before 和 after 对象,没有更早或更晚状态时为 null。limit 取值 1 到 500,默认 100。

GET /v1/history/servers/756872/events?limit=3

{
  "data": {
    "server": { "serverId": "756872", "name": "Official #4", "…": "…" },
    "events": [
      {
        "at": "2026-09-14T12:40:30.000Z",
        "kind": "map",
        "before": { "map": "Madrid", "world": "Europe", "sky": "DayEarlyFog" },
        "after": { "map": "Detroit", "world": "Europe", "sky": "DayLateGray" }
      },
      {
        "at": "2026-09-14T09:12:04.000Z",
        "kind": "restart",
        "before": { "instanceId": "001ab36e-9985-4a9c-8dff-9dc137826dfe" },
        "after": { "instanceId": "7c1e0b52-3d9a-4e1f-9b6e-2f4c8a9d0e11" }
      },
      {
        "at": "2026-09-13T00:00:39.000Z",
        "kind": "tracking_started",
        "before": null,
        "after": { "instanceId": "…", "changelist": "501228", "map": "Bakurani", "…": "…" }
      }
    ]
  },
  "history": { "limit": 3, "since": 1789257600 },
  "meta": { "…": "…" }
}

/v1/history/servers 列出已记录的服务器,最近出现的在前。q 精确匹配加入码,或不区分大小写地匹配最后已知名称,所以能找到当前离线的服务器;在线服务器在 /v1/servers 中已经带有 serverId。

参数取值含义
q文本,最多 200 个字符加入码(精确匹配)或最后已知名称(不区分大小写匹配)。
typeall · official · community, 默认 all官方服务器、社区服务器,或两者都要。
limit1–100, 默认 20返回多少个服务器。

缓存与轮询

每个响应都带有 ETag。把它作为 If-None-Match 发回来,快照未变时会返回不带响应体的 304,双方几乎都没有开销。推荐的用法是每分钟带 If-None-Match 轮询一次。

const res = await fetch('https://api.wardogservers.com/v1/snapshot', {
  headers: lastEtag ? { 'if-none-match': lastEtag } : {}
});
if (res.status === 304) return; // 自上次轮询以来没有变化
lastEtag = res.headers.get('etag');
const { data, meta } = await res.json();
if (meta.stale) console.warn('stale'); // 采集器落后了;继续显示最后已知的数据

新鲜的响应会在边缘节点缓存 15 秒,所以短时间内大量相同的请求开销很低。目前没有硬性速率限制,但比 meta.refreshSeconds 更频繁地轮询并不能拿到更新的数据,将来也可能被限速。如果你需要完整列表,请获取一次 /v1/snapshot 后在本地筛选,而不是翻页遍历 /v1/servers。

错误

错误以 JSON 返回,包含稳定的 code 和人类可读的 message。message 可能会变;请根据 code 判断。

{
  "error": {
    "code": "bad_request",
    "message": "An unsupported query parameter was supplied."
  }
}
状态码何时出现
400查询参数未知、重复或无效,或者 ID 不是 UUID。
401需要 API 密钥,但缺失或错误。公开访问开启期间,读取请求不会返回此错误。
404当前快照中没有该 ID 的服务器、该加入码没有历史记录,或路由不存在。
405使用了 GET 或 HEAD 以外的方法。
503没有可用的快照。请一分钟后或在 /readyz 返回 200 时重试。

使用条款

API 对社区项目免费开放:Discord 机器人、直播叠加层、仪表盘、研究。公开展示数据时,请附上指向 Wardog Servers 的链接注明出处,并且不要把它说成是 BULKHEAD 或 Team17 的官方数据。

读取 API 的版本路径为 /v1。同一版本内可能会新增字段,所以请兼容你不认识的键。破坏性变更将作为新版本发布,并会先在本页公布。

有问题、想展示你的项目,或需要某个字段:Discord @xcausxn。