Skip to content

Node

Location

Node

Region


List All Nodes

GET /api/admin/locations/{location_id}/regions/{region_id}/nodes

Schema
  • nodes: Array
    • id: String
    • label: String
    • hostname: String
    • primary_ip: String
    • disconnected: Boolean
    • failed_health_checks: Integer
    • active: Boolean
    • online_at: DateTime
    • disconnected_at: DateTime
    • public_ip: String
    • region_id: Integer
    • maintenance: Boolean - effective maintenance: the controller's hold OR the node's own
    • maintenance_updated: DateTime - when the controller hold last changed
    • maintenance_status: Object - read from stored state; never calls the agent
      • effective: Boolean - same as maintenance
      • requested: Boolean - the controller hold
      • reason: String - reason given with the controller hold (internal; never shown to customers)
      • requested_at: DateTime | null
      • gen: Integer - generation of the controller hold
      • holds: Object - as the agent last reported them (since in unix seconds)
        • controller: Object | null - since, reason, gen
        • local: Object | null - since, reason, by (placed with cs-agent maintenance on)
      • paused_since: DateTime | null
      • skipped_backups: Integer - backups skipped during the maintenance window
      • sample: Object | null - quiesce (quiesced, busy or unknown), running_count, pending, sampled_at (unix seconds)
      • agent: Object - supported (Boolean, cs-agent 3.4 or later), observed_at, instance_id
      • running: Array - work running on the node at the last status check (id, kind, volume, started_at)
      • pending: Integer
      • warnings: Array - see Maintenance Warnings
    • job_status: String
    • ssh_port: Integer
    • volume_device: String
    • block_write_bps: Integer
    • block_read_bps: Integer
    • customer_notice: String | null - message shown to customers while the node is not online
    • customer_status: Object - what customers see for this node; the same object as node_status on the User API (state, since, planned, message, operations)
    • created_at: DateTime
    • updated_at: DateTime

View Node

GET /api/admin/locations/{location_id}/regions/{region_id}/nodes/{id}

Schema
  • node: Object
    • id: String
    • label: String
    • hostname: String
    • primary_ip: String
    • disconnected: Boolean
    • failed_health_checks: Integer
    • active: Boolean
    • online_at: DateTime
    • disconnected_at: DateTime
    • public_ip: String
    • region_id: Integer
    • maintenance: Boolean - effective maintenance: the controller's hold OR the node's own
    • maintenance_updated: DateTime - when the controller hold last changed
    • maintenance_status: Object - read from stored state; never calls the agent
      • effective: Boolean - same as maintenance
      • requested: Boolean - the controller hold
      • reason: String - reason given with the controller hold (internal; never shown to customers)
      • requested_at: DateTime | null
      • gen: Integer - generation of the controller hold
      • holds: Object - as the agent last reported them (since in unix seconds)
        • controller: Object | null - since, reason, gen
        • local: Object | null - since, reason, by (placed with cs-agent maintenance on)
      • paused_since: DateTime | null
      • skipped_backups: Integer - backups skipped during the maintenance window
      • sample: Object | null - quiesce (quiesced, busy or unknown), running_count, pending, sampled_at (unix seconds)
      • agent: Object - supported (Boolean, cs-agent 3.4 or later), observed_at, instance_id
      • running: Array - work running on the node at the last status check (id, kind, volume, started_at)
      • pending: Integer
      • warnings: Array - see Maintenance Warnings
    • job_status: String
    • ssh_port: Integer
    • volume_device: String
    • block_write_bps: Integer
    • block_read_bps: Integer
    • customer_notice: String | null - message shown to customers while the node is not online
    • customer_status: Object - what customers see for this node; the same object as node_status on the User API (state, since, planned, message, operations)
    • created_at: DateTime
    • updated_at: DateTime

Update Node

PATCH /api/admin/locations/{location_id}/regions/{region_id}/nodes/{id}

Note: We currently do not allow changing the hostname of an existing node.

Schema
  • node: Object
    • label: String
    • primary_ip: String
    • active: Boolean
    • public_ip: String
    • region_id: Integer
    • ssh_port: Integer
    • volume_device: String
    • block_write_bps: Integer
    • block_read_bps: Integer
    • customer_notice: String (optional) - message to customers with something on this node, shown in the portal and as node_status.message on the User API. Plain text. Can only be set while the node is in maintenance or offline (422 otherwise). Blank clears it, and it clears itself when the node is back online. Applied before the other fields, and audited.

