Multi-Software Multilingual Release Center API
APay provides a unified core releases module (releases table across SQLite, PostgreSQL, and MySQL) to manage software releases, changelogs, and installable packages across multiple products (shoply, qingpu-ai, hoxi-desktop, codex, goray, gopanel, or any custom appKey).
Key capabilities:
- Multi-Software & Release Channels: Isolated by
(app_key, channel, version)with support forstable,beta,rc, andnightlychannels. - 7-Locale Structured Release Notes: Native support for
zh,en,zh-TW,zh-HK,ru,ja, andkowith automatic language fallback (zh-HK -> zh-TW -> zh -> en,other -> en -> zh). Each locale containstitle,summary,body, and structureditems(feat,fix,perf,ui,ops,security,breaking). - Multi-Platform Assets: Each release can attach multiple installable packages (
macos,windows,linux,chrome,container,android,ios) witharch,package,size,sha256, and CDNmirrors. - Bad-Release Withdrawal & Rollback: Marking a release with
withdrawn_atimmediately hides it from public feeds and instructs clients currently running the withdrawn version (isRollbackTarget: true) to roll back to the latest healthy release.
Public Endpoints
1. List Releases (GET /api/releases)
Returns the localized release timeline and latest release for a given software application and channel.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
app / appKey | string | default | Software identifier (e.g., shoply, qingpu-ai, hoxi-desktop, codex, or all) |
channel | string | stable | Release channel (stable, beta, rc, nightly, or all) |
lang / locale | string | zh | Output language (en, zh, zh-TW, zh-HK, ru, ja, ko) |
platform / os | string | - | Optional target OS filter (macos/darwin, windows/win32, linux, chrome, container) |
arch | string | - | Optional CPU architecture filter (arm64, x64, universal) |
package | string | - | Optional package type filter (desktop, extension, container, cli, installer) |
limit | number | 30 | Maximum number of releases returned (1–100) |
Response (200)
{
"code": 0,
"msg": "ok",
"appKey": "shoply",
"channel": "stable",
"lang": "en",
"latest": {
"id": 1,
"appKey": "shoply",
"channel": "stable",
"version": "1.8.0",
"versionCode": 1008000,
"tag_name": "v1.8.0",
"title": "Shoply 1.8.0 Stable",
"summary": "One-click migration and multilingual SEO routing",
"body": "- Added one-click migration\n- Fixed multi-currency rounding",
"items": [
{ "type": "feat", "text": "Added one-click migration" },
{ "type": "fix", "text": "Fixed multi-currency rounding" }
],
"assets": [
{
"name": "ghcr.io/shoply/shoply:1.8.0",
"platform": "container",
"arch": "universal",
"package": "container",
"browser_download_url": "https://downloads.shoply.example/shoply-1.8.0.tar.gz",
"size": 104857600,
"sha256": "..."
}
],
"mandatory": false,
"releasedAt": "2026-10-20T00:00:00.000Z"
},
"releases": []
}
2. Check Client Upgrade (GET /api/releases/check)
Evaluates whether a client running currentVersion on a specific (platform, arch, package) needs an update or rollback. Automatically skips releases that have been withdrawn or do not provide an asset for the client's platform.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
app / appKey | string | No (default) | Target software identifier |
channel | string | No (stable) | Release channel |
currentVersion / version | string | No | Client's currently installed SemVer (e.g., 1.2.0) |
platform / os | string | No | Client OS (darwin/macos, win32/windows, linux, chrome, container) |
arch | string | No | Client CPU architecture (arm64, x64, universal) |
package | string | No | Package format (desktop, extension, container, cli) |
lang | string | No (zh) | Language code for localized release notes |
format | string | No | Optional output format: tauri (Tauri Updater JSON manifest, returns 204 when no update is available) or appcast / xml (Sparkle 2.x RSS feed) |
Response (200)
{
"code": 0,
"msg": "ok",
"data": {
"appKey": "qingpu-ai",
"channel": "stable",
"lang": "en",
"currentVersion": "1.2.0",
"currentVersionCode": 1002000,
"needUpdate": true,
"hasUpdate": true,
"isRollbackTarget": false,
"mandatory": false,
"latestVersion": "1.3.0",
"latestVersionCode": 1003000,
"downloadUrl": "https://cdn.qingpu.example/Qingpu-1.3.0-arm64.dmg",
"sha256": "...",
"size": 94371840,
"appcastUrl": "/api/releases/appcast.xml?app=qingpu-ai&channel=stable&lang=en",
"asset": {
"name": "Qingpu-1.3.0-arm64.dmg",
"platform": "macos",
"arch": "arm64",
"package": "desktop",
"browser_download_url": "https://cdn.qingpu.example/Qingpu-1.3.0-arm64.dmg",
"size": 94371840
},
"release": {
"version": "1.3.0",
"title": "Qingpu 1.3.0",
"summary": "macOS performance optimization"
}
}
}
3. Sparkle 2.x / WinSparkle Appcast Feed (GET /api/releases/appcast.xml)
Generates a standard RSS 2.0 XML feed with xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" for native macOS (Sparkle 2) and Windows (WinSparkle / NetSparkle) auto-updaters. Also accessible at /api/releases/appcast.
- Supports
?app=<appKey>&channel=stable&lang=zh&platform=macos&arch=arm64&limit=20. - Renders localized
summaryanditemsinto clean HTML inside<description><![CDATA[...]]></description>. - Maps
versionCodeto<sparkle:version>, SemVerversionto<sparkle:shortVersionString>,mandatory/minUpgradeVersionto<sparkle:criticalUpdate />, and assetsignature/edSignaturetosparkle:edSignature="...". - Automatically excludes withdrawn (
withdrawn_at) or draft releases.
4. Tauri v1 / v2 Auto-Updater Manifest (GET /api/releases/check?format=tauri)
Returns the standard Tauri dynamic updater JSON manifest ({ version, notes, pub_date, platforms }) with automatic mapping of APay (platform, arch) assets onto darwin-aarch64, darwin-x86_64, windows-x86_64, linux-x86_64, etc. When version (currentVersion) is supplied and already up to date, returns HTTP 204 No Content.
CI / AI Agent & Admin Endpoints
1. Publish / Upsert Release via APAY_RELEASE_KEY (POST /api/releases & POST /api/releases/publish)
Protected by the APAY_RELEASE_KEY environment variable via Authorization: Bearer <APAY_RELEASE_KEY> or x-release-key: <APAY_RELEASE_KEY>.
- Publish / Upsert Release: Pass
appKey,appName,channel,version,locales,assets,mandatory,minUpgradeVersion,isActive,releasedAt, ordryRun: true. Every published or updated release is recorded in the operation audit log (operation_logs). - Administrative actions (
save_app,delete_app,withdraw,restore,seed_bundled) are unified under/api/admin/releases(which also acceptsAuthorization: Bearer <APAY_RELEASE_KEY>).
2. Admin Console Endpoints (/api/admin/releases)
All /api/admin/releases/** endpoints accept either an administrator session / token (releases permission module) or Authorization: Bearer <APAY_RELEASE_KEY>.
GET /api/admin/releases: Lists releases with filtering byappKey,channel,status(all/published/withdrawn/draft), andkeyword, plus per-software summary cards (data.apps).POST /api/admin/releases:- Publishes or upserts a release record (
appKey,channel,version,locales,assets,mandatory,minUpgradeVersion,isActive,releasedAt). - Supports
{ "action": "seed_bundled", "appKey": "all" }to import bundled JSON release histories into the database idempotently.
- Publishes or upserts a release record (
PUT /api/admin/releases/:id: Updates an existing release's metadata, multilinguallocales, or multi-platformassets.PATCH /api/admin/releases/:id/status: Toggles release state (status: 'published' | 'withdrawn' | 'draft'or{ isActive, withdrawn }).DELETE /api/admin/releases/:id: Permanently deletes a release record.