公开 API

PVZ: Voyage API 文档

这里汇总了面向启动器、机器人、镜像站和资料工具的公开接口。建议先读取最新版本详情,再按需获取图鉴、世界、搜索、动态或 RSS 数据。

这些接口通过静态构建生成,公开可读,不包含用户状态,也不需要鉴权。API JSON 本身不会出现在搜索结果中;面向读者的索引是此页面。

三步接入

大多数客户端只需要最新版本详情、一个下载 URL,以及一次 SHA-256 校验。

  1. 步骤 1

    读取最新版本

    请求版本详情,并选择与设备匹配的平台 key。

    /api/v1/releases/latest.json
  2. 步骤 2

    下载并校验

    使用 builds.*.url 下载文件,完成后用 builds.*.sha256 校验。

    /download/0.17p/windows
  3. 步骤 3

    展示更新内容

    启动器可以读取 news JSON;社区公告机器人可以读取 changelog 或 RSS。

    /api/v1/news/zh.json

端点目录

按用途筛选。每个卡片都可复制真实示例 URL。

版本

版本与更新

当前版本、各平台构建、校验值和更新日志。

内容

图鉴与世界资料

图鉴条目、世界区域、你知道吗冷知识以及本地化正文。

搜索/动态

搜索与动态

稳定的搜索语料、公告流,以及适合机器人的订阅入口。

下载

下载路由

由 R2 提供的二进制下载,支持 HEAD 和 Range 请求。

RSS

RSS 订阅

面向阅读器的 RSS 2.0 发布源。

GET · 版本

最新版本详情

适用于启动器、镜像站和机器人的完整版本详情,包含所有平台的构建信息。

/api/v1/releases/latest.json

GET · 版本

自动更新清单

这份更新清单兼容旧客户端;顶层字段保留 Windows 64 位主构建,builds 则包含所有平台。

/api/v1/updates/latest.json

GET · 版本

版本索引

列出已公开版本,并提供当前 latest 字段和版本详情链接。

/api/v1/releases.json

GET · 版本

结构化更新日志

一次返回中英两种更新日志内容,适合公告机器人和启动器更新页。

/api/v1/changelog/0.17p.json

GET · 内容

世界区域索引

本地化世界设定索引;目前没有单独的区域详情 JSON,区域完整段落直接放在 regions 中。

/api/v1/world/zh/index.json

GET · 内容

你知道吗目录

本地化冷知识与玩法贴士目录;首页卡片与外部工具都读取这套人工校验内容。

/api/v1/did-you-know/zh/index.json

GET · 搜索/动态

稳定搜索语料

这是面向外部工具的站内搜索文档封装;不要依赖根目录的 search-index 文件。

/api/v1/search/zh.json

GET · 搜索/动态

动态与公告 JSON

面向启动器、机器人和聚合器的本地化新闻流。

/api/v1/news/zh.json

GET · HEAD · 下载

二进制下载

用于下载 Windows 和 Android 构建;支持 HEAD 预检和单段 Range 请求,文件名会通过 Content-Disposition 返回。

/download/0.17p/windows

GET · RSS

RSS 发布源

RSS 2.0 发布源;每个版本对应一个 item,并链接到本地化更新日志。

/zh/feed.xml

端点详情

展开后可查看字段摘要、精简响应示例,以及带标准 User-Agent 的 curl 和服务端 fetch 示例。

GET

最新版本详情

/api/v1/releases/latest.json
适用场景
启动器、镜像站、下载机器人
缓存
public, max-age=300, s-maxage=3600, must-revalidate
Schema
1
字段摘要
字段类型说明
version string 当前版本号。
platforms string[] 可用的平台 key 列表。
builds object 按平台 key 索引的构建详情。
builds.*.sha256 string 二进制文件的 SHA-256 校验值。
feeds object 中英文 RSS 订阅链接。
urls.canonical Link 固定版本详情 URL。

精简版版本详情

