Reference
View as MarkdownServers API
Servers and agents.
37 operations. Every call needs a session cookie or an Authorization: Bearer nct_… token unless marked Public. Conventions, errors and scopes
/geo/maxmindWhether the team has a MaxMind GeoLite2 account on file
The licence key is write-only. serversUsing counts the team's servers that currently use the MaxMind source.
Response 200 · OK · application/json
- accountIdstringrequiredMaxMind account ID; empty when none is stored
- configuredbooleanrequired
- serversUsinginteger (int64)required
- updatedAtstring (date-time) | nullrequired
401Unauthorized403Forbidden500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/geo/maxmindStore the team's MaxMind account ID and licence key
The key is sealed with the instance secret key. Servers on the MaxMind source receive it with their next reconcile (sent immediately to online agents, never persisted in a command).
Request body · application/json · required
- accountIdstringrequiredNumeric MaxMind account ID
- licenseKeystringrequiredMaxMind licence key; stored encrypted, never returned
Response 200 · OK · application/json
- accountIdstringrequiredMaxMind account ID; empty when none is stored
- configuredbooleanrequired
- serversUsinginteger (int64)required
- updatedAtstring (date-time) | nullrequired
401Unauthorized403Forbidden422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/geo/maxmindRemove the team's MaxMind account
Refused with 409 maxmind_in_use while a server still uses the MaxMind source.
Response 200 · OK · application/json
- accountIdstringrequiredMaxMind account ID; empty when none is stored
- configuredbooleanrequired
- serversUsinginteger (int64)required
- updatedAtstring (date-time) | nullrequired
401Unauthorized403Forbidden409Conflictmaxmind_in_use422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/instance/upgradeControl-plane version, agent version skew per server and the pre-upgrade backup
The version the control plane runs, whether agents behind it upgrade themselves when they connect, the outcome of the backup the control plane took before its last upgrade, and for every server how its agent's version compares (behind, current, ahead, unknown), whether it can be upgraded now (and if not, why) and the state of its latest upgrade.
Response 200 · OK · application/json
- agentAutoUpgradebooleanrequiredUpgrade an agent that is behind the control plane as soon as it connects. Default on.
- behindinteger (int64)requiredServers whose agent is behind the control plane.
- controlPlaneVersionstringrequired
- PreUpgradeBackupView
- ServerUpgradeView[] | nullrequired
- upgradableinteger (int64)requiredServers whose agent can be upgraded now.
401Unauthorized403Forbidden404Not Found500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/instance/upgradeSwitch the automatic agent upgrade
Needs the servers:write scope and the instance admin (the first account). Audited.
Request body · application/json · required
- agentAutoUpgradebooleanUpgrade an agent that is behind the control plane when it connects.
Response 200 · OK · application/json
- agentAutoUpgradebooleanrequiredUpgrade an agent that is behind the control plane as soon as it connects. Default on.
- behindinteger (int64)requiredServers whose agent is behind the control plane.
- controlPlaneVersionstringrequired
- PreUpgradeBackupView
- ServerUpgradeView[] | nullrequired
- upgradableinteger (int64)requiredServers whose agent can be upgraded now.
401Unauthorized403Forbidden404Not Found422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/serversList servers
| Parameter | In | Type | Description |
|---|---|---|---|
cursor | query | string | Opaque cursor from a previous page's nextCursor |
limit | query | integer (int64) | Page size (default 50, max 200) |
Response 200 · OK · application/json
- Server[] | nullrequired
- nextCursorstringPresent when more items exist
401Unauthorized403Forbidden422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}Get a server
| Parameter | In | Type | Description |
|---|---|---|---|
serverIdrequired | path | string |
Response 200 · OK · application/json
- acceptWorkloadsbooleanrequiredWhether services may be scheduled on this server. Turning it off keeps what already runs here and refuses new placements and moves.
- acmeEmailstring | nullrequired
- agentVersionstring | nullrequired
- baseDomainstring | nullrequired
- buildAllowEmulationbooleanrequiredAllow building for another CPU architecture through emulation (slow); needs the agent to report emulation for the platform
- buildAllowPreviewsbooleanrequiredAllow pull request previews (untrusted code) to build here; off by default
- buildEnabledbooleanrequiredThe server builds images for other servers and pushes them to a registry (the Builds or Both role). Independent of acceptWorkloads.
- buildMaxConcurrentinteger (int64)requiredBuilds that run at the same time; more queue on the control plane
- composeVersionstringrequiredDocker Compose plugin version the agent reported, empty when it has none
- controlPlanebooleanrequiredThe host the installer put the control plane on; its proxy serves the dashboard
- createdAtstring (date-time)required
- diskAlertbooleanrequiredTrue while the root filesystem is at or above the threshold
- diskAlertThresholdPercentinteger (int64)requiredRoot filesystem usage that raises the disk alert (50-99)
- drainMessagestringrequiredWhy the last drain failed or was canceled, empty otherwise
- drainStartedAtstring (date-time) | nullrequired
- drainStateenum: none | draining | drained | failedrequiredEvacuation state; draining and drained servers accept no new services
- Factsrequired
- geoEnabledbooleanrequiredCount where requests come from (country, and city at the city level) from the client IP; IPs are never stored
- geoLevelenum: country | cityrequiredcountry needs a ~8 MB database on the server, city ~130 MB
- geoRefreshDaysinteger (int64)requiredCheck for a newer database every N days (1-90)
- geoSourceenum: dbip | maxmindrequireddbip = DB-IP Lite (CC BY 4.0, no key); maxmind = MaxMind GeoLite2 with the team's account
- idstringrequired
- lastSeenAtstring (date-time) | nullrequired
- Latestrequired
- metricsRetentionDaysinteger (int64)requiredHow long resource metric history is kept (1-90)
- namestringrequired
- ServerPatchSummaryrequired
- protocolVersioninteger (int32) | nullrequired
- Proxyrequired
- publicIpstring | nullrequired
- serviceCountinteger (int64)required
- statusenum: pending | online | offline | revokedrequired
- trafficAnalyticsEnabledbooleanrequiredAggregate Traefik access logs into traffic analytics
- trafficDailyRetentionDaysinteger (int64)requiredDaily traffic history (7-365 days)
- trafficHourlyRetentionDaysinteger (int64)requiredHourly traffic history (2-90 days)
- ServerTunnelSummaryrequired
- unrestrictedbooleanrequiredAn instance admin made this server unrestricted: stacks and services on it may use privileged mode, host networking, devices, GPUs, a runtime, the host PID namespace, unconfined seccomp or AppArmor, NET_ADMIN, SYS_ADMIN, the Docker socket and host bind mounts
401Unauthorized403Forbidden404Not Found422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}Update a server's name, host settings, retention or alert settings
| Parameter | In | Type | Description |
|---|---|---|---|
serverIdrequired | path | string |
Request body · application/json · required
- acceptWorkloadsbooleanfalse stops new services being scheduled on this server (what already runs here keeps running); default true
- acmeEmailstringEmpty string clears
- baseDomainstringEmpty string clears
- buildAllowEmulationbooleanAllow cross-architecture builds through emulation (default off)
- buildAllowPreviewsbooleanLet pull request previews build on this server (default off: previews build on their own server)
- buildEnabledbooleanMake the server a build server: it builds git sources for other servers and pushes the images to a registry. Combine with acceptWorkloads: Deployments (true/false), Builds (false/true) or Both (true/true).
- buildMaxConcurrentinteger (int64)Parallel builds on this server (default 2); more queue on the control plane
- diskAlertThresholdPercentinteger (int64)Disk usage percent that raises the disk alert (default 80)
- geoEnabledbooleanCount where requests come from (default on); needs traffic analytics
- geoLevelenum: country | citycountry (default, ~8 MB database) or city (~130 MB)
- geoRefreshDaysinteger (int64)Check for a newer database every N days (default 7)
- geoSourceenum: dbip | maxminddbip = DB-IP Lite (default, no key); maxmind = MaxMind GeoLite2 (needs the team's account, see PUT /geo/maxmind)
- metricsRetentionDaysinteger (int64)Days of resource metric history (default 7)
- namestring
- publicIpstringEmpty string clears
- trafficAnalyticsEnabledbooleanTurns Traefik access-log analytics on or off (default on)
- trafficDailyRetentionDaysinteger (int64)Days of daily traffic history (default 90)
- trafficHourlyRetentionDaysinteger (int64)Days of hourly traffic history (default 7)
Response 200 · OK · application/json
- acceptWorkloadsbooleanrequiredWhether services may be scheduled on this server. Turning it off keeps what already runs here and refuses new placements and moves.
- acmeEmailstring | nullrequired
- agentVersionstring | nullrequired
- baseDomainstring | nullrequired
- buildAllowEmulationbooleanrequiredAllow building for another CPU architecture through emulation (slow); needs the agent to report emulation for the platform
- buildAllowPreviewsbooleanrequiredAllow pull request previews (untrusted code) to build here; off by default
- buildEnabledbooleanrequiredThe server builds images for other servers and pushes them to a registry (the Builds or Both role). Independent of acceptWorkloads.
- buildMaxConcurrentinteger (int64)requiredBuilds that run at the same time; more queue on the control plane
- composeVersionstringrequiredDocker Compose plugin version the agent reported, empty when it has none
- controlPlanebooleanrequiredThe host the installer put the control plane on; its proxy serves the dashboard
- createdAtstring (date-time)required
- diskAlertbooleanrequiredTrue while the root filesystem is at or above the threshold
- diskAlertThresholdPercentinteger (int64)requiredRoot filesystem usage that raises the disk alert (50-99)
- drainMessagestringrequiredWhy the last drain failed or was canceled, empty otherwise
- drainStartedAtstring (date-time) | nullrequired
- drainStateenum: none | draining | drained | failedrequiredEvacuation state; draining and drained servers accept no new services
- Factsrequired
- geoEnabledbooleanrequiredCount where requests come from (country, and city at the city level) from the client IP; IPs are never stored
- geoLevelenum: country | cityrequiredcountry needs a ~8 MB database on the server, city ~130 MB
- geoRefreshDaysinteger (int64)requiredCheck for a newer database every N days (1-90)
- geoSourceenum: dbip | maxmindrequireddbip = DB-IP Lite (CC BY 4.0, no key); maxmind = MaxMind GeoLite2 with the team's account
- idstringrequired
- lastSeenAtstring (date-time) | nullrequired
- Latestrequired
- metricsRetentionDaysinteger (int64)requiredHow long resource metric history is kept (1-90)
- namestringrequired
- ServerPatchSummaryrequired
- protocolVersioninteger (int32) | nullrequired
- Proxyrequired
- publicIpstring | nullrequired
- serviceCountinteger (int64)required
- statusenum: pending | online | offline | revokedrequired
- trafficAnalyticsEnabledbooleanrequiredAggregate Traefik access logs into traffic analytics
- trafficDailyRetentionDaysinteger (int64)requiredDaily traffic history (7-365 days)
- trafficHourlyRetentionDaysinteger (int64)requiredHourly traffic history (2-90 days)
- ServerTunnelSummaryrequired
- unrestrictedbooleanrequiredAn instance admin made this server unrestricted: stacks and services on it may use privileged mode, host networking, devices, GPUs, a runtime, the host PID namespace, unconfined seccomp or AppArmor, NET_ADMIN, SYS_ADMIN, the Docker socket and host bind mounts
401Unauthorized403Forbidden404Not Found422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/agent-upgradeUpgrade one server's agent to the control plane's version
The agent downloads the binary from this control plane, checks its SHA-256 against the one in the command, replaces itself, restarts when its running work is done and rolls back if the new binary does not start. Needs the Owner or Admin role; audited. 409 server_offline, agent_current, agent_newer or upgrade_in_progress; 422 agent_predates_upgrade (re-run the agent installer once) or no_agent_binary.
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key (<=255 chars). A retry with the same key replays the original response for 24 hours. |
serverIdrequired | path | string |
Request body · application/json · required
- forcebooleanInstall a version this agent rolled back before.
Response 202 · Accepted · application/json
- agentVersionstring
- canSelfUpgradebooleanrequired
- finishedAtstring (date-time)
- messagestring
- namestringrequired
- reasonstringWhy the agent cannot be upgraded now.
- requestedAtstring (date-time)
- serverIdstringrequired
- skewenum: current | behind | ahead | unknownrequiredThe agent against the control plane: behind (older), ahead (newer), current, or unknown when a version is not a release version.
- stateenum: queued | restarting | succeeded | failed
- statusstringrequiredpending, online, offline or revoked.
- targetVersionstring
- triggerenum: auto | manual
- upgradablebooleanrequiredThe agent can be upgraded now.
401Unauthorized403Forbidden404Not Found409Conflictserver_offline422Unprocessable Entityagent_predates_upgrade500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/cleanupDocker cleanup settings and history of a server
Whether the scheduled cleanup is on, when it runs next and the most recent runs with what each prune step removed. A cleanup removes dangling images, unused images older than unusedImageMinAgeHours (default 72), build cache older than buildCacheMinAgeDays (default 7) and unused NebulaCtrl networks, and optionally stopped containers NebulaCtrl does not manage. It never removes the current or a rollback-eligible release's image, a pinned infrastructure image, or any volume.
| Parameter | In | Type | Description |
|---|---|---|---|
serverIdrequired | path | string |
Response 200 · OK · application/json
- agentSupportedbooleanrequiredThe server's agent can run a cleanup
- buildCacheMinAgeDaysinteger (int64)requiredBuild cache older than this many days is pruned (default 7)
- cronstringrequiredThe schedule as a 5-field cron expression, evaluated in UTC (default 0 4 * * *)
- diskAlertbooleanrequiredThe disk alert is active now
- diskAlertThresholdPercentinteger (int64)requiredThe server's disk alert threshold, which starts the emergency cleanup when diskTriggerPercent is null
- diskTriggerPercentinteger (int64) | nullrequiredDisk usage (50-99) that starts an emergency cleanup; null follows the server's disk alert threshold
- enabledbooleanrequiredScheduled and emergency cleanups run (default true)
- nextRunAtstring (date-time) | nullrequiredThe next scheduled cleanup; null when cleanup is off
- removeStoppedUnmanagedbooleanrequiredAlso remove stopped containers NebulaCtrl does not manage (default false)
- runningbooleanrequiredA cleanup is waiting for the agent or running
- CleanupRun[]requiredThe most recent runs, newest first
- schedulestringrequiredThe schedule in words
- unusedImageMinAgeHoursinteger (int64)requiredUnused images older than this are removed unless a release or the infrastructure needs them (default 72)
401Unauthorized403Forbidden404Not Found422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/cleanupChange the Docker cleanup settings of a server
Needs the servers:write scope. cron sets the schedule (UTC), unusedImageMinAgeHours and buildCacheMinAgeDays the age limits and diskTriggerPercent the disk usage that starts an emergency run (omitted or 0: the server's disk alert threshold); omitted or 0 keeps each default. Turning the schedule off also turns off the emergency run; "Run cleanup now" still works. 422 validation_failed for a bad cron expression (or one that fires more often than every 15 minutes) or an out-of-range value.
| Parameter | In | Type | Description |
|---|---|---|---|
serverIdrequired | path | string |
Request body · application/json · required
- buildCacheMinAgeDaysinteger (int64)Prune build cache older than this many days (1-365). 0 or omitted keeps the default, 7.
- cronstringThe schedule: a 5-field cron expression (or @daily, @weekly, ...) evaluated in UTC. Runs must be at least 15 minutes apart. Empty keeps the default, 0 4 * * *.
- diskTriggerPercentinteger (int64)Start an emergency cleanup when disk usage reaches this percent (50-99). 0 or omitted follows the server's disk alert threshold.
- enabledbooleanrequiredRun the scheduled (daily, 04:00 UTC) and emergency cleanups
- removeStoppedUnmanagedbooleanrequiredAlso remove stopped containers that NebulaCtrl does not manage. Their volumes are kept.
- unusedImageMinAgeHoursinteger (int64)Remove unused images older than this many hours (1-8760). 0 or omitted keeps the default, 72.
Response 200 · OK · application/json
- agentSupportedbooleanrequiredThe server's agent can run a cleanup
- buildCacheMinAgeDaysinteger (int64)requiredBuild cache older than this many days is pruned (default 7)
- cronstringrequiredThe schedule as a 5-field cron expression, evaluated in UTC (default 0 4 * * *)
- diskAlertbooleanrequiredThe disk alert is active now
- diskAlertThresholdPercentinteger (int64)requiredThe server's disk alert threshold, which starts the emergency cleanup when diskTriggerPercent is null
- diskTriggerPercentinteger (int64) | nullrequiredDisk usage (50-99) that starts an emergency cleanup; null follows the server's disk alert threshold
- enabledbooleanrequiredScheduled and emergency cleanups run (default true)
- nextRunAtstring (date-time) | nullrequiredThe next scheduled cleanup; null when cleanup is off
- removeStoppedUnmanagedbooleanrequiredAlso remove stopped containers NebulaCtrl does not manage (default false)
- runningbooleanrequiredA cleanup is waiting for the agent or running
- CleanupRun[]requiredThe most recent runs, newest first
- schedulestringrequiredThe schedule in words
- unusedImageMinAgeHoursinteger (int64)requiredUnused images older than this are removed unless a release or the infrastructure needs them (default 72)
401Unauthorized403Forbidden404Not Found422Unprocessable Entityvalidation_failed500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/cleanup/runsRun the Docker cleanup of a server now
Queues the same cleanup the schedule runs. The result (reclaimed bytes, items per step) appears in the server's cleanup history. 409 server_offline when the server is offline, 409 cleanup_running while one is in flight.
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key (<=255 chars). A retry with the same key replays the original response for 24 hours. |
serverIdrequired | path | string |
Response 202 · Accepted · application/json
- createdAtstring (date-time)required
- errorstring
- finishedAtstring (date-time) | nullrequired
- idstringrequired
- itemsinteger (int64)requiredThings removed: containers, images, networks or volumes
- modeenum: standard | volumesrequiredstandard is the scheduled cleanup; volumes the explicit removal of unused volumes
- reclaimedBytesinteger (int64)required
- statusenum: pending | succeeded | failedrequired
- CleanupStep[]requiredWhat each prune step did; empty until the agent reports
- triggerenum: scheduled | emergency | manualrequired
401Unauthorized403Forbidden404Not Found409Conflictserver_offlinecleanup_running422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/cleanup/volumesRemove unused Docker volumes of a server
Removes volumes that no container (running or stopped) mounts and that NebulaCtrl does not manage: anonymous volumes and volumes made outside NebulaCtrl. Volumes of NebulaCtrl services (nc-vol-*, or labeled as managed) are never removed. This deletes data and cannot be undone: confirm must be the server's name. The schedule never does this.
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key (<=255 chars). A retry with the same key replays the original response for 24 hours. |
serverIdrequired | path | string |
Request body · application/json · required
- confirmstringrequiredThe server's name, typed to confirm
Response 202 · Accepted · application/json
- createdAtstring (date-time)required
- errorstring
- finishedAtstring (date-time) | nullrequired
- idstringrequired
- itemsinteger (int64)requiredThings removed: containers, images, networks or volumes
- modeenum: standard | volumesrequiredstandard is the scheduled cleanup; volumes the explicit removal of unused volumes
- reclaimedBytesinteger (int64)required
- statusenum: pending | succeeded | failedrequired
- CleanupStep[]requiredWhat each prune step did; empty until the agent reports
- triggerenum: scheduled | emergency | manualrequired
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/hardeningHost hardening of a server: the Lynis index, the safe fixes and what is left
The Security tab: Lynis's hardening index from the latest audit, every curated safe fix with its state on the host (applied, already compliant, pending, unavailable), the findings that remain with an explanation and the commands to deal with them, and the history of runs. NebulaCtrl never offers a fix for SSH, the firewall or accounts.
| Parameter | In | Type | Description |
|---|---|---|---|
serverIdrequired | path | string |
Response 200 · OK · application/json
- agentSupportedbooleanrequiredThe server's agent can audit the host
- auditedAtstring (date-time) | nullrequired
- firstIndexinteger (int64) | nullrequiredThe score of the first audit
- HardeningFix[]required
- hardeningIndexinteger (int64) | nullrequiredLynis's 0 to 100 score from the latest audit; null before the first audit
- lynisInstalledbooleanrequired
- lynisVersionstring
- modeenum: host | helper |How the agent reaches the host: directly, or through a privileged helper container
- nextAuditAtstring (date-time) | nullrequiredThe next weekly audit; null when the weekly audit is off
- pendingSafeinteger (int64)requiredDefault fixes that would change something now
- rebootRequiredbooleanrequiredAn applied fix takes effect after the next reboot
- HardeningRemaining[]required
- runningbooleanrequiredAn audit or fix run waits for the agent or is running
- HardeningRun[]requiredThe most recent runs, newest first
- suggestionsinteger (int64)required
- testsDoneinteger (int64)required
- warningsinteger (int64)required
- weeklybooleanrequiredA weekly audit runs (default true)
401Unauthorized403Forbidden404Not Found422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/hardeningSwitch the weekly Lynis audit of a server
Needs the servers:write scope and the Owner or Admin role. Audited.
| Parameter | In | Type | Description |
|---|---|---|---|
serverIdrequired | path | string |
Request body · application/json · required
- weeklybooleanrequiredAudit the host every week (default true)
Response 200 · OK · application/json
- agentSupportedbooleanrequiredThe server's agent can audit the host
- auditedAtstring (date-time) | nullrequired
- firstIndexinteger (int64) | nullrequiredThe score of the first audit
- HardeningFix[]required
- hardeningIndexinteger (int64) | nullrequiredLynis's 0 to 100 score from the latest audit; null before the first audit
- lynisInstalledbooleanrequired
- lynisVersionstring
- modeenum: host | helper |How the agent reaches the host: directly, or through a privileged helper container
- nextAuditAtstring (date-time) | nullrequiredThe next weekly audit; null when the weekly audit is off
- pendingSafeinteger (int64)requiredDefault fixes that would change something now
- rebootRequiredbooleanrequiredAn applied fix takes effect after the next reboot
- HardeningRemaining[]required
- runningbooleanrequiredAn audit or fix run waits for the agent or is running
- HardeningRun[]requiredThe most recent runs, newest first
- suggestionsinteger (int64)required
- testsDoneinteger (int64)required
- warningsinteger (int64)required
- weeklybooleanrequiredA weekly audit runs (default true)
401Unauthorized403Forbidden404Not Found422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/hardening/applyApply safe hardening fixes
Applies the selected fixes (the default set when none is selected), checks each one and undoes it by itself if it did not take effect, then audits again so the new index is known. Each fix is reversible with the rollback endpoint. Never changes SSH, the firewall or accounts. Needs the Owner or Admin role; audited.
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key (<=255 chars). A retry with the same key replays the original response for 24 hours. |
serverIdrequired | path | string |
Request body · application/json · required
- fixIdsstring[] | nullThe fixes to apply or undo. Apply with none selects the default set (the ones marked default in the fix list); rollback needs at least one.
Response 202 · Accepted · application/json
- actionenum: audit | apply | rollbackrequired
- createdAtstring (date-time)required
- errorstring
- finishedAtstring (date-time) | nullrequired
- fixIdsstring[]required
- hardeningIndexinteger (int64) | nullrequiredThe hardening index the run measured; null when it did not audit
- idstringrequired
- indexBeforeinteger (int64) | nullrequiredThe hardening index before the run; null when there was no audit yet
- lynisVersionstring
- messagestring
- HardeningFixOutcome[]requiredWhat an apply or rollback did, per fix
- statusenum: pending | succeeded | failed | skippedrequiredskipped: Lynis is not installed on the server
- triggerenum: scheduled | manualrequired
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/hardening/auditAudit the host with Lynis now
Queues a Lynis audit on the server. It only reads the host. With installLynis, the agent first installs Lynis (from CISOfy's repository, else the distribution's). Needs the Owner or Admin role. 409 server_offline when the server is offline, 409 hardening_running while a run is in flight.
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key (<=255 chars). A retry with the same key replays the original response for 24 hours. |
serverIdrequired | path | string |
Request body · application/json · required
- installLynisbooleanInstall Lynis from the distribution's or CISOfy's package repository when the server does not have it
Response 202 · Accepted · application/json
- actionenum: audit | apply | rollbackrequired
- createdAtstring (date-time)required
- errorstring
- finishedAtstring (date-time) | nullrequired
- fixIdsstring[]required
- hardeningIndexinteger (int64) | nullrequiredThe hardening index the run measured; null when it did not audit
- idstringrequired
- indexBeforeinteger (int64) | nullrequiredThe hardening index before the run; null when there was no audit yet
- lynisVersionstring
- messagestring
- HardeningFixOutcome[]requiredWhat an apply or rollback did, per fix
- statusenum: pending | succeeded | failed | skippedrequiredskipped: Lynis is not installed on the server
- triggerenum: scheduled | manualrequired
400Bad Request401Unauthorized403Forbidden404Not Found409Conflictserver_offlinehardening_running422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/hardening/rollbackUndo safe hardening fixes
Restores what NebulaCtrl changed for the selected fixes: the previous sysctl values, file modes, login.defs lines and banners. A fix NebulaCtrl did not apply is left alone. Needs the Owner or Admin role; audited.
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key (<=255 chars). A retry with the same key replays the original response for 24 hours. |
serverIdrequired | path | string |
Request body · application/json · required
- fixIdsstring[] | nullThe fixes to apply or undo. Apply with none selects the default set (the ones marked default in the fix list); rollback needs at least one.
Response 202 · Accepted · application/json
- actionenum: audit | apply | rollbackrequired
- createdAtstring (date-time)required
- errorstring
- finishedAtstring (date-time) | nullrequired
- fixIdsstring[]required
- hardeningIndexinteger (int64) | nullrequiredThe hardening index the run measured; null when it did not audit
- idstringrequired
- indexBeforeinteger (int64) | nullrequiredThe hardening index before the run; null when there was no audit yet
- lynisVersionstring
- messagestring
- HardeningFixOutcome[]requiredWhat an apply or rollback did, per fix
- statusenum: pending | succeeded | failed | skippedrequiredskipped: Lynis is not installed on the server
- triggerenum: scheduled | manualrequired
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/meshMesh node of a server
Whether the server joined the mesh, its node (state, tailnet addresses, peers, exposed services) and the link nodes that run on it.
| Parameter | In | Type | Description |
|---|---|---|---|
serverIdrequired | path | string |
Response 200 · OK · application/json
- agentCapablebooleanrequired
- enabledbooleanrequired
- MeshLinkView[] | nullrequiredLink nodes that run on this server
- NodeViewrequired
- pausedbooleanrequired
- tunDevicebooleanrequired
401Unauthorized403Forbidden404Not Found422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/meshTurn the mesh on or off for a server
Enabling adds one tagged device to the team's tailnet (it may be billed by Tailscale) and needs acceptMeshChanges; with ?dryRun=true it returns the plan instead (devices added, whether the host has /dev/net/tun, warnings and blockers). Disabling is refused (409 mesh_server_in_use) while replicas or cross-server links use the server's node. The node key is minted when the command is sent and never stored.
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key (<=255 chars). A retry with the same key replays the original response for 24 hours. |
serverIdrequired | path | string | |
dryRun | query | boolean | Return the plan (devices added, blockers, warnings) without changing anything |
Request body · application/json · required
- acceptMeshChangesbooleanConfirms that enabling adds tailnet devices (tagged devices may be billed by Tailscale)
- enabledbooleanrequired
Response 202 · Accepted · application/json
- appliedbooleanrequired
- enabledbooleanrequired
- ServerMeshPlanrequired
401Unauthorized403Forbidden404Not Found422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/mesh/checkTest the mesh connectivity of a server
The agent checks whether the server's node reaches the other servers' nodes (connected, refused, timeout, no_path). This is the ground truth for advisory ACL modes.
| Parameter | In | Type | Description |
|---|---|---|---|
serverIdrequired | path | string |
Request body · application/json · required
- peerServerIdstringCheck only this peer (default: every other server with a mesh node)
Response 200 · OK · application/json
- ServerCheckResult[] | nullrequired
401Unauthorized403Forbidden404Not Found422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/mesh/reprovisionRe-provision the mesh node of a server
Deletes the node's device from the tailnet and re-creates it with a fresh single-use key and a fresh state volume. The node gets a new tailnet IP and the access rules regenerate. Use it when the node needs attention.
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key (<=255 chars). A retry with the same key replays the original response for 24 hours. |
serverIdrequired | path | string |
Response 202 · Accepted · application/json
- acceptedbooleanrequired
401Unauthorized403Forbidden404Not Found422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/patchesPending OS updates and reboot-required of a server
The Updates panel: how many packages are waiting (and how many are security updates), whether the host asks for a reboot, the pending packages with a warning where an upgrade is risky, the production services that run on the server, and the recent runs. The agent checks every server about every 6 hours; known is false until the first check completes.
| Parameter | In | Type | Description |
|---|---|---|---|
serverIdrequired | path | string |
Response 200 · OK · application/json
- agentSupportedbooleanrequiredThe agent advertised patching support; false means update the agent first
- busyenum: check | apply | reboot | requiredThe run in flight, if any
- checkedAtstring (date-time) | nullrequired
- controlPlanebooleanrequiredThis server runs the control plane: upgrades and reboots take the dashboard down
- knownbooleanrequiredA check has completed at least once
- managerenum: apt | dnf | requiredEmpty until the first check
- messagestringA caution from the last check
- onlinebooleanrequired
- PatchPackage[]requiredPending upgrades, security first, at most 200
- ProductionService[]required
- rebootPackagesstring[]requiredPackages that asked for the reboot, when the host says
- rebootRequiredbooleanrequired
- PatchRun[]requiredThe most recent runs, newest first, without logs
- securityinteger (int64)requiredHow many of the updates are security updates
- stalebooleanrequiredThe last check is older than 12 hours
- supportedbooleanrequiredThe host has a supported package manager (apt or dnf)
- updatesinteger (int64)required
401Unauthorized403Forbidden404Not Found422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/patches/applyUpgrade the server's packages
Runs apt-get upgrade or dnf upgrade (security updates only with securityOnly) on the host as root, keeping the configuration files you changed, then checks again. The upgrade runs detached on the host, so it finishes even when Docker restarts. Never reboots. Instance admin only; confirm must be the server's name; a server that runs production services or the control plane also needs acknowledgeProduction (422 production_ack_required), and a token that asks for production approvals gets 409 approval_required. Needs a completed check first (409 no_check_yet). Audited.
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key (<=255 chars). A retry with the same key replays the original response for 24 hours. |
serverIdrequired | path | string |
Request body · application/json · required
- acknowledgeProductionbooleanRequired when production services or the control plane run on the server
- confirmstringrequiredThe server's name, typed by the person
- securityOnlybooleanUpgrade only the packages with a security update
Response 202 · Accepted · application/json
- actionenum: check | apply | rebootrequired
- createdAtstring (date-time)required
- errorstring
- exitCodeinteger (int64) | nullrequiredThe package manager's exit status (upgrades only)
- finishedAtstring (date-time) | nullrequired
- idstringrequired
- logstringThe tail of what the package manager printed (upgrades only; only in the single-run read)
- messagestring
- rebootingSincestring (date-time) | nullrequired
- requestedBystringThe person who started the run; absent for automatic checks
- securityOnlybooleanrequired
- statusenum: pending | rebooting | succeeded | failedrequiredrebooting: the host accepted the reboot and NebulaCtrl waits for the agent to reconnect on a new boot
- triggerenum: scheduled | manualrequired
- updatesAfterinteger (int64) | nullrequired
- updatesBeforeinteger (int64) | nullrequired
400Bad Request401Unauthorized403Forbidden404Not Found409Conflictapproval_requiredno_check_yet422Unprocessable Entityproduction_ack_required500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/patches/checkCheck the server for updates now
Refreshes the package lists on the host and records the pending updates and reboot-required. Changes no package. Needs the Owner or Admin role. 409 server_offline when the server is offline, 409 patching_running while a run is in flight.
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key (<=255 chars). A retry with the same key replays the original response for 24 hours. |
serverIdrequired | path | string |
Response 202 · Accepted · application/json
- actionenum: check | apply | rebootrequired
- createdAtstring (date-time)required
- errorstring
- exitCodeinteger (int64) | nullrequiredThe package manager's exit status (upgrades only)
- finishedAtstring (date-time) | nullrequired
- idstringrequired
- logstringThe tail of what the package manager printed (upgrades only; only in the single-run read)
- messagestring
- rebootingSincestring (date-time) | nullrequired
- requestedBystringThe person who started the run; absent for automatic checks
- securityOnlybooleanrequired
- statusenum: pending | rebooting | succeeded | failedrequiredrebooting: the host accepted the reboot and NebulaCtrl waits for the agent to reconnect on a new boot
- triggerenum: scheduled | manualrequired
- updatesAfterinteger (int64) | nullrequired
- updatesBeforeinteger (int64) | nullrequired
400Bad Request401Unauthorized403Forbidden404Not Found409Conflictserver_offlinepatching_running422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/patches/planWhat an upgrade of the server would do
The plan shown before the confirmation: the packages that would be upgraded, the risky ones among them and why, whether a reboot will probably be needed, whether Docker restarts, the production services on the server and what the apply request must carry (the server's name, and acknowledgeProduction when requiresAcknowledgement). Changes nothing.
| Parameter | In | Type | Description |
|---|---|---|---|
serverIdrequired | path | string | |
securityOnly | query | boolean | Plan to upgrade only the packages with a security update |
Response 200 · OK · application/json
- checkedAtstring (date-time) | nullrequired
- confirmstringrequiredWhat the person types to confirm: the server's name
- controlPlanebooleanrequired
- managerenum: apt | dnf | required
- notReadyReasonstring
- PatchPackage[]required
- ProductionService[]required
- readybooleanrequiredThe plan can be applied now
- rebootLikelybooleanrequiredThe upgrade probably leaves the server wanting a reboot
- requiresAcknowledgementbooleanrequired
- restartsDockerbooleanrequiredDocker is among the packages: its daemon restarts and containers may stop for a moment
- PatchRisk[]required
- securityinteger (int64)required
- securityOnlybooleanrequired
- serverstringrequired
- servicesOnServerinteger (int64)required
- stalebooleanrequired
- updatesinteger (int64)requiredPackages that would be upgraded
- warningsstring[]required
401Unauthorized403Forbidden404Not Found422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/patches/rebootReboot the server
Schedules a reboot of the host a few seconds ahead. Every service on the server goes down until it boots and Docker starts them again. The run stays rebooting until the agent reconnects on a new boot (it fails after 20 minutes). Instance admin only; confirm must be the server's name; a server that runs production services or the control plane also needs acknowledgeProduction. Audited.
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key (<=255 chars). A retry with the same key replays the original response for 24 hours. |
serverIdrequired | path | string |
Request body · application/json · required
- acknowledgeProductionbooleanRequired when production services or the control plane run on the server
- confirmstringrequiredThe server's name, typed by the person
Response 202 · Accepted · application/json
- actionenum: check | apply | rebootrequired
- createdAtstring (date-time)required
- errorstring
- exitCodeinteger (int64) | nullrequiredThe package manager's exit status (upgrades only)
- finishedAtstring (date-time) | nullrequired
- idstringrequired
- logstringThe tail of what the package manager printed (upgrades only; only in the single-run read)
- messagestring
- rebootingSincestring (date-time) | nullrequired
- requestedBystringThe person who started the run; absent for automatic checks
- securityOnlybooleanrequired
- statusenum: pending | rebooting | succeeded | failedrequiredrebooting: the host accepted the reboot and NebulaCtrl waits for the agent to reconnect on a new boot
- triggerenum: scheduled | manualrequired
- updatesAfterinteger (int64) | nullrequired
- updatesBeforeinteger (int64) | nullrequired
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/patches/runs/{runId}One check, upgrade or reboot of a server, with the upgrade's log
The log is the tail of what the package manager printed. A run in rebooting waits for the agent to reconnect on a new boot.
| Parameter | In | Type | Description |
|---|---|---|---|
serverIdrequired | path | string | |
runIdrequired | path | string |
Response 200 · OK · application/json
- actionenum: check | apply | rebootrequired
- createdAtstring (date-time)required
- errorstring
- exitCodeinteger (int64) | nullrequiredThe package manager's exit status (upgrades only)
- finishedAtstring (date-time) | nullrequired
- idstringrequired
- logstringThe tail of what the package manager printed (upgrades only; only in the single-run read)
- messagestring
- rebootingSincestring (date-time) | nullrequired
- requestedBystringThe person who started the run; absent for automatic checks
- securityOnlybooleanrequired
- statusenum: pending | rebooting | succeeded | failedrequiredrebooting: the host accepted the reboot and NebulaCtrl waits for the agent to reconnect on a new boot
- triggerenum: scheduled | manualrequired
- updatesAfterinteger (int64) | nullrequired
- updatesBeforeinteger (int64) | nullrequired
401Unauthorized403Forbidden404Not Found422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/revokeRevoke a server's agent
Revokes the agent identity and pending enrollment tokens, cancels commands that were never delivered (their deployments fail with "Server revoked. No changes were made.") and disconnects the agent. Containers already running on the host are left untouched.
| Parameter | In | Type | Description |
|---|---|---|---|
serverIdrequired | path | string |
Response 200 · OK · application/json
- acceptWorkloadsbooleanrequiredWhether services may be scheduled on this server. Turning it off keeps what already runs here and refuses new placements and moves.
- acmeEmailstring | nullrequired
- agentVersionstring | nullrequired
- baseDomainstring | nullrequired
- buildAllowEmulationbooleanrequiredAllow building for another CPU architecture through emulation (slow); needs the agent to report emulation for the platform
- buildAllowPreviewsbooleanrequiredAllow pull request previews (untrusted code) to build here; off by default
- buildEnabledbooleanrequiredThe server builds images for other servers and pushes them to a registry (the Builds or Both role). Independent of acceptWorkloads.
- buildMaxConcurrentinteger (int64)requiredBuilds that run at the same time; more queue on the control plane
- composeVersionstringrequiredDocker Compose plugin version the agent reported, empty when it has none
- controlPlanebooleanrequiredThe host the installer put the control plane on; its proxy serves the dashboard
- createdAtstring (date-time)required
- diskAlertbooleanrequiredTrue while the root filesystem is at or above the threshold
- diskAlertThresholdPercentinteger (int64)requiredRoot filesystem usage that raises the disk alert (50-99)
- drainMessagestringrequiredWhy the last drain failed or was canceled, empty otherwise
- drainStartedAtstring (date-time) | nullrequired
- drainStateenum: none | draining | drained | failedrequiredEvacuation state; draining and drained servers accept no new services
- Factsrequired
- geoEnabledbooleanrequiredCount where requests come from (country, and city at the city level) from the client IP; IPs are never stored
- geoLevelenum: country | cityrequiredcountry needs a ~8 MB database on the server, city ~130 MB
- geoRefreshDaysinteger (int64)requiredCheck for a newer database every N days (1-90)
- geoSourceenum: dbip | maxmindrequireddbip = DB-IP Lite (CC BY 4.0, no key); maxmind = MaxMind GeoLite2 with the team's account
- idstringrequired
- lastSeenAtstring (date-time) | nullrequired
- Latestrequired
- metricsRetentionDaysinteger (int64)requiredHow long resource metric history is kept (1-90)
- namestringrequired
- ServerPatchSummaryrequired
- protocolVersioninteger (int32) | nullrequired
- Proxyrequired
- publicIpstring | nullrequired
- serviceCountinteger (int64)required
- statusenum: pending | online | offline | revokedrequired
- trafficAnalyticsEnabledbooleanrequiredAggregate Traefik access logs into traffic analytics
- trafficDailyRetentionDaysinteger (int64)requiredDaily traffic history (7-365 days)
- trafficHourlyRetentionDaysinteger (int64)requiredHourly traffic history (2-90 days)
- ServerTunnelSummaryrequired
- unrestrictedbooleanrequiredAn instance admin made this server unrestricted: stacks and services on it may use privileged mode, host networking, devices, GPUs, a runtime, the host PID namespace, unconfined seccomp or AppArmor, NET_ADMIN, SYS_ADMIN, the Docker socket and host bind mounts
401Unauthorized403Forbidden404Not Found422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/tunnelCloudflare Tunnel state of a server
Whether the server has a Cloudflare Tunnel, the connector's observed state and the ingress sync. A server without a tunnel answers state: off and says whether one can be enabled.
| Parameter | In | Type | Description |
|---|---|---|---|
serverIdrequired | path | string |
Response 200 · OK · application/json
- accountIdstring
- accountReadybooleanrequiredThe connection has an account ID (needed for tunnels)
- activebooleanrequired
- agentSupportedbooleanrequiredThe server's agent can run the cloudflared connector
- cloudflareConnectedbooleanrequiredThe team has a Cloudflare connection
- cnamestringThe DNS target of the tunnel: <tunnelId>.cfargotunnel.com
- connectionsinteger (int64)requiredReady connections to Cloudflare's edge
- enabledbooleanrequiredThe server has a tunnel (or is removing one)
- imagestring
- ingressErrorstring
- ingressHostsinteger (int64)required
- ingressSyncedAtstring (date-time) | nullrequired
- messagestringrequiredWhy the connector needs attention, or the last teardown problem
- observedAtstring (date-time) | nullrequired
- stateenum: off | provisioning | online | offline | needs_attention | removingrequiredObserved connector state; off when the server has no tunnel
- tunnelIdstring
- tunnelNamestring
- upstreamstringrequiredWhere the tunnel forwards every request
401Unauthorized403Forbidden404Not Found422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/tunnelEnable a Cloudflare Tunnel on a server
Creates a remotely-managed tunnel with the team's Cloudflare connection, pushes its ingress rules (every hostname of the server's services to the proxy, then a 404 catch-all) and tells the agent to run the cloudflared connector. The connector token is fetched when the command is sent and is never stored. Once the connector connects, the server's domains in connected zones point at the tunnel and ports 80 and 443 may stay closed. Needs the servers:write and proxy:write scopes. The Cloudflare token needs the permission Account, Cloudflare Tunnel, Edit (422 cloudflare_tunnel_forbidden).
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key (<=255 chars). A retry with the same key replays the original response for 24 hours. |
serverIdrequired | path | string |
Response 202 · Accepted · application/json
- accountIdstring
- accountReadybooleanrequiredThe connection has an account ID (needed for tunnels)
- activebooleanrequired
- agentSupportedbooleanrequiredThe server's agent can run the cloudflared connector
- cloudflareConnectedbooleanrequiredThe team has a Cloudflare connection
- cnamestringThe DNS target of the tunnel: <tunnelId>.cfargotunnel.com
- connectionsinteger (int64)requiredReady connections to Cloudflare's edge
- enabledbooleanrequiredThe server has a tunnel (or is removing one)
- imagestring
- ingressErrorstring
- ingressHostsinteger (int64)required
- ingressSyncedAtstring (date-time) | nullrequired
- messagestringrequiredWhy the connector needs attention, or the last teardown problem
- observedAtstring (date-time) | nullrequired
- stateenum: off | provisioning | online | offline | needs_attention | removingrequiredObserved connector state; off when the server has no tunnel
- tunnelIdstring
- tunnelNamestring
- upstreamstringrequiredWhere the tunnel forwards every request
401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entitycloudflare_tunnel_forbidden500Internal Server Error502Bad Gateway
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/tunnelDisable the Cloudflare Tunnel of a server
Points the server's domains back at its public IP, removes the connector and deletes the tunnel at Cloudflare shortly afterwards. Disabling a tunnel that is already being removed retries the delete. Ports 80 and 443 must be reachable again before the DNS change propagates.
| Parameter | In | Type | Description |
|---|---|---|---|
serverIdrequired | path | string | |
force | query | boolean | Drop the tunnel record without asking Cloudflare (it may linger in the Cloudflare dashboard). Use it when the Cloudflare connection is gone or Cloudflare keeps refusing the delete. |
Response 202 · Accepted · application/json
- accountIdstring
- accountReadybooleanrequiredThe connection has an account ID (needed for tunnels)
- activebooleanrequired
- agentSupportedbooleanrequiredThe server's agent can run the cloudflared connector
- cloudflareConnectedbooleanrequiredThe team has a Cloudflare connection
- cnamestringThe DNS target of the tunnel: <tunnelId>.cfargotunnel.com
- connectionsinteger (int64)requiredReady connections to Cloudflare's edge
- enabledbooleanrequiredThe server has a tunnel (or is removing one)
- imagestring
- ingressErrorstring
- ingressHostsinteger (int64)required
- ingressSyncedAtstring (date-time) | nullrequired
- messagestringrequiredWhy the connector needs attention, or the last teardown problem
- observedAtstring (date-time) | nullrequired
- stateenum: off | provisioning | online | offline | needs_attention | removingrequiredObserved connector state; off when the server has no tunnel
- tunnelIdstring
- tunnelNamestring
- upstreamstringrequiredWhere the tunnel forwards every request
401Unauthorized403Forbidden404Not Found422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/tunnel/syncRe-sync the Cloudflare Tunnel of a server
Re-pushes the ingress rules and re-sends the connector command (creating the container again when it is gone). Use it when the connector needs attention.
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key (<=255 chars). A retry with the same key replays the original response for 24 hours. |
serverIdrequired | path | string |
Response 202 · Accepted · application/json
- accountIdstring
- accountReadybooleanrequiredThe connection has an account ID (needed for tunnels)
- activebooleanrequired
- agentSupportedbooleanrequiredThe server's agent can run the cloudflared connector
- cloudflareConnectedbooleanrequiredThe team has a Cloudflare connection
- cnamestringThe DNS target of the tunnel: <tunnelId>.cfargotunnel.com
- connectionsinteger (int64)requiredReady connections to Cloudflare's edge
- enabledbooleanrequiredThe server has a tunnel (or is removing one)
- imagestring
- ingressErrorstring
- ingressHostsinteger (int64)required
- ingressSyncedAtstring (date-time) | nullrequired
- messagestringrequiredWhy the connector needs attention, or the last teardown problem
- observedAtstring (date-time) | nullrequired
- stateenum: off | provisioning | online | offline | needs_attention | removingrequiredObserved connector state; off when the server has no tunnel
- tunnelIdstring
- tunnelNamestring
- upstreamstringrequiredWhere the tunnel forwards every request
401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity500Internal Server Error502Bad Gateway
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/unrestrictedThe Unrestricted switch and Compose availability of a server
| Parameter | In | Type | Description |
|---|---|---|---|
serverIdrequired | path | string |
Response 200 · OK · application/json
- availablebooleanrequiredThe agent can run Compose stacks (Docker Compose plugin 2.24 or newer)
- composeVersionstringrequiredDocker Compose plugin version the agent reported, empty when it has none
- dockerServicesinteger (int64)requiredLive services placed on this server that use Docker options which need an unrestricted server
- stacksinteger (int64)requiredLive Compose stacks placed on this server
- unrestrictedbooleanrequiredAn instance admin allowed this server to run stacks and services with privileged mode, host networking, devices, GPUs, a runtime, the host PID namespace, unconfined seccomp or AppArmor, NET_ADMIN, SYS_ADMIN, the Docker socket and host bind mounts
401Unauthorized403Forbidden404Not Found422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/{serverId}/unrestrictedMake a server unrestricted, or restricted again
By default Compose stacks and services run under safe allow-lists: no privileged mode, host network, host PID namespace, devices, GPUs, custom runtime, unconfined seccomp or AppArmor, NET_ADMIN or SYS_ADMIN, Docker socket or host bind mounts. An unrestricted server lifts them for everything on it, so anyone who can deploy there can take over the server. Instance admin only; enabling needs confirm to equal the server's name. Audited as server.unrestricted.enable or .disable. Disabling does not touch running containers: the next deploy, rollback or reconcile of a stack or service that needs the lifted rules fails until it is edited or moved.
| Parameter | In | Type | Description |
|---|---|---|---|
serverIdrequired | path | string |
Request body · application/json · required
- confirmstringThe server's name; required when enabling
- unrestrictedbooleanrequired
Response 200 · OK · application/json
- availablebooleanrequiredThe agent can run Compose stacks (Docker Compose plugin 2.24 or newer)
- composeVersionstringrequiredDocker Compose plugin version the agent reported, empty when it has none
- dockerServicesinteger (int64)requiredLive services placed on this server that use Docker options which need an unrestricted server
- stacksinteger (int64)requiredLive Compose stacks placed on this server
- unrestrictedbooleanrequiredAn instance admin allowed this server to run stacks and services with privileged mode, host networking, devices, GPUs, a runtime, the host PID namespace, unconfined seccomp or AppArmor, NET_ADMIN, SYS_ADMIN, the Docker socket and host bind mounts
401Unauthorized403Forbidden404Not Found422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/agent-upgradesUpgrade agents one server at a time (staged)
Upgrades the given servers (every server whose agent can be upgraded now when none are given) in name order. Each upgrade must be confirmed by the agent reconnecting with the new version before the next one starts; the first failure stops the rollout and leaves the remaining servers untouched. Needs the Owner or Admin role; audited. 409 nothing_to_upgrade when no agent qualifies.
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key (<=255 chars). A retry with the same key replays the original response for 24 hours. |
Request body · application/json · required
- forcebooleanInstall a version an agent rolled back before.
- serverIdsstring[] | nullThe servers to upgrade. Empty: every server whose agent can be upgraded now.
Response 202 · Accepted · application/json
- serverIdsstring[] | nullrequiredThe servers in upgrade order. They are upgraded one at a time; the rollout stops at the first failure.
401Unauthorized403Forbidden404Not Found409Conflictnothing_to_upgrade422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/servers/enrollment-tokensCreate a pending server and a one-time enrollment token
The token is valid for one hour and can enroll exactly one agent. It is returned only in this response (and in an idempotent replay of it).
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key (<=255 chars). A retry with the same key replays the original response for 24 hours. |
Request body · application/json · required
- acmeEmailstring
- baseDomainstring
- namestringrequired
- publicIpstring
Response 201 · Created · application/json
- expiresAtstring (date-time)required
- installCommandstringrequired
- Serverrequired
- tokenstringrequiredShown once; only its hash is stored
401Unauthorized403Forbidden422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.