---
title: "Multi-Software Multilingual Release Center"
canonical_url: "https://ainode.run/docs/software-releases"
type: "doc"
locale: "en"
description: "Core API endpoints for multi-software release management, 7-locale structured changelogs, multi-platform package matching, and withdrawal rollback."
---

# Multi-Software Multilingual Release Center
> Core API endpoints for multi-software release management, 7-locale structured changelogs, multi-platform package matching, and withdrawal rollback.

# 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 for `stable`, `beta`, `rc`, and `nightly` channels.
- **7-Locale Structured Release Notes**: Native support for `zh`, `en`, `zh-TW`, `zh-HK`, `ru`, `ja`, and `ko` with automatic language fallback (`zh-HK -> zh-TW -> zh -> en`, `other -> en -> zh`). Each locale contains `title`, `summary`, `body`, and structured `items` (`feat`, `fix`, `perf`, `ui`, `ops`, `security`, `breaking`).
- **Multi-Platform Assets**: Each release can attach multiple installable packages (`macos`, `windows`, `linux`, `chrome`, `container`, `android`, `ios`) with `arch`, `package`, `size`, `sha256`, and CDN `mirrors`.
- **Bad-Release Withdrawal & Rollback**: Marking a release with `withdrawn_at` immediately 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)

```json
{
  "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)

```json
{
  "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=&channel=stable&lang=zh&platform=macos&arch=arm64&limit=20`.
- Renders localized `summary` and `items` into clean HTML inside ``.
- Maps `versionCode` to ``, SemVer `version` to ``, `mandatory` / `minUpgradeVersion` to ``, and asset `signature` / `edSignature` to `sparkle: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 ` or `x-release-key: `.

- **Publish / Upsert Release**: Pass `appKey`, `appName`, `channel`, `version`, `locales`, `assets`, `mandatory`, `minUpgradeVersion`, `isActive`, `releasedAt`, or `dryRun: 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 accepts `Authorization: Bearer `).

### 2. Admin Console Endpoints (`/api/admin/releases`)

All `/api/admin/releases/**` endpoints accept either an administrator session / token (`releases` permission module) or `Authorization: Bearer `.

- **`GET /api/admin/releases`**: Lists releases with filtering by `appKey`, `channel`, `status` (`all` / `published` / `withdrawn` / `draft`), and `keyword`, 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.
- **`PUT /api/admin/releases/:id`**: Updates an existing release's metadata, multilingual `locales`, or multi-platform `assets`.
- **`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.
