Developer / APIDesktop Release API

Desktop Release API

The HummyTummy Desktop app’s installers and updates are served from a server-side release catalog (DesktopRelease). The catalog is a single platform-level global list — every restaurant tenant sees the same published releases. A few endpoints are publicly accessible (download, update query, latest release); publishing a release is restricted to platform operators (SuperAdmin) or CI/CD.

All endpoints are served under the global /api prefix. The examples below use https://app.hummytummy.com as the server root; substitute your own. See API Fundamentals for the cross-cutting conventions (error envelope, rate-limit tiers, status codes).

Public endpoints

These endpoints require no authentication (@Public) and are rate-limited (throttled).

Method & pathDescriptionLimit
GET /api/desktop/releases/latestLatest published release30/min
GET /api/desktop/releases/publishedAll published releases (newest pubDate first)30/min
GET /api/desktop/updates/:platform/:currentVersionTauri updater query60/min
POST /api/desktop/releases/:version/download/:platformIncrement the download counter (analytics)10/min
⚠️

Path parameters are validated: :platform must match ^[a-z0-9-]{1,32}$, and :version / :currentVersion must match ^v?\d+\.\d+\.\d+$. A non-matching value returns 400 Bad Request.

Only releases with published: true are visible through the public endpoints. Draft (unpublished) releases are listed only via the SuperAdmin management endpoints.

Get the latest release

GET /api/desktop/releases/latest returns the single newest published release record. If there is no published release it returns 404.

curl https://app.hummytummy.com/api/desktop/releases/latest

Per-platform package fields

A client picks the URL field that matches the platform it runs on:

PlatformURL fieldSignature fieldTypical artifact
WindowswindowsUrlwindowsSignature.msi
macOS (Apple Silicon)macArmUrlmacArmSignature.dmg
macOS (Intel)macIntelUrlmacIntelSignature.dmg
LinuxlinuxUrllinuxSignature.deb / .AppImage

If the URL for a given platform is null, that release was not built for that platform.

GET /api/desktop/releases/published returns the same record shape as an array, sorted by pubDate descending (newest first).

The updater endpoint

GET /api/desktop/updates/:platform/:currentVersion

The desktop app uses the Tauri updater to fetch new versions on its own. The flow is fully server-controlled: the app reports the platform it runs on and its current version, and the server returns a signed update manifest if an upgradable release exists.

ParameterDescriptionExample
:platformThe platform key Tauri reportswindows-x86_64
:currentVersionThe app’s current version0.2.5 or v0.2.5

Valid platform keys: windows-x86_64, darwin-aarch64, darwin-x86_64, linux-x86_64. This endpoint is public and rate-limited to 60 requests/min.

Responses

  • Update available200 with the manifest below.
  • No update / not applicable → the body is null. Tauri treats this as “up to date”. null is returned when:
    • the current version equals or is newer than the latest published release,
    • there is no published release,
    • the requested platform is not present in the latest release (no URL, or unsigned).
curl https://app.hummytummy.com/api/desktop/updates/windows-x86_64/0.2.5

The platforms object only includes platforms that have both a URL and a valid signature (see the security note below). The notes field is the release’s releaseNotes text, and pub_date is the publication date in ISO format.

Version comparison

The server compares versions as numeric semver: it splits the major.minor.patch parts, strips a leading v prefix, and compares numerically. An update is offered only when the latest published version is strictly greater than the supplied currentVersion; if equal or lower, it returns null.

⚠️

The comparison considers numeric parts only; pre-release tags (such as 1.0.0-beta.1) are not supported. Since the release catalog is operator/CI-controlled, this is sufficient — published versions are always kept in plain major.minor.patch form.

Signature verification (security)

The Tauri updater installs a binary only if its minisign signature verifies against a pinned public key. The server behaves to preserve that contract:

  • If a platform has a URL but no signature (empty/missing), that platform is not added to the manifest — it is treated as not-installable and a warning is logged on the server. A half-populated, unsigned entry is never emitted.
  • If a platform has no URL (the release was not built for that platform), it is silently skipped.
  • If the requested platform ends up absent from platforms, the endpoint returns null.

This guarantees the auto-updater never receives an unsigned (and therefore unverifiable) binary.

Which endpoint and which public key the updater uses are defined in the desktop app’s Tauri configuration (the updater block in tauri.conf.json). The server contract above (manifest format, mandatory signature, version comparison) holds regardless of that client configuration.

Download counter

POST /api/desktop/releases/:version/download/:platform

Increments the per-release download counter for analytics.

curl -X POST https://app.hummytummy.com/api/desktop/releases/0.2.6/download/windows-x86_64

This call is best-effort: if an unknown version is supplied it does not throw, it is just logged on the server.

Publishing a release (operator / CI)

A new release reaches the catalog through one of two routes.

⚠️

The release catalog is a platform-level global list, and every restaurant’s desktop updater pulls from it. For that reason the management endpoints (create / publish / delete) are accessible only with SuperAdmin or the CI API key; tenant admins cannot modify the catalog. Otherwise a single tenant could swap the binary that every restaurant’s updater fetches.

Auth realms

RealmHeaderUsed by
CI API keyx-api-key (or api-key): DESKTOP_RELEASE_API_KEYGitHub Actions / CI-driven publishing
SuperAdmin (Bearer)Authorization: Bearer <jwt>Platform operators

Management endpoints

Method & pathRealmDescription
POST /api/desktop/ci/releasesCI API keyCreate a release (CI)
POST /api/desktop/ci/releases/:id/publishCI API keyPublish a release (CI)
POST /api/desktop/releasesSuperAdminCreate a release
PATCH /api/desktop/releases/:idSuperAdminUpdate a release
POST /api/desktop/releases/:id/publishSuperAdminPublish a release
POST /api/desktop/releases/:id/unpublishSuperAdminUnpublish a release
DELETE /api/desktop/releases/:idSuperAdminDelete a release

Example — create a release via CI

curl -X POST https://app.hummytummy.com/api/desktop/ci/releases \
  -H "x-api-key: $DESKTOP_RELEASE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "version": "0.2.7",
    "releaseTag": "v0.2.7",
    "releaseNotes": "## What'\''s New\n- ...",
    "windowsUrl": "https://github.com/.../setup.msi",
    "windowsSignature": "dW50cnVzdGVkIGNvbW1lbnQ6...",
    "published": false
  }'
⚠️

version must be unique and in \d+\.\d+\.\d+ form (plain semver, no v prefix). Re-creating an existing version returns 400. The publish step sets pubDate; the updater’s “latest release” ordering is based on that field.

Building from source

To build the desktop app from source (the Tauri CLI ships with npm):

Install dependencies and build

npm install
npm run tauri:dev    # run in development mode
npm run tauri:build  # produce a production bundle

Collect the bundles

Output bundles are created under src-tauri/target/release/bundle/ per platform (msi/, dmg/, deb/, appimage/).

Development requires Rust 1.70+ and Node.js 18+; on Linux you also need libdbus-1-dev and pkg-config (for Bluetooth printer support).

Operator screens

End users do not call these endpoints directly — the desktop app does. Operators install and update the app through the in-app experience: