View .md

Nodes endpoints (Admin API)

23 FeatherPanel Admin API endpoints from admin/nodes.php: methods, paths, auth, permissions, rate limits, parameters and responses.

Last synced from FeatherPanel 15b94e9 on .

On this page

Defined in backend/app/routes/admin/nodes.php. Authentication used here: Admin. Read Authentication for how to send credentials and Rate limits and errors for the response envelope.

Paths, methods, permissions and rate limits come from the route file. Summaries, parameters and response codes come from the OpenAPI annotations on the controllers; endpoints without annotations show only what the route file declares.

Endpoints

GET/api/admin/nodes/status/global

Auth: AdminPermission: admin.nodes.viewRoute name: admin-nodes-status-globalController: NodeStatusController::getGlobalStatusroute source

Get global node status and utilization Retrieve aggregated utilization and status information from all nodes including CPU, memory, disk usage, and health status.

Response data fieldTypeDescription
globalobject
nodesobject[]
curl -X GET "$PANEL_URL/api/admin/nodes/status/global" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"

Responses: 200 Global node status retrieved successfully · 401 Unauthorized · 403 Forbidden - Insufficient permissions

GET/api/admin/nodes

Auth: AdminPermission: admin.nodes.viewRoute name: admin-nodesController: NodesController::indexroute source

Get all nodes Retrieve a paginated list of all nodes with optional search functionality.

ParameterInTypeRequiredDescription
pagequeryintegernoPage number for pagination
limitqueryintegernoNumber of records per page
searchquerystringnoSearch term to filter nodes by name or FQDN
location_idqueryintegernoLocation ID to filter nodes by
exclude_node_idqueryintegernoNode ID to exclude from results (useful for transfer destinations)
Response data fieldTypeDescription
nodesNode[]
paginationNodePagination
searchobject
curl -X GET "$PANEL_URL/api/admin/nodes" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"

Responses: 200 Nodes retrieved successfully · 401 Unauthorized · 403 Forbidden - Insufficient permissions

GET/api/admin/nodes/{id}

Auth: AdminPermission: admin.nodes.viewRoute name: admin-nodes-showController: NodesController::showroute source

Get node by ID Retrieve a specific node by its ID.

ParameterInTypeRequiredDescription
idpathintegeryesNode ID
Response data fieldTypeDescription
nodeNode
curl -X GET "$PANEL_URL/api/admin/nodes/$ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"

Responses: 200 Node retrieved successfully · 400 Bad request - Invalid node ID · 401 Unauthorized · 403 Forbidden - Insufficient permissions · 404 Node not found

GET/api/admin/nodes/{id}/diagnostics

Auth: AdminPermission: admin.nodes.viewRoute name: admin-nodes-diagnosticsController: NodesController::diagnosticsroute source

Generate node diagnostics bundle Fetches diagnostics output from the Wings daemon. Returns plain-text content by default or an uploaded report URL when format=url.

ParameterInTypeRequiredDescription
idpathintegeryesNode ID
include_endpointsquerybooleannoInclude HTTP endpoint metadata
include_logsquerybooleannoInclude daemon logs in the report
log_linesqueryintegernoNumber of log lines to include (1-500)
formatquerystringnoResponse format: raw text or uploaded URL
upload_api_urlquerystringnoOverride upload endpoint when requesting format=url
Response data fieldTypeDescription
diagnosticsobject
curl -X GET "$PANEL_URL/api/admin/nodes/$ID/diagnostics" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"

Responses: 200 Diagnostics generated successfully · 400 Bad request - Invalid query parameters · 401 Unauthorized · 403 Forbidden - Insufficient permissions · 404 Node not found · 500 Internal server error - Failed to generate diagnostics

GET/api/admin/nodes/{id}/system-logs

Auth: AdminPermission: admin.nodes.viewRoute name: admin-nodes-system-logsController: NodesController::listSystemLogsroute source

List node system log files Lists daemon log files via Calagopus GET /api/system/logs.

ParameterInTypeRequiredDescription
idpathintegeryesNode ID
curl -X GET "$PANEL_URL/api/admin/nodes/$ID/system-logs" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"

Responses: 200 System logs listed successfully · 404 Node not found · 500 Failed to list system logs · 501 Daemon feature unsupported

GET/api/admin/nodes/{id}/system-logs/{file}

Auth: AdminPermission: admin.nodes.viewRoute name: admin-nodes-system-log-fileController: NodesController::getSystemLogFileroute source

Read a node system log file Reads a daemon log file via Calagopus GET /api/system/logs/{file}.

ParameterInTypeRequiredDescription
idpathintegeryesNode ID
filepathstringyesLog file name
curl -X GET "$PANEL_URL/api/admin/nodes/$ID/system-logs/$FILE" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"

Responses: 200 System log file retrieved successfully · 400 Invalid log file name · 404 Node not found · 500 Failed to read system log · 501 Daemon feature unsupported

PATCH/api/admin/nodes/{id}

Auth: AdminPermission: admin.nodes.editRoute name: admin-nodes-updateController: NodesController::updateroute source

Update node Update an existing node. Only provided fields will be updated. Validates location existence and UUID format.

ParameterInTypeRequiredDescription
idpathintegeryesNode ID

Request body: NodeUpdate (application/json)

Body fieldTypeRequiredDescription
namestringnoNode name
fqdnstringnoFully qualified domain name
location_idintegernoLocation ID
uuidstringnoNode UUID (must be valid UUID format)
daemon_typestringnoDaemon implementation for this node
public_ip_v4stringnoPublic IPv4 address reachable by clients. Set this if you plan to use the subdomain manager.
public_ip_v6stringnoPublic IPv6 address reachable by clients.
sftp_subdomainstringnoOptional custom hostname for SFTP connections shown to users.
Response data fieldTypeDescription
nodeNode
curl -X PATCH "$PANEL_URL/api/admin/nodes/$ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name":"","fqdn":"","location_id":0,"uuid":"","daemon_type":"","public_ip_v4":"","public_ip_v6":"","sftp_subdomain":""}'

Plugin events: featherpanel:admin:nodes:node:updated

Responses: 200 Node updated successfully · 400 Bad request - Invalid JSON, no data provided, validation errors, location not found, or invalid UUID format · 401 Unauthorized · 403 Forbidden - Insufficient permissions · 404 Node not found · 500 Internal server error - Failed to update node

DELETE/api/admin/nodes/{id}

Auth: AdminPermission: admin.nodes.deleteRoute name: admin-nodes-deleteController: NodesController::deleteroute source

Delete node Permanently delete a node from the database. This action cannot be undone.

ParameterInTypeRequiredDescription
idpathintegeryesNode ID
Response data fieldTypeDescription
messagestringSuccess message
curl -X DELETE "$PANEL_URL/api/admin/nodes/$ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"

Plugin events: featherpanel:admin:nodes:node:deleted

Responses: 200 Node deleted successfully · 400 Bad request - Invalid node ID · 401 Unauthorized · 403 Forbidden - Insufficient permissions · 404 Node not found · 500 Internal server error - Failed to delete node

PUT/api/admin/nodes

Auth: AdminPermission: admin.nodes.createRoute name: admin-nodes-createController: NodesController::createroute source

Create new node Create a new node with name, FQDN, and location. Automatically generates UUID and daemon tokens. Validates location existence and ensures UUID uniqueness.

Request body: NodeCreate (application/json)

Body fieldTypeRequiredDescription
namestringyesNode name
fqdnstringyesFully qualified domain name
location_idintegeryesLocation ID
daemon_typestringnoDaemon implementation for this node
public_ip_v4stringnoPublic IPv4 address reachable by clients. Set this if you plan to use the subdomain manager.
public_ip_v6stringnoPublic IPv6 address reachable by clients.
sftp_subdomainstringnoOptional custom hostname for SFTP connections shown to users.
idintegernoOptional node ID (useful for migrations from other platforms)
Response data fieldTypeDescription
nodeNode
curl -X PUT "$PANEL_URL/api/admin/nodes" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name":"","fqdn":"","location_id":0,"daemon_type":"","public_ip_v4":"","public_ip_v6":"","sftp_subdomain":"","id":0}'