{
  "schemaVersion": 1,
  "kind": "release",
  "version": "0.17p",
  "releasedAt": "2026-05-01",
  "latest": true,
  "primaryPlatform": "windows",
  "platforms": [
    "windows",
    "windows-zip",
    "windows-x86",
    "windows-x86-zip",
    "android"
  ],
  "urls": {
    "self": {
      "path": "/api/v1/releases/latest.json",
      "url": "https://pvzvoyage.com/api/v1/releases/latest.json"
    },
    "canonical": {
      "path": "/api/v1/releases/0.17p.json",
      "url": "https://pvzvoyage.com/api/v1/releases/0.17p.json"
    }
  },
  "builds": {
    "windows": {
      "platformKey": "windows",
      "platform": {
        "zh": "Windows 64 位(自解压)",
        "en": "Windows x64 (self-extracting EXE)"
      },
      "path": "/download/0.17p/windows",
      "url": "https://pvzvoyage.com/download/0.17p/windows",
      "aliasPath": "/download/0.17p/windows.exe",
      "filename": "PVZ-Voyage-0.17p-Windows-x64.exe",
      "size": 147749281,
      "sizeMiB": 140.9,
      "sha256": "788532e0381dda16784f62d3bc2df6d6e7adaf7ad9674f76742efb21db5c4988",
      "digest": {
        "algorithm": "SHA-256",
        "hex": "788532e0381dda16784f62d3bc2df6d6e7adaf7ad9674f76742efb21db5c4988"
      },
      "mime": "application/vnd.microsoft.portable-executable",
      "extension": ".exe",
      "minOs": {
        "name": "Windows 7",
        "build": 7600,
        "label": "Windows 7+"
      },
      "note": "示例只展示 Windows 64 位构建;真实响应会包含所有平台。"
    }
  }
}

curl

curl -fsSL \
  -A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
  https://pvzvoyage.com/api/v1/releases/latest.json

fetch

// Server-side fetch example. Browser fetch sends a browser User-Agent automatically.
const response = await fetch("https://pvzvoyage.com/api/v1/releases/latest.json", {
  headers: {
    "User-Agent": "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)",
  },
});
if (!response.ok) {
  throw new Error(`PVZ: Voyage API failed: ${response.status}`);
}
const release = await response.json();
  • 如果需要长期引用同一版本,请保存 urls.canonical 指向的固定版本 URL。
  • 客户端应从 builds 中选择平台,而不是硬编码下载 URL。
GET

自动更新清单

/api/v1/updates/latest.json
适用场景
自动更新器、启动器
缓存
public, max-age=300, s-maxage=3600, must-revalidate
Schema
2
字段摘要
字段类型说明
url string 主构建下载 URL,保留给 v1 客户端使用。
sha256 string 主构建的校验值。
builds object 所有平台的构建信息。
minOs object 最低系统要求。
changelog object 更新日志页面和 JSON changelog 链接。

自动更新样例

{
  "schemaVersion": 2,
  "version": "0.17p",
  "releasedAt": "2026-05-01",
  "url": "https://pvzvoyage.com/download/0.17p/windows",
  "sha256": "788532e0381dda16784f62d3bc2df6d6e7adaf7ad9674f76742efb21db5c4988",
  "size": 147749281,
  "filename": "PVZ-Voyage-0.17p-Windows-x64.exe",
  "minOs": {
    "name": "Windows 7",
    "build": 7600
  },
  "builds": {
    "windows": {
      "url": "https://pvzvoyage.com/download/0.17p/windows",
      "sha256": "788532e0381dda16784f62d3bc2df6d6e7adaf7ad9674f76742efb21db5c4988",
      "size": 147749281,
      "filename": "PVZ-Voyage-0.17p-Windows-x64.exe",
      "minOs": {
        "name": "Windows 7",
        "build": 7600
      }
    }
  }
}

curl

curl -fsSL \
  -A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
  https://pvzvoyage.com/api/v1/updates/latest.json

fetch

// Server-side fetch example. Browser fetch sends a browser User-Agent automatically.
const response = await fetch("https://pvzvoyage.com/api/v1/updates/latest.json", {
  headers: {
    "User-Agent": "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)",
  },
});
if (!response.ok) {
  throw new Error(`PVZ: Voyage API failed: ${response.status}`);
}
const manifest = await response.json();
  • 如果你维护的是新客户端,优先读取版本详情;它比自动更新清单更完整。
  • 顶层字段只是兼容层,并不代表只有这些平台可下载。
