Skip to main content

Introduction

The Pterodactyl Wings API is a RESTful HTTP API built with Go and the Gin framework. It provides programmatic access to server management, file operations, backups, and real-time communication via WebSockets.
All API requests to Wings originate from the Pterodactyl Panel backend. Direct client access is not supported for most endpoints.

Base URL

The API is accessible at:
http://<wings-host>:<port>/api
Default configuration:
  • Host: 0.0.0.0
  • Port: 8080 (configurable in config.yml)
  • SSL: Optional (configured via api.ssl in config)

API Architecture

Endpoint Structure

Wings organizes endpoints into logical groups:

System Endpoints

POST   /api/update              Update Wings configuration
GET    /api/system              Get system information
GET    /api/servers             List all servers
POST   /api/servers             Create new server
POST   /api/deauthorize-user    Revoke user WebSocket access

Server Management

GET    /api/servers/:server                 Get server details
DELETE /api/servers/:server                 Delete server
GET    /api/servers/:server/logs            Get server logs
POST   /api/servers/:server/power           Control power state
POST   /api/servers/:server/commands        Send console commands
POST   /api/servers/:server/install         Trigger installation
POST   /api/servers/:server/reinstall       Reinstall server
POST   /api/servers/:server/sync            Sync with Panel
POST   /api/servers/:server/ws/deny         Deny WebSocket tokens

File Management

GET    /api/servers/:server/files/contents           Read file contents
GET    /api/servers/:server/files/list-directory     List directory
PUT    /api/servers/:server/files/rename             Rename/move files
POST   /api/servers/:server/files/copy               Copy file
POST   /api/servers/:server/files/write              Write file
POST   /api/servers/:server/files/create-directory   Create directory
POST   /api/servers/:server/files/delete             Delete files
POST   /api/servers/:server/files/compress           Compress files
POST   /api/servers/:server/files/decompress         Decompress archive
POST   /api/servers/:server/files/chmod              Change permissions

Remote Downloads

Remote download endpoints require api.disable_remote_download to be false in the Wings configuration.
GET    /api/servers/:server/files/pull          Get download status
POST   /api/servers/:server/files/pull          Start remote download
DELETE /api/servers/:server/files/pull/:download  Cancel download

Backup Management

POST   /api/servers/:server/backup                Create backup
POST   /api/servers/:server/backup/:backup/restore Restore backup
DELETE /api/servers/:server/backup/:backup        Delete backup

Signed URL Endpoints

These endpoints use JWT tokens instead of Bearer authentication:
GET    /download/backup        Download backup (JWT)
GET    /download/file          Download file (JWT)
POST   /upload/file            Upload files (JWT)
GET    /api/servers/:server/ws WebSocket connection (JWT)

Server Transfers

POST   /api/transfers                     Receive incoming transfer
POST   /api/servers/:server/transfer      Initiate outgoing transfer
DELETE /api/servers/:server/transfer      Cancel outgoing transfer
DELETE /api/transfers/:server             Cancel incoming transfer

Response Formats

Success Responses

All successful responses return JSON with appropriate HTTP status codes:
HTTP 200
OK
Request completed successfully with data returned.
{
  "data": [...],
  "attribute": "value"
}
HTTP 202
Accepted
Request accepted for background processing.
// No body - used for async operations like power actions
HTTP 204
No Content
Request completed successfully with no data to return.
// No response body

Error Responses

All errors include a unique request ID for troubleshooting:
{
  "error": "Error message describing what went wrong",
  "request_id": "550e8400-e29b-41d4-a716-446655440000"
}

Common Error Codes

400
Bad Request
Invalid request data or parameters.
{
  "error": "The data passed in the request was not in a parsable format. Please try again.",
  "request_id": "550e8400-e29b-41d4-a716-446655440000"
}
401
Unauthorized
Missing or invalid authentication headers.
{
  "error": "The required authorization heads were not present in the request.",
  "request_id": "550e8400-e29b-41d4-a716-446655440000"
}
403
Forbidden
Authentication provided but insufficient permissions.
{
  "error": "You are not authorized to access this endpoint.",
  "request_id": "550e8400-e29b-41d4-a716-446655440000"
}
404
Not Found
Requested resource does not exist.
{
  "error": "The requested resource does not exist on this instance.",
  "request_id": "550e8400-e29b-41d4-a716-446655440000"
}
422
Unprocessable Entity
Validation failed on request data.
{
  "error": "The data provided in the request could not be validated."
}
500
Internal Server Error
Unexpected server error occurred.
{
  "error": "An unexpected error was encountered while processing this request",
  "request_id": "550e8400-e29b-41d4-a716-446655440000"
}
502
Bad Gateway
Server is in invalid state for operation.
{
  "error": "Cannot send commands to a stopped server instance.",
  "request_id": "550e8400-e29b-41d4-a716-446655440000"
}
504
Gateway Timeout
Request took too long to process.
{
  "error": "The server could not process this request in time, please try again.",
  "request_id": "550e8400-e29b-41d4-a716-446655440000"
}

Filesystem-Specific Errors

File operation endpoints may return specialized error messages:
// File not found
{
  "error": "The requested resources was not found on the system.",
  "request_id": "..."
}

// File is denylisted
{
  "error": "This file cannot be modified: present in egg denylist.",
  "request_id": "..."
}

// Target is directory
{
  "error": "Cannot perform that action: file is a directory.",
  "request_id": "..."
}

// Insufficient disk space
{
  "error": "There is not enough disk space available to perform that action.",
  "request_id": "..."
}

// Filename too long
{
  "error": "Cannot perform that action: file name is too long.",
  "request_id": "..."
}

Rate Limiting

WebSocket Rate Limits

WebSocket connections enforce multiple rate limits:

Upload Limits

Request Tracking

All API responses include a unique request identifier in the X-Request-Id header:
X-Request-Id: 550e8400-e29b-41d4-a716-446655440000
This ID is:
  • Automatically generated for each request
  • Included in error responses
  • Logged for debugging purposes
  • Useful for correlating Panel and Wings logs

CORS Configuration

Wings sets the following CORS headers:
Access-Control-Allow-Origin: <panel-location>
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Accept, Accept-Encoding, Authorization, Cache-Control, Content-Type, Content-Length, Origin, X-Real-IP, X-CSRF-Token
Access-Control-Max-Age: 7200
The Access-Control-Allow-Origin header is dynamically set based on the panel_location and allowed_origins configuration options.

Private Network Access

When allow_cors_private_network is enabled:
Access-Control-Request-Private-Network: true
This allows CORS requests from private networks (RFC1918) in Chromium-based browsers.

Trusted Proxies

Wings can be configured to trust specific proxy IP addresses for client IP resolution:
api:
  trusted_proxies:
    - 127.0.0.1
    - 172.16.0.0/12
When properly configured, Wings will use X-Forwarded-For headers from trusted proxies to identify the true client IP address.

Build docs developers (and LLMs) love