Plugin events: featherpanel:admin:nodes:node:created

Responses: 201 Node created successfully · 400 Bad request - Invalid JSON, validation errors, location not found, or UUID already exists · 401 Unauthorized · 403 Forbidden - Insufficient permissions · 500 Internal server error - Failed to create node

POST/api/admin/nodes/{id}/reset-key

Auth: AdminPermission: admin.nodes.editRoute name: admin-nodes-reset-keyController: NodesController::resetKeyroute source

Reset node daemon tokens Generate new daemon token ID and daemon token for a node. This invalidates the current tokens and requires the node to be reconfigured with the new tokens.

ParameterInTypeRequiredDescription
idpathintegeryesNode ID
Response data fieldTypeDescription
nodeNode
curl -X POST "$PANEL_URL/api/admin/nodes/$ID/reset-key" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"

Responses: 200 Node daemon tokens reset successfully · 400 Bad request - Invalid node ID · 401 Unauthorized · 403 Forbidden - Insufficient permissions · 404 Node not found · 500 Internal server error - Failed to reset node tokens

GET/api/admin/nodes/{id}/setup-command

Auth: AdminPermission: admin.nodes.editRoute name: admin-nodes-setup-commandController: NodesController::getSetupCommandroute source

Get node setup command Returns install command (step 1) and setup command (step 2) to configure the node. Step 1 installs FeatherWings only; step 2 runs the interactive featherwings configure wizard.

ParameterInTypeRequiredDescription
idpathintegeryesNode ID
Response data fieldTypeDescription
panel_urlstringPanel base URL
config_urlstringFull URL to fetch config (GET with Wings Bearer token)
install_commandstringStep 1: Install FeatherWings on the node (binary + Docker, no SSL)
setup_commandstringStep 2: Run featherwings configure (handles node join, SSL, and systemd)
config_path_hintstringSuggested config path on the node (e.g. /etc/featherpanel/config.yml)
curl -X GET "$PANEL_URL/api/admin/nodes/$ID/setup-command" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"

Responses: 200 Setup commands (install + config) · 401 Unauthorized · 403 Forbidden · 404 Node not found

POST/api/admin/nodes/{id}/self-update

Auth: AdminPermission: admin.nodes.editRoute name: admin-nodes-self-updateController: NodesController::triggerSelfUpdateroute source

Trigger Wings self-update Initiate a self-update on the Wings daemon either via GitHub release channel or a custom download URL.

ParameterInTypeRequiredDescription
idpathintegeryesNode ID
Body fieldTypeRequiredDescription
sourcestringnoUpdate source (e.g. github, url)
versionstringnoSpecific Wings version to install
urlstringnoDirect download URL for installing Wings
repo_ownerstringnoGitHub repository owner (when source=github)
repo_namestringnoGitHub repository name (when source=github)
sha256stringnoSHA256 checksum for validating download
forcebooleannoForce reinstall even if Wings is up-to-date
disable_checksumbooleannoSkip checksum validation of the downloaded artifact
curl -X POST "$PANEL_URL/api/admin/nodes/$ID/self-update" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"source":"","version":"","url":"","repo_owner":"","repo_name":"","sha256":"","force":false,"disable_checksum":false}'

Responses: 200 Self-update already applied or not required · 202 Self-update accepted and queued · 400 Bad request - Invalid payload or updates disabled · 401 Unauthorized · 403 Forbidden - Insufficient permissions or API updates disabled · 404 Node not found · 500 Failed to trigger self-update

POST/api/admin/nodes/{id}/terminal/exec

Auth: AdminPermission: admin.nodes.editRoute name: admin-nodes-terminal-execController: NodesController::executeTerminalCommandroute source

