# App Updates > [!note] Diese Seite ist noch nicht auf Deutsch verfügbar und wird auf Englisch angezeigt. The app-update endpoints expose the hub's self-update mechanism. The hub uses [Velopack](https://velopack.io/) 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 ```http GET /v1/app-updates/info ``` ```bash curl http://localhost:42042/v1/app-updates/info ``` Performs an update check against the configured release channel and returns the resulting state: ```json { "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 ```http POST /v1/app-updates/action?action=download ``` ```bash 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: 1. Call `GET /info` at start-up (or on a slow timer) and surface the update banner when `updateAvailable` is `true`. 2. When the user agrees to update, `POST /action "download"`. Show progress as indeterminate (the API does not currently expose a percentage). 3. Once `updateDownloaded` is `true`, prompt the user to apply. On confirmation, `POST /action "applyAndRestart"` and treat the next failed request as the expected restart signal. 4. After the hub is back up, call `GET /info` again. `currentVersion` should now match the previous `availableVersion` and `updateAvailable` should be `false`. ### 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 \"\"."` | The body of these failures is a plain string, not an [`ErrorInfo`](rhopoint-elements-hub-error-handling.md) 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 /info` no more often than once every few minutes. There is no rate-limiting, but the underlying check hits the release feed. - Do not call `applyAndRestart` without 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 `portable` and `installed` to decide whether to show the update UI at all. A portable copy can be replaced manually; an installed one is the typical update target.