GET

版本索引

/api/v1/releases.json
适用场景
版本列表、历史版本入口
缓存
public, max-age=300, s-maxage=3600, must-revalidate
Schema
1
字段摘要
字段类型说明
latest string 最新版本号。
releases array 已公开版本列表。
releases[].detail string 固定版本详情 API。
releases[].latestDetail string | null 当前版本的 latest 详情别名。

版本索引样例

{
  "schemaVersion": 1,
  "latest": "0.17p",
  "releases": [
    {
      "version": "0.17p",
      "releasedAt": "2026-05-01",
      "url": "https://pvzvoyage.com/download/0.17p/windows",
      "sha256": "788532e0381dda16784f62d3bc2df6d6e7adaf7ad9674f76742efb21db5c4988",
      "detail": "https://pvzvoyage.com/api/v1/releases/0.17p.json",
      "latestDetail": "https://pvzvoyage.com/api/v1/releases/latest.json"
    }
  ]
}

curl

curl -fsSL \
  -A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
  https://pvzvoyage.com/api/v1/releases.json

fetch

// Server-side fetch example. Browser fetch sends a browser User-Agent automatically.
const response = await fetch("https://pvzvoyage.com/api/v1/releases.json", {
  headers: {
    "User-Agent": "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)",
  },
});
if (!response.ok) {
  throw new Error(`PVZ: Voyage API failed: ${response.status}`);
}
const index = await response.json();
  • 只需要版本列表时使用它;如果需要平台构建信息,再读取 detail 字段指向的详情。
GET

结构化更新日志

/api/v1/changelog/{version}.json
适用场景
公告机器人、更新页、社区工具
缓存
public, max-age=300, s-maxage=3600, must-revalidate
Schema
1
字段摘要
字段类型说明
version string 这份更新日志对应的版本。
locales.zh object 中文更新日志。
locales.en object 英文更新日志。
sections array 标题、段落、小节和条目。

更新日志结构样例

{
  "schemaVersion": 1,
  "version": "0.17p",
  "releasedAt": "2026-05-01",
  "locales": {
    "zh": {
      "title": "远征 0.17p 更新日志",
      "sections": [
        {
          "title": "版本亮点",
          "paragraphs": [
            "..."
          ],
          "sections": []
        }
      ]
    }
  }
}

curl

curl -fsSL \
  -A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
  https://pvzvoyage.com/api/v1/changelog/0.17p.json

fetch

// Server-side fetch example. Browser fetch sends a browser User-Agent automatically.
const response = await fetch("https://pvzvoyage.com/api/v1/changelog/0.17p.json", {
  headers: {
    "User-Agent": "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)",
  },
});
if (!response.ok) {
  throw new Error(`PVZ: Voyage API failed: ${response.status}`);
}
const changelog = await response.json();
  • 当前站点只为当前版本提供结构化 changelog。
GET

图鉴索引

/api/v1/encyclopedia/{locale}/index.json
适用场景
图鉴浏览器、Wiki 工具、站内搜索
缓存
public, max-age=300, s-maxage=3600, must-revalidate
Schema
1
字段摘要
字段类型说明
locale 'zh' | 'en' 当前语言。
tabs array 植物、僵尸、Boss 分类与计数。
entries array 条目摘要、页面 URL、API URL 和肖像。
alternate object 另一语言的页面与 API。

图鉴索引样例

{
  "schemaVersion": 1,
  "kind": "encyclopediaIndex",
  "locale": "zh",
  "title": "远征图鉴",
  "counts": {
    "total": 48,
    "byKind": {
      "plant": 22,
      "zombie": 16,
      "boss": 10
    }
  },
  "entries": [
    {
      "slug": "peashooter",
      "name": "豌豆射手",
      "kind": "plant",
      "path": "/zh/encyclopedia/peashooter/",
      "api": {
        "path": "/api/v1/encyclopedia/zh/peashooter.json",
        "url": "https://pvzvoyage.com/api/v1/encyclopedia/zh/peashooter.json"
      },
      "portrait": {
        "avif": {
          "path": "/media/encyclopedia/peashooter.avif"
        },
        "width": 1200,
        "height": 1185
      }
    }
  ]
}

