App Updates
The app-update endpoints expose the hub's self-update mechanism. The hub uses Velopack under the hood to discover, download and apply releases. The endpoints surface that machinery through a small REST API so integrators can check for new versions, drive the update process from their own UI, and observe the resulting state without restarting the hub themselves until they are ready.
Endpoints Overview
| Method | Endpoint | Description |
|---|---|---|
| GET | /v1/app-updates/info |
Query the current update state (also performs a fresh update check) |
| POST | /v1/app-updates/action |
Drive the update workflow (Check / Download / Apply and Restart) |
Update State
GET /v1/app-updates/info
curl http://localhost:42042/v1/app-updates/info
Performs an update check against the configured release channel and returns the resulting state:
{
"currentVersion": "1.7.0",
"availableVersion": "1.8.0",
"updateAvailable": true,
"updateDownloaded": false,
"pendingRestart": false,
"portable": false,
"installed": true
}
| Field | Type | Description |
|---|---|---|
currentVersion |
string | The running hub version. "###version###" indicates an unbuilt developer copy. |
availableVersion |
string | The newest version offered by the release feed, or "-" if no newer release is available. |
updateAvailable |
bool | true if availableVersion is newer than currentVersion. |
updateDownloaded |
bool | true once Download has finished and the package is staged on disk. |
pendingRestart |
bool | true after ApplyAndRestart has prepared the swap and is waiting for the hub process to exit. |
installed |
bool | true if the hub is running from an installed location (vs. a portable copy). |
portable |
bool | true if the hub is running as a portable distribution. Updates may behave differently in this mode. |
Calling GET /info triggers a fresh check against the release feed, so it is safe to use as the primary refresh entry point — there is no separate "refresh" verb.
Driving the Update Workflow
POST /v1/app-updates/action?action=download
curl -X POST "http://localhost:42042/v1/app-updates/action?action=download"
The action is passed as a query-string parameter. No request body is required.
action value |
Effect | Preconditions |
|---|---|---|
check |
Re-runs the update check, refreshing availableVersion and updateAvailable. |
None. |
download |
Downloads the available release package in the background and stages it on disk. After completion updateDownloaded flips to true. |
An update must be available (check has reported one). |
applyAndRestart |
Applies the downloaded package and restarts the hub process. The client should expect the connection to drop. | updateDownloaded must be true. |
Values are matched case-insensitively against the enum names, so Check, check and CHECK are equivalent.
The response body of POST /action has the same shape as GET /info — call it once and observe the resulting state.
Update Workflow
┌──────────────────────┐
│ GET /info │ Initial state — reports updateAvailable
└──────────┬───────────┘
│ updateAvailable == true
▼
┌──────────────────────┐
│ POST /action "check" │ (optional, refreshes the check)
└──────────┬───────────┘
│
▼
┌──────────────────────────┐
│ POST /action "download" │ Stages the package
└──────────┬───────────────┘
│ updateDownloaded == true
▼
┌──────────────────────────────────┐
│ POST /action "applyAndRestart" │ Hub restarts; connection drops
└──────────────────────────────────┘
Typical client implementation:
- Call
GET /infoat start-up (or on a slow timer) and surface the update banner whenupdateAvailableistrue. - When the user agrees to update,
POST /action "download". Show progress as indeterminate (the API does not currently expose a percentage). - Once
updateDownloadedistrue, prompt the user to apply. On confirmation,POST /action "applyAndRestart"and treat the next failed request as the expected restart signal. - After the hub is back up, call
GET /infoagain.currentVersionshould now match the previousavailableVersionandupdateAvailableshould befalse.
Error Cases
| Condition | HTTP | Body |
|---|---|---|
download / applyAndRestart called before check ever reported an update |
400 | "There is new version available for update. Have you performed the update check first?" |
applyAndRestart called before download finished |
424 | "Update is not downloaded. Please download the update first." |
| Unknown action value | 400 | "Unknown action \"<value>\"." |
The body of these failures is a plain string, not an `ErrorInfo` record, because the responses come from ASP.NET's built-in validation rather than the device error pipeline. Treat any non-2xx response as an indication that the request did not advance the update state.
Best Practices
- Poll
GET /infono more often than once every few minutes. There is no rate-limiting, but the underlying check hits the release feed. - Do not call
applyAndRestartwithout explicit user confirmation — connected devices are disconnected when the hub exits, which can interrupt a running measurement workflow. - Stop all device scans and measurements before applying an update. The hub graceful-shutdown path will handle this, but proactive cleanup avoids surprise errors on the client side.
- Use
portableandinstalledto decide whether to show the update UI at all. A portable copy can be replaced manually; an installed one is the typical update target.