Execute command on node host Execute a command on the node host system via Wings terminal API. Requires system.host_terminal.enabled=true in Wings config.

ParameterInTypeRequiredDescription
idpathintegeryesNode ID
Body fieldTypeRequiredDescription
commandstringyesCommand to execute on the host
timeout_secondsintegernoTimeout in seconds (default: 60)
working_directorystringnoWorking directory for command execution
environmentobjectnoEnvironment variables for the command
Response data fieldTypeDescription
exit_codeintegerCommand exit code
stdoutstringStandard output
stderrstringStandard error
timed_outbooleanWhether command timed out
duration_msintegerExecution duration in milliseconds
curl -X POST "$PANEL_URL/api/admin/nodes/$ID/terminal/exec" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"command":"","timeout_seconds":0,"working_directory":"","environment":{}}'

Responses: 200 Command executed successfully · 400 Bad request - Invalid payload or missing command · 401 Unauthorized · 403 Forbidden - Insufficient permissions or host terminal disabled · 404 Node not found · 500 Internal server error - Failed to execute command · 504 Gateway Timeout - Command execution timed out

GET/api/admin/nodes/{id}/config

Auth: AdminPermission: admin.nodes.editRoute name: admin-nodes-config-getController: NodesController::getConfigroute source

Get Wings configuration Retrieve the complete Wings configuration file as raw YAML with all comments preserved.

ParameterInTypeRequiredDescription
idpathintegeryesNode ID
Response data fieldTypeDescription
configstringRaw YAML configuration content
curl -X GET "$PANEL_URL/api/admin/nodes/$ID/config" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"

Responses: 200 Wings configuration retrieved successfully · 401 Unauthorized · 403 Forbidden - Insufficient permissions · 404 Node not found · 500 Internal server error - Failed to retrieve configuration

PUT/api/admin/nodes/{id}/config

Auth: AdminPermission: admin.nodes.editRoute name: admin-nodes-config-putController: NodesController::putConfigroute source

Replace Wings configuration Replace the entire Wings configuration file with new YAML content. All comments and formatting are preserved. Optionally restart Wings after update.

ParameterInTypeRequiredDescription
idpathintegeryesNode ID
Body fieldTypeRequiredDescription
configstringyesComplete YAML configuration content
restartbooleannoWhether to restart Wings after update
Response data fieldTypeDescription
configstringUpdated YAML configuration content
curl -X PUT "$PANEL_URL/api/admin/nodes/$ID/config" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"config":"","restart":false}'

Responses: 200 Configuration updated successfully · 400 Bad request - Invalid JSON or missing config · 401 Unauthorized · 403 Forbidden - Insufficient permissions · 404 Node not found · 500 Internal server error - Failed to update configuration

PATCH/api/admin/nodes/{id}/config/patch

Auth: AdminPermission: admin.nodes.editRoute name: admin-nodes-config-patchController: NodesController::patchConfigroute source

Patch Wings configuration values Update specific configuration values using dot notation (e.g., "api.port", "system.root_directory"). Preserves comments and other values.

ParameterInTypeRequiredDescription
idpathintegeryesNode ID
Body fieldTypeRequiredDescription
valuesobjectyesConfiguration values to update using dot notation (e.g., {"api.port": 8443, "system.root_directory": "/var/lib/featherpanel"})
restartbooleannoWhether to restart Wings after update
Response data fieldTypeDescription
resultobjectPatch operation result
curl -X PATCH "$PANEL_URL/api/admin/nodes/$ID/config/patch" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"values":{},"restart":false}'

Responses: 200 Configuration patched successfully · 400 Bad request - Invalid JSON or missing values · 401 Unauthorized · 403 Forbidden - Insufficient permissions · 404 Node not found · 500 Internal server error - Failed to patch configuration

GET/api/admin/nodes/{id}/config/schema

Auth: AdminPermission: admin.nodes.viewRoute name: admin-nodes-config-schemaController: NodesController::getConfigSchemaroute source