curl

curl -fsSL \
  -A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
  https://pvzvoyage.com/api/v1/encyclopedia/zh/index.json

fetch

// Server-side fetch example. Browser fetch sends a browser User-Agent automatically.
const response = await fetch("https://pvzvoyage.com/api/v1/encyclopedia/zh/index.json", {
  headers: {
    "User-Agent": "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)",
  },
});
if (!response.ok) {
  throw new Error(`PVZ: Voyage API failed: ${response.status}`);
}
const fieldGuide = await response.json();
  • slug 列表来自内容模块;不要照着文档硬编码。
GET

图鉴条目详情

/api/v1/encyclopedia/{locale}/{slug}.json
适用场景
资料库、机器人、图鉴镜像
缓存
public, max-age=300, s-maxage=3600, must-revalidate
Schema
1
字段摘要
字段类型说明
entry object 条目正文、定位、能力与高级机制。
portrait object AVIF/WebP/PNG 肖像与尺寸。
navigation object 上一个/下一个条目摘要。
alternate object | null 另一语言的条目。

条目详情样例

{
  "schemaVersion": 1,
  "kind": "encyclopediaEntry",
  "locale": "zh",
  "slug": "peashooter",
  "entry": {
    "slug": "peashooter",
    "kind": "plant",
    "name": "豌豆射手",
    "mechanics": {
      "role": "远程攻击 · 杂交基础",
      "abilities": [
        "..."
      ]
    },
    "interactions": [
      {
        "target": "坚果墙",
        "targetSlug": "wall-nut",
        "effect": "..."
      }
    ]
  },
  "portrait": {
    "png": {
      "path": "/media/encyclopedia/peashooter.png"
    },
    "width": 1200,
    "height": 1185
  }
}

curl

curl -fsSL \
  -A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
  https://pvzvoyage.com/api/v1/encyclopedia/zh/peashooter.json

fetch

// Server-side fetch example. Browser fetch sends a browser User-Agent automatically.
const response = await fetch("https://pvzvoyage.com/api/v1/encyclopedia/zh/peashooter.json", {
  headers: {
    "User-Agent": "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)",
  },
});
if (!response.ok) {
  throw new Error(`PVZ: Voyage API failed: ${response.status}`);
}
const entry = await response.json();
  • 高级机制字段只在有对应资料的条目上出现。
GET

世界区域索引

/api/v1/world/{locale}/index.json
适用场景
地图、资料库、区域浏览器
缓存
public, max-age=300, s-maxage=3600, must-revalidate
Schema
1
字段摘要
字段类型说明
regions array 区域 slug、编号、标题、简介、段落与视觉资源。
visual object 卡片/首屏图片与主题色。
alternate object 另一语言的世界索引。

世界索引样例

{
  "schemaVersion": 1,
  "kind": "worldIndex",
  "locale": "zh",
  "count": 4,
  "regions": [
    {
      "slug": "maple-falls",
      "number": "I",
      "title": "枫威瀑布",
      "summary": "...",
      "path": "/zh/world/maple-falls/",
      "visual": {
        "accent": "#8da66b",
        "motif": "wind / lake / stairway"
      }
    }
  ]
}

curl

curl -fsSL \
  -A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
  https://pvzvoyage.com/api/v1/world/zh/index.json

fetch

// Server-side fetch example. Browser fetch sends a browser User-Agent automatically.
const response = await fetch("https://pvzvoyage.com/api/v1/world/zh/index.json", {
  headers: {
    "User-Agent": "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)",
  },
});
if (!response.ok) {
  throw new Error(`PVZ: Voyage API failed: ${response.status}`);
}
const world = await response.json();
  • 不同语言共用稳定的区域 slug;标题和正文会随 locale 本地化。
GET

你知道吗目录

