Release
Release and updates
Current version, platform builds, checksums, and changelog data.
PUBLIC API
Public interface notes for launchers, bots, mirrors, and data tools. Start with latest release detail, then fetch Field Guide, world, search, news, or RSS data as needed.
These endpoints are static-first public data surfaces. They do not contain user state and do not require authentication. API JSON itself is kept out of search results; this page is the human-facing index.
Most clients only need latest release detail, one download URL, and one checksum verification.
Step 1
Request release detail and choose the platform key that matches the device.
/api/v1/releases/latest.jsonStep 2
Download from builds.*.url and verify the finished file with builds.*.sha256.
/download/0.17p/windowsStep 3
Launchers can read news JSON; community announcement bots can read changelog or RSS.
/api/v1/news/en.jsonFilter by use case. Every card exposes a copyable concrete example URL.
Release
Current version, platform builds, checksums, and changelog data.
Content
Encyclopedia entries, world regions, DidYouKnow trivia, and localized prose.
Search/news
Stable search corpus, announcement feed, and bot-friendly updates.
Downloads
R2-backed binary downloads with HEAD and Range support.
RSS
RSS 2.0 release feeds for feed readers.
GET · Release
Recommended release detail for launchers, mirrors, and bots. Includes every platform build.
/api/v1/releases/latest.jsonGET · Release
Updater manifest with backward-compatible top-level Windows x64 fields and a full builds matrix.
/api/v1/updates/latest.jsonGET · Release
Lists public releases with the current latest version and detail links.
/api/v1/releases.jsonGET · Release
Returns both localized changelogs in one payload for announcement bots and launcher news panes.
/api/v1/changelog/0.17p.jsonGET · Content
Localized Field Guide catalog with counts, entry links, portrait assets, and alternate locale links.
/api/v1/encyclopedia/en/index.jsonGET · Content
Localized detail for one plant, zombie, or boss, including mechanics, interactions, portrait, and navigation.
/api/v1/encyclopedia/en/peashooter.jsonGET · Content
Localized world codex. There is no separate region-detail JSON; full paragraphs are included in regions.
/api/v1/world/en/index.jsonGET · Content
Localized trivia and gameplay tips used by the homepage card and external tools.
/api/v1/did-you-know/en/index.jsonGET · HEAD · Content
Worker-composed deterministic selection over the static catalog for clients that need one trivia item.
/api/v1/did-you-know/en/random.json?context=homeHero&entry=sunflower&seed=session-42GET · Search/news
Public wrapper for site-search documents. Do not depend on the root search-index files.
/api/v1/search/en.jsonGET · Search/news
Localized news feed for launchers, bots, and aggregators.
/api/v1/news/en.jsonGET · HEAD · Downloads
Download Windows and Android builds. Supports HEAD and single byte ranges; filenames are returned through Content-Disposition.
/download/0.17p/windowsGET · RSS
RSS 2.0 feed with one item per release, linking to the localized changelog.
/feed.xmlOpen a panel for field summaries, trimmed responses, and curl/server-side fetch examples with the standard User-Agent.
/api/v1/releases/latest.json| Field | Type | Description |
|---|---|---|
| version | string | Current release version. |
| platforms | string[] | Available platform keys. |
| builds | object | Build details keyed by platform. |
| builds.*.sha256 | string | SHA-256 digest for the binary. |
| feeds | object | English and Chinese RSS feed links. |
| urls.canonical | Link | Version-pinned detail 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": "Example shows the Windows x64 build only; the real payload includes every platform."
}
}
}
curl -fsSL \
-A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
https://pvzvoyage.com/api/v1/releases/latest.json
// 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();
/api/v1/updates/latest.json| Field | Type | Description |
|---|---|---|
| url | string | Primary build download URL kept for v1 consumers. |
| sha256 | string | Primary build checksum. |
| builds | object | All platform builds. |
| minOs | object | Minimum OS requirement. |
| changelog | object | Human changelog pages and JSON changelog link. |
{
"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 -fsSL \
-A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
https://pvzvoyage.com/api/v1/updates/latest.json
// 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();
/api/v1/releases.json| Field | Type | Description |
|---|---|---|
| latest | string | Latest version. |
| releases | array | Published releases. |
| releases[].detail | string | Version-pinned detail API. |
| releases[].latestDetail | string | null | Latest detail alias for the current version. |
{
"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 -fsSL \
-A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
https://pvzvoyage.com/api/v1/releases.json
// 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();
/api/v1/changelog/{version}.json| Field | Type | Description |
|---|---|---|
| version | string | Version represented by the changelog. |
| locales.zh | object | Chinese changelog. |
| locales.en | object | English changelog. |
| sections | array | Headings, paragraphs, subsections, and items. |
{
"schemaVersion": 1,
"version": "0.17p",
"releasedAt": "2026-05-01",
"locales": {
"en": {
"title": "PVZ: Voyage 0.17p Changelog",
"sections": [
{
"title": "Highlights",
"paragraphs": [
"..."
],
"sections": []
}
]
}
}
}
curl -fsSL \
-A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
https://pvzvoyage.com/api/v1/changelog/0.17p.json
// 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();
/api/v1/encyclopedia/{locale}/index.json| Field | Type | Description |
|---|---|---|
| locale | 'zh' | 'en' | Current locale. |
| tabs | array | Plant, zombie, and boss categories with counts. |
| entries | array | Entry summaries, page URLs, API URLs, and portraits. |
| alternate | object | Other-locale page and API. |
{
"schemaVersion": 1,
"kind": "encyclopediaIndex",
"locale": "en",
"title": "Field Guide",
"counts": {
"total": 48,
"byKind": {
"plant": 22,
"zombie": 16,
"boss": 10
}
},
"entries": [
{
"slug": "peashooter",
"name": "Peashooter",
"kind": "plant",
"path": "/en/encyclopedia/peashooter/",
"api": {
"path": "/api/v1/encyclopedia/en/peashooter.json",
"url": "https://pvzvoyage.com/api/v1/encyclopedia/en/peashooter.json"
},
"portrait": {
"avif": {
"path": "/media/encyclopedia/peashooter.avif"
},
"width": 1200,
"height": 1185
}
}
]
}
curl -fsSL \
-A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
https://pvzvoyage.com/api/v1/encyclopedia/en/index.json
// Server-side fetch example. Browser fetch sends a browser User-Agent automatically.
const response = await fetch("https://pvzvoyage.com/api/v1/encyclopedia/en/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();
/api/v1/encyclopedia/{locale}/{slug}.json| Field | Type | Description |
|---|---|---|
| entry | object | Entry copy, role, abilities, and advanced mechanics. |
| portrait | object | AVIF/WebP/PNG portrait and dimensions. |
| navigation | object | Previous/next entry summaries. |
| alternate | object | null | Other-locale entry. |
{
"schemaVersion": 1,
"kind": "encyclopediaEntry",
"locale": "en",
"slug": "peashooter",
"entry": {
"slug": "peashooter",
"kind": "plant",
"name": "Peashooter",
"mechanics": {
"role": "Ranged attacker · Crossbreed base",
"abilities": [
"..."
]
},
"interactions": [
{
"target": "Wall-nut",
"targetSlug": "wall-nut",
"effect": "..."
}
]
},
"portrait": {
"png": {
"path": "/media/encyclopedia/peashooter.png"
},
"width": 1200,
"height": 1185
}
}
curl -fsSL \
-A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
https://pvzvoyage.com/api/v1/encyclopedia/en/peashooter.json
// Server-side fetch example. Browser fetch sends a browser User-Agent automatically.
const response = await fetch("https://pvzvoyage.com/api/v1/encyclopedia/en/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();
/api/v1/world/{locale}/index.json| Field | Type | Description |
|---|---|---|
| regions | array | Region slug, number, title, summary, paragraphs, and visuals. |
| visual | object | Card/hero images and accent colors. |
| alternate | object | Other-locale world index. |
{
"schemaVersion": 1,
"kind": "worldIndex",
"locale": "en",
"count": 4,
"regions": [
{
"slug": "maple-falls",
"number": "I",
"title": "Maple Falls",
"summary": "...",
"path": "/en/world/maple-falls/",
"visual": {
"accent": "#8da66b",
"motif": "wind / lake / stairway"
}
}
]
}
curl -fsSL \
-A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
https://pvzvoyage.com/api/v1/world/en/index.json
// Server-side fetch example. Browser fetch sends a browser User-Agent automatically.
const response = await fetch("https://pvzvoyage.com/api/v1/world/en/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();
/api/v1/did-you-know/{locale}/index.json| Field | Type | Description |
|---|---|---|
| counts | object | Total count and counts by trivia, tip, mechanic, and lore. |
| filters | object | Available contexts, kinds, spoiler levels, and tags. |
| selectionDefaults.homeHero | object | Default homepage selection rules. |
| items | array | Localized items with copy, source refs, tags, weight, and related Field Guide entries. |
| items[].sourceRefs | array | Local sources checked before publication. |
{
"schemaVersion": 1,
"kind": "didYouKnowIndex",
"locale": "en",
"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": "Sunflower matching is no longer directional, and CocoBottle Shine can pass its large-sun charge into the kept plant.",
"spoilerLevel": "mechanics",
"contexts": [
"homeHero",
"encyclopedia",
"api"
],
"relatedEntries": [
{
"slug": "sunflower",
"name": "Sunflower",
"path": "/en/encyclopedia/sunflower/"
}
]
}
]
}
curl -fsSL \
-A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
https://pvzvoyage.com/api/v1/did-you-know/en/index.json
// Server-side fetch example. Browser fetch sends a browser User-Agent automatically.
const response = await fetch("https://pvzvoyage.com/api/v1/did-you-know/en/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();
/api/v1/did-you-know/{locale}/random.json| Field | Type | Description |
|---|---|---|
| context | query | homeHero, encyclopedia, api, or any. |
| kind | query | Comma-separated trivia, tip, mechanic, or lore. |
| entry | query | Related Field Guide slug; preferred by default and required with strictEntry=1. |
| spoilerMax | query | Maximum spoiler level; defaults to mechanics for homeHero and lateGame otherwise. |
| exclude | query | Comma-separated item IDs; the first 20 are honored. |
| selection | object | Seed, pool size, excluded count, and filters actually used. |
| item | object | Selected DidYouKnow item. |
{
"schemaVersion": 1,
"kind": "didYouKnowSelection",
"locale": "en",
"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": "Sunflower matching is no longer directional, and CocoBottle Shine can pass its large-sun charge into the kept plant.",
"cta": {
"path": "/en/encyclopedia/sunflower/",
"url": "https://pvzvoyage.com/en/encyclopedia/sunflower/"
}
}
}
curl -fsSL \
-A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
"https://pvzvoyage.com/api/v1/did-you-know/en/random.json?context=homeHero&entry=sunflower&seed=session-42"
// Server-side fetch example. Browser fetch sends a browser User-Agent automatically.
const response = await fetch("https://pvzvoyage.com/api/v1/did-you-know/en/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();
/api/v1/search/{locale}.json| Field | Type | Description |
|---|---|---|
| documentCount | number | Number of documents. |
| source | object | Source file note for the internal search index. |
| documents | array | Normalized documents. |
| documents[].kind | string | nav, changelog, world, encyclopedia, mechanics, channel, faq, and more. |
{
"schemaVersion": 1,
"kind": "searchIndex",
"locale": "en",
"documentCount": 100,
"documents": [
{
"id": "encyclopedia:en:peashooter",
"kind": "encyclopedia",
"title": "Peashooter",
"subtitle": "Plant file · Owned by default",
"path": "/en/encyclopedia/peashooter/",
"url": "https://pvzvoyage.com/en/encyclopedia/peashooter/",
"aliases": [
"peashooter",
"Peashooter",
"plant"
]
}
]
}
curl -fsSL \
-A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
https://pvzvoyage.com/api/v1/search/en.json
// Server-side fetch example. Browser fetch sends a browser User-Agent automatically.
const response = await fetch("https://pvzvoyage.com/api/v1/search/en.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();
/api/v1/news/{locale}.json| Field | Type | Description |
|---|---|---|
| latestVersion | string | Latest version. |
| links | object | Home, download, changelog, RSS, and release API links. |
| items | array | Announcement items. |
| items[].highlights | array | Structured highlights. |
{
"schemaVersion": 1,
"kind": "newsFeed",
"locale": "en",
"latestVersion": "0.17p",
"items": [
{
"id": "release-0.17p",
"kind": "release",
"version": "0.17p",
"title": "PVZ: Voyage 0.17p released",
"publishedAt": "2026-05-01",
"api": {
"path": "/api/v1/releases/0.17p.json",
"url": "https://pvzvoyage.com/api/v1/releases/0.17p.json"
}
}
]
}
curl -fsSL \
-A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
https://pvzvoyage.com/api/v1/news/en.json
// Server-side fetch example. Browser fetch sends a browser User-Agent automatically.
const response = await fetch("https://pvzvoyage.com/api/v1/news/en.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();
/download/{version}/{platform}| Field | Type | Description |
|---|---|---|
| Content-Type | header | Build MIME type, such as application/zip or the APK MIME type. |
| Content-Disposition | header | Attachment filename. |
| Accept-Ranges | header | Supports bytes. |
| Range | request header | Request a single byte range. |
| Retry-After | header | Returned on 429 responses. |
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
curl -I \
-A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
https://pvzvoyage.com/download/0.17p/windows
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
// 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");
/feed.xml| Field | Type | Description |
|---|---|---|
| channel | RSS | Release channel. |
| item | RSS | Release item. |
| link | RSS | Localized changelog link. |
| pubDate | RSS | Release date. |
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>PVZ: Voyage</title>
<item>
<title>PVZ: Voyage 0.17p released</title>
<link>https://pvzvoyage.com/en/version/0.17p/</link>
</item>
</channel>
</rss>
curl -fsSL \
-A "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)" \
https://pvzvoyage.com/feed.xml
// Server-side fetch example. Browser fetch sends a browser User-Agent automatically.
const response = await fetch("https://pvzvoyage.com/feed.xml", {
headers: {
"User-Agent": "PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/)",
},
});
const xml = await response.text();
Do not hardcode binary paths in clients. Read latest release detail first, then choose a platform from builds. Download routes support HEAD probes, GET downloads, and single-range resumes; verify the result with SHA-256.
Both are generated by the same static build pipeline, but they serve different consumers.
Use News JSON
Structured fields, CTAs, images, tags, and release API links are better for software.
Use RSS
RSS 2.0 is better for feed readers and generic subscription services.
Command-line, script, and server-side clients should send a User-Agent that identifies the integration, for example: PVZVoyage-API-Client/1.0 (+https://pvzvoyage.com/). If you maintain your own client, you may replace the product/version and support URL. Browser fetch uses the browser UA automatically.
JSON API responses are readable cross-origin with Access-Control-Allow-Origin: *.
API JSON uses short browser cache and longer edge cache; binary downloads use immutable versioned-path caching.
Unknown .json API paths return a JSON error object instead of an HTML 404 page. Requests that do not follow the public interface conventions may receive a plain 404 before API handling, and that response is not guaranteed to use the JSON error shape.
/api/v1 is intended to remain stable; additive fields may appear without a schemaVersion bump, while breaking shape changes should use a new schemaVersion or a future /api/v2 path.