Create Node

POST /api/admin/locations/{location_id}/regions/{region_id}/nodes

Schema
  • node: Object
    • label: String
    • hostname: String
    • primary_ip: String
    • active: Boolean
    • public_ip: String
    • region_id: Integer
    • ssh_port: Integer
    • volume_device: String
    • block_write_bps: Integer
    • block_read_bps: Integer

Delete Node

DELETE /api/admin/locations/{location_id}/regions/{region_id}/nodes/{id}


Maintenance Mode

A node is in maintenance (maintenance is true) while either of two holds is present:

  • the controller hold, placed and released with the endpoints below (or from the admin UI);
  • the node (local) hold, placed on the node itself with cs-agent maintenance on and released with cs-agent maintenance off.

A node in maintenance takes no new containers, the controller stops recovering its containers, and its agent (cs-agent 3.4 or later) pauses backups and other background work. Containers are not moved. Nodes running an older agent behave as before: the controller hold is not enforced on the node.

Every change to the controller hold is audited.

Request Maintenance

POST /api/admin/locations/{location_id}/regions/{region_id}/nodes/{node_id}/maintenance

Places the controller hold. Returns HTTP 202 Accepted; the hold is delivered to the node asynchronously. Repeating the request is safe: it does not bump the generation, and it re-sends the hold to the node.

If customer_message is given, it is set as the node's customer_notice once the hold is placed (see Update Node). Omit it to leave any existing notice as it is. If the notice can't be set, the request returns HTTP 422 with errors, though the hold has already been placed.

Schema

Request

  • reason: String (optional) - internal; never shown to customers
  • customer_message: String (optional) - message to customers with something on this node

Response

  • maintenance: Boolean - effective maintenance (controller OR node hold)
  • maintenance_requested: Boolean - the controller hold
  • maintenance_gen: Integer
  • maintenance_status: Object - as on the node (see View Node)
Example
{
  "maintenance": true,
  "maintenance_requested": true,
  "maintenance_gen": 4,
  "maintenance_status": {
    "effective": true,
    "requested": true,
    "reason": "kernel 6.12",
    "requested_at": "2026-10-08T12:00:00.000Z",
    "gen": 4,
    "holds": {
      "controller": { "since": 1791460805, "reason": "kernel 6.12", "gen": 4 },
      "local": null
    },
    "paused_since": "2026-10-08T12:00:05.000Z",
    "skipped_backups": 0,
    "sample": { "quiesce": "quiesced", "running_count": 0, "pending": 0, "sampled_at": 1791460810 },
    "agent": { "supported": true, "observed_at": "2026-10-08T12:02:00Z", "instance_id": "4f1c9e2a" },
    "running": [],
    "pending": 0,
    "warnings": []
  }
}

Release Maintenance

DELETE /api/admin/locations/{location_id}/regions/{region_id}/nodes/{node_id}/maintenance

Releases the controller hold only. A node that holds itself in maintenance stays in maintenance (maintenance remains true); see Release All Holds.

Returns HTTP 202 Accepted, with the same body as Request Maintenance.

Note

Older clients sent DELETE .../nodes/{node_id}/maintenance/{id}. That form is still accepted, and the trailing id is ignored.

Release All Holds

POST /api/admin/locations/{location_id}/regions/{region_id}/nodes/{node_id}/maintenance/release_all

Releases the controller hold and the node's own hold. Use it for a node that was left in maintenance by someone who is no longer around; whoever placed the local hold is not asked. The override is audited and raises a warning-level system event.

Returns HTTP 202 Accepted, with the same body as Request Maintenance. The node leaves maintenance once its agent applies the override; until then maintenance_status.warnings includes override_pending. A local hold placed after the override (for example, by an upgrade playbook that started while the override was still waiting to reach the agent) is left alone.

Returns HTTP 422 without confirm=true.

Schema
  • confirm: Boolean - must be true

Maintenance Warnings

maintenance_status.warnings contains any of:

Warning Meaning
mismatch The agent's copy of the controller hold still disagrees with the controller after a correction attempt.
stale_hold A hold has been in place for more than 12 hours.
unsupported_agent The controller hold is requested, but the agent is older than 3.4 (or has no token), so the node doesn't enforce it.
status_stale No status has been read from the agent in the last 10 minutes.
override_pending A Release All Holds override hasn't reached the agent yet.