/api/v1/did-you-know/{locale}/index.json
适用场景
启动器、机器人、资料工具、首页本地选择
缓存
public, max-age=300, s-maxage=3600, must-revalidate
Schema
1
字段摘要
字段类型说明
counts object 总数以及按 trivia、tip、mechanic、lore 分组的计数。
filters object 可用 contexts、kinds、spoilerLevels 与 tags。
selectionDefaults.homeHero object 首页默认选择规则。
items array 本地化条目数组,含正文、来源、标签、权重和关联图鉴。
items[].sourceRefs array 发布前校验过的本地来源。

你知道吗目录样例

{
  "schemaVersion": 1,
  "kind": "didYouKnowIndex",
  "locale": "zh",
  "counts": {
    "total": 36,
    "byKind": {
      "trivia": 2,
      "tip": 22,
      "mechanic": 11,
      "lore": 1
    }
  },
  "selectionDefaults": {
    "homeHero": {
      "allowedSpoilerLevels": [
        "none",
        "mild",
        "mechanics"
      ],
      "preferredRelatedSlugs": [
        "sunflower",
        "peashooter"
      ],
      "maxRecentIds": 12
    }
  },
  "items": [
    {
      "id": "sunflower-match-inheritance",
      "kind": "mechanic",
      "text": "向日葵连线不再区分方向;搭配阳光椰瓶时,还能继承大阳光充能。",
      "spoilerLevel": "mechanics",
      "contexts": [
        "homeHero",
        "encyclopedia",
        "api"
      ],
      "relatedEntries": [
        {
          "slug": "sunflower",
          "name": "向日葵",
          "path": "/zh/encyclopedia/sunflower/"
        }
      ]
    }
  ]
}

curl

curl -fsSL \
  -A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
  https://pvzvoyage.com/api/v1/did-you-know/zh/index.json

fetch

// Server-side fetch example. Browser fetch sends a browser User-Agent automatically.
const response = await fetch("https://pvzvoyage.com/api/v1/did-you-know/zh/index.json", {
  headers: {
    "User-Agent": "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)",
  },
});
if (!response.ok) {
  throw new Error(`PVZ: Voyage API failed: ${response.status}`);
}
const didYouKnow = await response.json();
  • 条目由仓库内容文件人工维护,并在构建时校验 ID、语言、slug、长度、标签和剧透等级。
  • 如果只需要一条结果,可以使用 random.json;如果要自行缓存或筛选,请读取完整目录。
GET · HEAD

随机你知道吗

/api/v1/did-you-know/{locale}/random.json
适用场景
启动器欢迎页、机器人、轻量工具
缓存
显式 seed 使用 public, max-age=300, s-maxage=3600;无 seed 使用 UTC 小时桶和 public, max-age=60, s-maxage=300
Schema
1
字段摘要
字段类型说明
context query homeHero、encyclopedia、api 或 any。
kind query 逗号分隔的 trivia、tip、mechanic、lore。
entry query 关联图鉴 slug;默认作为偏好,strictEntry=1 时变为必需。
spoilerMax query 允许的最高剧透等级;homeHero 默认 mechanics,其他场景默认 lateGame。
exclude query 逗号分隔的条目 ID,最多处理前 20 个。
selection object 实际使用的 seed、池大小、排除数量与过滤器。
item object 被选中的 DidYouKnow 条目。

随机选择样例

{
  "schemaVersion": 1,
  "kind": "didYouKnowSelection",
  "locale": "zh",
  "selection": {
    "strategy": "weighted-stable-random",
    "seed": "session-42",
    "context": "homeHero",
    "poolSize": 31,
    "excludedCount": 0,
    "filters": {
      "entry": "sunflower",
      "strictEntry": false,
      "spoilerMax": "mechanics"
    }
  },
  "item": {
    "id": "sunflower-match-inheritance",
    "kind": "mechanic",
    "text": "向日葵连线不再区分方向;搭配阳光椰瓶时,还能继承大阳光充能。",
    "cta": {
      "path": "/zh/encyclopedia/sunflower/",
      "url": "https://pvzvoyage.com/zh/encyclopedia/sunflower/"
    }
  }
}

curl

curl -fsSL \
  -A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
  "https://pvzvoyage.com/api/v1/did-you-know/zh/random.json?context=homeHero&entry=sunflower&seed=session-42"