Get Wings configuration schema Retrieve a schema describing all configurable fields in the Wings configuration, useful for building GUIs.

ParameterInTypeRequiredDescription
idpathintegeryesNode ID
Response data fieldTypeDescription
schemaobjectConfiguration schema
curl -X GET "$PANEL_URL/api/admin/nodes/$ID/config/schema" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"

Responses: 200 Configuration schema retrieved successfully · 401 Unauthorized · 403 Forbidden - Insufficient permissions · 404 Node not found · 500 Internal server error - Failed to retrieve schema

GET/api/admin/nodes/{id}/version-status

Auth: AdminPermission: admin.nodes.viewRoute name: admin-nodes-version-statusController: NodesController::getVersionStatusroute source

Check FeatherWings version status Check if the node's FeatherWings version matches the latest version available on GitHub. Compares the installed version with the latest release from mythicalltd/featherwings repository.

ParameterInTypeRequiredDescription
idpathintegeryesNode ID
Response data fieldTypeDescription
current_versionstringCurrently installed FeatherWings version
latest_versionstringLatest available version from GitHub
is_up_to_datebooleanWhether the installed version matches the latest
update_availablebooleanWhether an update is available
github_errorstringError message if GitHub check failed
curl -X GET "$PANEL_URL/api/admin/nodes/$ID/version-status" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"

Responses: 200 Version status retrieved successfully · 401 Unauthorized · 403 Forbidden - Insufficient permissions · 404 Node not found · 500 Internal server error - Failed to check version status

GET/api/admin/nodes/{id}/wings/config

Auth: AdminPermission: admin.nodes.editRoute name: admin-nodes-wings-config-getController: NodesController::getConfigroute source
ParameterInTypeRequiredDescription
idpath-yes
curl -X GET "$PANEL_URL/api/admin/nodes/$ID/wings/config" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"

PUT/api/admin/nodes/{id}/wings/config

Auth: AdminPermission: admin.nodes.editRoute name: admin-nodes-wings-config-putController: NodesController::putConfigroute source
ParameterInTypeRequiredDescription
idpath-yes
curl -X PUT "$PANEL_URL/api/admin/nodes/$ID/wings/config" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"

POST/api/admin/nodes/{id}/wings/config

Auth: AdminPermission: admin.nodes.editRoute name: admin-nodes-wings-config-putController: NodesController::putConfigroute source
ParameterInTypeRequiredDescription
idpath-yes
curl -X POST "$PANEL_URL/api/admin/nodes/$ID/wings/config" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"

GET/api/admin/nodes/{id}/mass-transfer/preview

Auth: AdminPermission: admin.servers.editRoute name: admin-nodes-mass-transfer-previewController: NodesController::previewMassTransferroute source

Preview mass server transfer from a node Lists transferable servers on the source node and free allocation capacity on a destination node.

ParameterInTypeRequiredDescription
idpathintegeryesSource node ID
destination_node_idqueryintegeryesDestination node ID
curl -X GET "$PANEL_URL/api/admin/nodes/$ID/mass-transfer/preview?destination_node_id=$DESTINATION_NODE_ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"

Responses: 200 Preview retrieved successfully · 400 Bad request · 404 Node not found

POST/api/admin/nodes/{id}/mass-transfer

Auth: AdminPermission: admin.servers.editRoute name: admin-nodes-mass-transferController: NodesController::massTransferroute source

Mass transfer servers from a node Transfer selected servers (or all transferable servers) from this node to another. Free allocations on the destination node are assigned automatically.

ParameterInTypeRequiredDescription
idpathintegeryesSource node ID
Body fieldTypeRequiredDescription
destination_node_idintegeryes
server_idsinteger[]noServer IDs to move (ignored when move_all is true)
move_allbooleannoMove every transferable server on this node
curl -X POST "$PANEL_URL/api/admin/nodes/$ID/mass-transfer" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"destination_node_id":0,"server_ids":[],"move_all":false}'

Responses: 200 Mass transfer processed · 400 Bad request · 404 Node not found