Agent upgrades
Endpoints: /api/servers/servers/{server_id}/agent-upgrades/, /api/servers/agent-upgrades/
Read the record of every agent upgrade: automatic ones started by the workspace’s agent update policy, and manual ones started from the Agent card or with the upgrade_agent action. This is the same record the console shows as upgrade history.
Both endpoints are read-only. They return only servers the caller can see, the same as the server list, and an API token needs the server:read scope. Records begin when upgrade history was introduced; earlier upgrades aren’t included.
One server
List a server’s upgrades
Retrieve one server’s agent upgrades, newest first.
Request
GET /api/servers/servers/{server_id}/agent-upgrades/Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
server_id | UUID | Yes | Server ID |
Query parameters
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
page_size | integer | Results per page (default: 15, max: 100) |
A server the caller can’t see returns 404.
Response
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": "3b1f6f0e-8a52-4c1d-9d6e-5f2a7c9e1b40",
"server": "7e3984de-49ab-4cc6-bcdf-21fbd35858b8",
"server_name": "web-server-01",
"from_version": "1.4.2",
"target_version": "1.5.0",
"to_version": "1.5.0",
"outcome": "success",
"error_class": null,
"detail": null,
"requested_at": "2026-09-21T02:14:05Z",
"acknowledged_at": "2026-09-21T02:14:07Z",
"reported_at": "2026-09-21T02:19:40Z",
"origin": "scheduled",
"policy_mode": "latest",
"initiator": {
"kind": "policy",
"id": null,
"label": "Alpacon automatic policy (latest)"
}
},
{
"id": "a0c4d2b7-19e3-4f56-8b0a-2d7e6c1f9a33",
"server": "7e3984de-49ab-4cc6-bcdf-21fbd35858b8",
"server_name": "web-server-01",
"from_version": "1.4.1",
"target_version": null,
"to_version": "1.4.1",
"outcome": "failed",
"error_class": "download_failed",
"detail": null,
"requested_at": "2026-09-14T09:30:12Z",
"acknowledged_at": "2026-09-14T09:30:13Z",
"reported_at": "2026-09-14T09:31:02Z",
"origin": "manual",
"policy_mode": null,
"initiator": {
"kind": "user",
"id": "a540bf0f-8b37-4f03-8546-dd71c6b03329",
"label": "admin"
}
}
]
}See Fields for what each field means.
Example
curl -X GET "https://your-workspace.us1.alpacon.io/api/servers/servers/7e3984de-49ab-4cc6-bcdf-21fbd35858b8/agent-upgrades/" \
-H "Authorization: token=\"alpat-xxxxxxxxxxxxxxxxxx\""Fields
| Field | Type | Description |
|---|---|---|
id | UUID | Upgrade record ID |
server | UUID | Server ID |
server_name | string | Server name |
from_version | string or null | Agent version before the upgrade |
target_version | string or null | The release the agent was asked to install. null when the agent was sent a plain upgrade to the newest version rather than a specific release |
to_version | string or null | The version the agent ended on; null until it reports back |
outcome | string | pending (in progress), success, rolled_back (the new version didn’t come up cleanly and the agent went back to the previous one), failed, timed_out (the agent didn’t confirm in time), or refused (withdrawn before it reached the agent) |
error_class | string or null | Why the upgrade didn’t land; null when there’s no error |
detail | string or null | A short explanation from Alpacon, for example why an upgrade was refused |
requested_at | date-time | When the upgrade was requested |
acknowledged_at | date-time or null | When the agent received the upgrade |
reported_at | date-time or null | When the agent reported the result |
origin | string | scheduled for an automatic upgrade, manual for one started by a member or a token |
policy_mode | string or null | For an automatic upgrade, the update policy it ran under (latest or n_minus_1); null for a manual one |
initiator | object | Who started the upgrade (see below) |
initiator is a snapshot taken when the upgrade was requested, so it keeps its name after the member or token is gone:
| Field | Type | Description |
|---|---|---|
kind | string | policy for an automatic upgrade, user or token for a manual one |
id | string or null | The user or token ID; null for policy |
label | string | Who started it, by name: the member’s username, the token’s name, or Alpacon automatic policy (latest) ((N-1) under n_minus_1). A request made in Korean gets Alpacon 자동 정책 (latest) |
error_class values, with the label the console shows:
| Value | Console label | Meaning |
|---|---|---|
signature_invalid | Signature invalid | The release’s signature didn’t verify, so the agent didn’t install it |
digest_mismatch | Digest mismatch | The downloaded package didn’t match its published checksum |
download_failed | Download failed | The agent couldn’t download the release |
swap_failed | Swap failed | The agent couldn’t replace its binary with the new one |
health_check_failed | Health check failed | The new version didn’t pass its health check |
package_manager | Package manager error | The system package manager reported an error |
window_closed | Maintenance window closed | The maintenance window closed before the upgrade reached the agent |
keys_unavailable | Alpacon configuration issue; no action needed | A problem on Alpacon’s side; nothing to change on your server, and no alert is raised |
unknown | Unknown error | A failure without a known reason |
A failed or rolled-back upgrade also raises a warning upgrade failure alert on the server, except for keys_unavailable. Each upgrade is recorded in the activity log as well, when it’s sent and when it ends.
Error responses
| Status | Error code | Description |
|---|---|---|
| 401 | — | Invalid or missing authentication. Uncoded {"detail": "..."} response |
| 403 | api_token_scope_missing | The API token doesn’t hold the server:read scope |
| 404 | — | Server not found, or not visible to the caller. Uncoded {"detail": "..."} response |