fetch

// Server-side fetch example. Browser fetch sends a browser User-Agent automatically.
const response = await fetch("https://pvzvoyage.com/api/v1/did-you-know/zh/random.json?context=homeHero&entry=sunflower&seed=session-42", {
  headers: {
    "User-Agent": "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)",
  },
});
if (!response.ok) {
  throw new Error(`PVZ: Voyage API failed: ${response.status}`);
}
const selection = await response.json();
  • 同一目录、同一查询和同一 seed 会得到稳定结果;目录内容变化后不保证仍选中同一条。
  • 错误参数返回 JSON 400;没有匹配条目返回 JSON 404,code 为 no_matching_item。
GET

稳定搜索语料

/api/v1/search/{locale}.json
适用场景
机器人、站外搜索、轻量镜像
缓存
public, max-age=300, s-maxage=3600, must-revalidate
Schema
1
字段摘要
字段类型说明
documentCount number 文档数量。
source object 站内搜索源文件说明。
documents array 标准化文档数组。
documents[].kind string nav、changelog、world、encyclopedia、mechanics、channel、faq 等。

搜索文档样例

{
  "schemaVersion": 1,
  "kind": "searchIndex",
  "locale": "zh",
  "documentCount": 100,
  "documents": [
    {
      "id": "encyclopedia:zh:peashooter",
      "kind": "encyclopedia",
      "title": "豌豆射手",
      "subtitle": "植物档案 · 初始拥有",
      "path": "/zh/encyclopedia/peashooter/",
      "url": "https://pvzvoyage.com/zh/encyclopedia/peashooter/",
      "aliases": [
        "peashooter",
        "豌豆射手",
        "plant"
      ]
    }
  ]
}

curl

curl -fsSL \
  -A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
  https://pvzvoyage.com/api/v1/search/zh.json

fetch

// Server-side fetch example. Browser fetch sends a browser User-Agent automatically.
const response = await fetch("https://pvzvoyage.com/api/v1/search/zh.json", {
  headers: {
    "User-Agent": "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)",
  },
});
if (!response.ok) {
  throw new Error(`PVZ: Voyage API failed: ${response.status}`);
}
const searchIndex = await response.json();
  • 根目录 search-index-*.json 面向站内 UI,不是稳定 API。
GET

动态与公告 JSON

/api/v1/news/{locale}.json
适用场景
启动器新闻栏、Discord/QQ 机器人、聚合器
缓存
public, max-age=300, s-maxage=3600, must-revalidate
Schema
1
字段摘要
字段类型说明
latestVersion string 最新版本。
links object 首页、下载、更新日志、RSS 与 release API。
items array 公告条目。
items[].highlights array 结构化亮点。

动态流样例

{
  "schemaVersion": 1,
  "kind": "newsFeed",
  "locale": "zh",
  "latestVersion": "0.17p",
  "items": [
    {
      "id": "release-0.17p",
      "kind": "release",
      "version": "0.17p",
      "title": "PVZ: Voyage 0.17p 已发布",
      "publishedAt": "2026-05-01",
      "api": {
        "path": "/api/v1/releases/0.17p.json",
        "url": "https://pvzvoyage.com/api/v1/releases/0.17p.json"
      }
    }
  ]
}

curl

curl -fsSL \
  -A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
  https://pvzvoyage.com/api/v1/news/zh.json

fetch

// Server-side fetch example. Browser fetch sends a browser User-Agent automatically.
const response = await fetch("https://pvzvoyage.com/api/v1/news/zh.json", {
  headers: {
    "User-Agent": "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)",
  },
});
if (!response.ok) {
  throw new Error(`PVZ: Voyage API failed: ${response.status}`);
}
const news = await response.json();
  • 给 RSS 阅读器请使用 RSS feed;给程序客户端请使用这个 JSON。
GET · HEAD

二进制下载

/download/{version}/{platform}
适用场景
启动器、镜像站、下载页面
缓存
public, max-age=3600, s-maxage=86400, immutable
Schema
binary
字段摘要
字段类型说明
Content-Type header 构建的 MIME 类型,例如 application/zip 或 Android APK 的 MIME 类型。
Content-Disposition header 附件文件名。
Accept-Ranges header 表示支持 bytes 范围请求。
Range request header 请求单个字节范围。
Retry-After header 响应为 429 时返回。

HEAD 预检示例

HTTP/2 200
content-type: application/vnd.microsoft.portable-executable
content-disposition: attachment; filename="PVZ-Voyage-0.17p-Windows-x64.exe"
accept-ranges: bytes
cache-control: public, max-age=3600, s-maxage=86400, immutable

HEAD

curl -I \
  -A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
  https://pvzvoyage.com/download/0.17p/windows

Range

curl -L \
  -A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
  -H "Range: bytes=0-1048575" \
  -o pvzvoyage.part \
  https://pvzvoyage.com/download/0.17p/windows

fetch

// Server-side fetch example. Browser fetch sends a browser User-Agent automatically.
const head = await fetch("https://pvzvoyage.com/download/0.17p/windows", {
  method: "HEAD",
  headers: {
    "User-Agent": "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)",
  },
});
const size = Number(head.headers.get("content-length") ?? 0);
const filename = head.headers.get("content-disposition");
  • 先读取版本详情,再使用其中的 builds.*.url。
  • 下载完成后,使用 builds.*.sha256 校验完整性。
  • 只支持单段 Range;多段或非法 Range 会返回 416。
GET

RSS 发布源

/zh/feed.xml
适用场景
RSS 阅读器、订阅服务
缓存
通过 Worker 响应头应用静态资源缓存
Schema
feed
字段摘要
字段类型说明
channel RSS 站点发布源。
item RSS 版本条目。
link RSS 本地化更新日志链接。
pubDate RSS 发布日期。

RSS 片段

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>PVZ: Voyage</title>
    <item>
      <title>PVZ: Voyage 0.17p 已发布</title>
      <link>https://pvzvoyage.com/zh/version/0.17p/</link>
    </item>
  </channel>
</rss>

curl

curl -fsSL \
  -A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
  https://pvzvoyage.com/zh/feed.xml

fetch

// Server-side fetch example. Browser fetch sends a browser User-Agent automatically.
const response = await fetch("https://pvzvoyage.com/zh/feed.xml", {
  headers: {
    "User-Agent": "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)",
  },
});
const xml = await response.text();
  • RSS 适合阅读器;程序化公告建议使用 /api/v1/news/{locale}.json。

客户端下载逻辑建议

不要在客户端中硬编码二进制文件的下载路径。客户端应先获取最新版本详情,再根据目标平台从 builds 中选择对应构建。下载路由支持 HEAD 预检、GET 下载,以及单段 Range 断点续传。下载完成后,必须使用 SHA-256 校验文件完整性。

选择 JSON 还是 RSS?

两者都来自同一套静态构建流程,但适用对象不同。

使用 News JSON

News JSON 包含结构化字段、CTA、图片、tag 和 release API 链接,更适合程序读取。

  • 启动器新闻栏
  • 机器人公告
  • 站外聚合器
/api/v1/news/zh.json

使用 RSS

RSS 2.0 更适合阅读器和通用订阅服务。

  • RSS 阅读器
  • 个人订阅
  • 低维护通知
/zh/feed.xml

请求头、错误与版本策略

User-Agent

命令行工具、脚本和服务端客户端应发送能够标识集成来源的 UA,例如:PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)。如果你维护自己的客户端,可以替换 product/version 和支持 URL。浏览器 fetch 会自动携带浏览器 UA。

CORS

JSON API 响应允许跨源读取:Access-Control-Allow-Origin: *。

缓存

API JSON 使用较短的浏览器缓存和较长的边缘缓存;下载文件使用带版本路径的 immutable 缓存。

404

未知的 .json API 路径会返回 JSON 错误对象,而不是 HTML 404 页面。少数不符合公开接口调用约定的请求,可能先由站点边缘层返回普通 404;这类响应不保证采用上述 JSON 错误格式。

兼容性

/api/v1 会尽力保持稳定;新增字段可能不会提升 schemaVersion。破坏性结构变更会使用新的 schemaVersion,或未来的 /api/v2 路径。