Updates
AppsXi hosts your update feed. Each approved build appears in it within five minutes, and nothing reaches installed copies without passing the pipeline first.
Feed URLs
https://appsxi.com/updates/<slug>/<macos|windows>/<stable|beta>/appcast.xml Sparkle 2, WinSparkle
https://appsxi.com/updates/<slug>/<macos|windows>/<stable|beta>/latest-mac.yml electron-updater (Mac)
https://appsxi.com/updates/<slug>/windows/<stable|beta>/latest.yml electron-updater (Windows)
https://appsxi.com/updates/<slug>/windows/<stable|beta>/<name>.appinstaller MSIX App InstallerThe beta feed includes stable releases, so beta users always get the newest build.
Sparkle (macOS)
In Info.plist:
<key>SUFeedURL</key>
<string>https://appsxi.com/updates/my-app/macos/stable/appcast.xml</string>
<key>SUPublicEDKey</key>
<string>your-base64-public-key</string>Sign each release with your own EdDSA key, after notarizing and stapling, and send the signature with the build:
npx appxi publish MyApp.dmg --app my-app --sparkle-sign /path/to/sign_update
# or: --ed-signature "<the sparkle:edSignature value from sign_update>"AppsXi verifies the signature against the SUPublicEDKey inside the app before approving. Sparkle compares CFBundleVersion, so raise it with every release.
WinSparkle
Call win_sparkle_set_appcast_url with the windows appcast URL.
electron-updater
# electron-builder.yml
publish:
provider: generic
url: https://appsxi.com/updates/my-app/${os}/stableUse mac → macos and win → windows in the path (set the URL per platform if your config cannot map it). AppsXi serves latest-mac.yml and latest.yml with SHA-512 hashes of the exact files it checked.
MSIX
AppsXi serves an .appinstaller file for .msix builds. Install from it and Windows checks for updates on launch.
Paid apps
Feeds for paid Level 1 apps need a license-bound token. The license validation response includes it:
"updates": { "feed_token": "axf_…", "feed_base": "https://appsxi.com/updates/my-app", "appcast_url": "…/macos/stable/appcast.xml?token=axf_…" }Set the feed URL at runtime (Sparkle: feedURLString(for:) in your updater delegate; electron-updater: autoUpdater.setFeedURL with requestHeaders: { Authorization: "Bearer axf_…" }). A refund revokes the token. Level 0 paid apps update from the buyer's AppsXi library.
Rollback
Developer → your app → Update feeds → Roll back withdraws the current build for that platform and channel. The previous approved build is served again within five minutes. Copies that already updated stay on the withdrawn version until the next release, which must have a higher version number.
Staged rollouts
Once an app has 1,000 installs, each approved update reaches a few copies first and everyone later. By default that is 1% of copies for a day, then 10% for a day, then everyone. A bad release then reaches few people, and you have time to pause it or roll back.
- Copies are chosen by their license feed token (paid apps), their AppsXi Desktop session, or their network address on public feeds. The same copy stays in or out for the whole rollout.
- Developer → your app → Staged rollouts sets the steps: each is a share of copies (1 to 99%, rising) and how long it lasts (1 hour, 6 hours, 1 day, 3 days, 1 week or 1 month), up to five steps, then everyone. A copy that has the update keeps it at the next step. Changes apply to the next approved update.
- The same section chooses when to stage: Automatic (1,000 installs or more), Always, or Never. Use Never only if you have to ship fixes to everyone at once.
- Developer → your app → Update feeds shows a running rollout, its step and when the next one starts, with Pause (stay at the current step until you decide; paused time does not count), Resume and Release to everyone. Roll back works as usual and ends the rollout.
- AppsXi can pause a rollout while it investigates a report.
Caching
Public feeds are cached for up to five minutes in total. Token feeds are cached privately for one minute. During a staged rollout feeds are not cached, so each copy gets its own answer.