-
Notifications
You must be signed in to change notification settings - Fork 0
API Reference Public API Endpoints Availability Endpoints
**Referenced Files in This Document** - [routes/api.php](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/routes/api.php) - [AvailabilityController.php](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/Http/Controllers/Api/AvailabilityController.php) - [NodeSelectionService.php](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/Services/NodeSelectionService.php) - [ResourceCalculationService.php](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/Services/ResourceCalculationService.php) - [EnsureUserIsAdmin.php](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/Http/Middleware/EnsureUserIsAdmin.php) - [AvailabilityApiTest.php](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/tests/Feature/AvailabilityApiTest.php) - [DECISIONS.md](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/DECISIONS.md)Preserved Qoder snapshot. This deep-dive page is retained so the earlier Wiki work and its source trail are not lost. For the reconciled implementation, Architecture Overview is canonical; references below to retired controllers, listeners, services, or API shapes are historical.
Changes Made
- Enhanced security section with new test assertions for preventing node-level data exposure
- Updated endpoint specification to emphasize security boundaries
- Added comprehensive security testing coverage details
- Strengthened error handling documentation with security considerations
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Security and Data Exposure Prevention
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
This document specifies the customer-facing availability endpoint that returns aggregate, location-based capacity data for Pterodactyl nodes. It covers authentication, rate limiting, request/response schemas, error handling, performance characteristics, and comprehensive security measures designed to prevent node-level data exposure to customers. The endpoint is designed to answer "what can I get at this location right now?" without exposing node-level internals to customers.
The availability feature spans routes, a controller, and services that call the Pterodactyl API in real time. Customer endpoints are grouped under a single route prefix with shared middleware for session-based authentication and throttling. Security measures ensure that only aggregate data is returned to customers while detailed node information remains admin-only.
graph TB
Client["Customer Client"] --> Routes["API Routes<br/>/api/dynamic-pterodactyl"]
Routes --> MW["Middleware: web, auth, throttle:30,1"]
MW --> Ctrl["AvailabilityController::getByLocation"]
Ctrl --> ResCalc["ResourceCalculationService::getLocationAvailability"]
Ctrl --> NodeSel["NodeSelectionService::getMaxAvailable with preloaded snapshot"]
ResCalc --> Ptero["Pterodactyl API"]
Ctrl --> Security["Security Layer<br/>Data Sanitization"]
Security --> Response["Secure JSON Response<br/>No Node Details"]
Diagram sources
- routes/api.php:17-22
- AvailabilityController.php:22-52
- NodeSelectionService.php:78-97
- ResourceCalculationService.php:23-67
Section sources
- Route group: Defines the public availability endpoint and applies session-based authentication and rate limiting.
- Controller: Orchestrates aggregation and returns a simplified response to customers with built-in security sanitization.
- Services:
- NodeSelectionService: Computes maximum allocatable resources across a location.
- ResourceCalculationService: Fetches live node/server data from Pterodactyl and aggregates totals and per-node details (used internally and by admin).
Key responsibilities:
- Enforce authentication via web session and auth middleware.
- Throttle requests to protect downstream Pterodactyl API budget.
- Aggregate per-location maxima for memory, CPU, and disk.
- Provide a boolean flag indicating whether all three resources have positive availability.
- Enhanced: Ensure no node-level data leaks to customer responses through comprehensive testing and validation.
Section sources
- routes/api.php:17-22
- AvailabilityController.php:22-52
- NodeSelectionService.php:78-97
- ResourceCalculationService.php:23-67
The GET /api/dynamic-pterodactyl/availability/{locationId} flow:
- Request enters the route group with web + auth + throttle middleware.
- AvailabilityController::getByLocation fetches one location snapshot via ResourceCalculationService.
- It passes that same snapshot to NodeSelectionService to read max_available, then computes node_count and resource_capacity booleans without another panel request.
- A compact JSON response is returned with only aggregate fields; no node identifiers or internal details are exposed.
- Enhanced: Comprehensive test coverage ensures security boundaries are maintained.
sequenceDiagram
participant C as "Client"
participant R as "Routes"
participant M as "Auth + Throttle"
participant A as "AvailabilityController"
participant N as "NodeSelectionService"
participant S as "ResourceCalculationService"
participant P as "Pterodactyl API"
C->>R : GET /api/dynamic-pterodactyl/availability/{locationId}
R->>M : Apply web, auth, throttle : 30,1
M-->>A : Proceed if authenticated and within limit
A->>S : getLocationAvailability(locationId)
S->>P : GET /locations/{id}?include=nodes,servers
P-->>S : Node and server data
S-->>A : Aggregated location data including nodes[]
A->>N : getMaxAvailable(locationId, locationData)
N-->>A : Max available from the same snapshot
A->>A : Security sanitization<br/>Remove node details
A-->>C : {success, data : {location_id, max_memory, max_cpu, max_disk, node_count, has_capacity, resource_capacity}}
Diagram sources
- routes/api.php:17-22
- AvailabilityController.php:22-52
- NodeSelectionService.php:78-97
- ResourceCalculationService.php:23-67
- Path parameter:
- locationId: integer. Identifies the target Pterodactyl location.
- Authentication:
- Requires an active web session and authenticated user via the web and auth middleware applied to the route group.
- Rate limiting:
- 30 requests per minute per client identity enforced by the throttle middleware on the route group.
- Success response schema:
- success: boolean
- data: object
- location_id: integer
- max_memory: integer (maximum allocatable memory across nodes in the location)
- max_cpu: integer (maximum allocatable CPU threads across nodes in the location)
- max_disk: integer (maximum allocatable disk MB across nodes in the location)
- node_count: integer (number of nodes in the location)
- has_capacity: boolean (true only when memory, cpu, and disk are all > 0)
- resource_capacity: object
- memory: boolean (true if max_memory > 0)
- cpu: boolean (true if max_cpu > 0)
- disk: boolean (true if max_disk > 0)
- Error responses:
- On exceptions during processing, returns HTTP 500 with
success: falseand the generic messageFailed to fetch availability. Exception details are reported server-side and are not returned to customers.
- On exceptions during processing, returns HTTP 500 with
Request examples
- Basic request:
- GET /api/dynamic-pterodactyl/availability/1
- Headers: Cookie (session), Authorization not required (uses session)
- Example success response:
- { "success": true, "data": { "location_id": 1, "max_memory": 16384, "max_cpu": 400, "max_disk": 102400, "node_count": 3, "has_capacity": true, "resource_capacity": { "memory": true, "cpu": true, "disk": true } } }
- Example partial capacity response:
- { "success": true, "data": { "location_id": 1, "max_memory": 16384, "max_cpu": 0, "max_disk": 102400, "node_count": 3, "has_capacity": false, "resource_capacity": { "memory": true, "cpu": false, "disk": true } } }
Error handling
- Invalid or missing locationId:
- If the location does not exist or cannot be resolved, the controller returns
success: falsewith a generic message and reports the underlying exception server-side.
- If the location does not exist or cannot be resolved, the controller returns
- Pterodactyl API failures:
- Network timeouts, connection errors, or non-2xx responses result in a generic
success: falseresponse; upstream details remain in server-side diagnostics.
- Network timeouts, connection errors, or non-2xx responses result in a generic
- Rate limiting exceeded:
- Requests beyond 30 per minute receive a standard throttle response from the framework's throttle middleware.
Why node-level details are not exposed
- Customer-facing endpoints intentionally return only aggregate per-location maxima and counts. Node names, FQDNs, maintenance flags, and per-node capacities are reserved for admin-only access. This reduces information leakage and keeps the customer experience focused on "can I buy here?" rather than infrastructure specifics.
- Enhanced Security: Comprehensive test coverage ensures that node-level data never leaks to customer responses through automated assertions.
Section sources
- NodeSelectionService::getMaxAvailable
- Delegates to ResourceCalculationService to obtain location availability and extracts the maximum allocatable values across nodes.
- ResourceCalculationService::getLocationAvailability
- Fetches nodes in the specified location and their servers from Pterodactyl.
- Computes effective capacity per node using overallocation settings and subtracts allocated and pending reservations.
- Tracks max_available (per-resource maximum across nodes) and total_capacity/total_allocated aggregates.
- Returns both per-node details (for internal/admin use) and aggregated metrics.
flowchart TD
Start(["getLocationAvailability(locationId)"]) --> FetchNodes["Fetch location with nodes and servers"]
FetchNodes --> ForEachNode{"For each node"}
ForEachNode --> |Yes| CalcNode["Calculate node availability<br/>from servers + reservations"]
CalcNode --> UpdateMax["Update max_available per resource"]
UpdateMax --> UpdateTotals["Accumulate total_capacity and total_allocated"]
UpdateTotals --> ForEachNode
ForEachNode --> |No| ReturnData["Return {location_id, nodes[], max_available, totals}"]
Diagram sources
Section sources
- NodeSelectionService.php:78-97
- ResourceCalculationService.php:23-67
- ResourceCalculationService.php:227-257
- Web session and authentication:
- The route group applies web and auth middleware, ensuring the caller has an active session and is authenticated.
- Admin-only node detail endpoint:
- The /availability/{locationId}/nodes endpoint is protected by additional admin middleware and is not part of the customer surface.
- Throttling:
- Availability endpoints are limited to 30 requests per minute to protect the Pterodactyl API budget.
Section sources
The system implements comprehensive security measures to prevent node-level data exposure in customer responses:
- Automated Assertions: Tests explicitly verify that the 'nodes' key is never present in customer-facing availability responses
- Security Validation: Both positive and negative capacity scenarios include assertions to ensure data isolation
- Mock Testing: Service mocks simulate realistic scenarios while maintaining security boundaries
- Response Sanitization: Customer endpoints return only aggregate data (max_memory, max_cpu, max_disk, node_count)
- Admin Isolation: Detailed node information is exclusively available through admin-only endpoints with proper authorization
- Data Minimization: Even when internal services process node-level data, it is never exposed to customer responses
The test suite includes comprehensive security validation:
- Verifies absence of 'nodes' key in customer responses
- Tests both capacity-available and capacity-exhausted scenarios
- Ensures consistent security behavior across different resource states
flowchart TD
CustomerReq["Customer Request"] --> AuthCheck["Authentication Check"]
AuthCheck --> SecurityLayer["Security Layer"]
SecurityLayer --> DataAggregation["Aggregate Data Only"]
DataAggregation --> SecurityValidation["Security Validation<br/>(No node details)"]
SecurityValidation --> TestCoverage["Automated Test Coverage"]
TestCoverage --> SecureResponse["Secure Response<br/>(Aggregate only)"]
Diagram sources
Section sources
classDiagram
class AvailabilityController {
+getByLocation(locationId) JsonResponse
+getNodes(locationId) JsonResponse
}
class NodeSelectionService {
+selectBestNode(locationId, requirements) ?array
+getMaxAvailable(locationId) array
}
class ResourceCalculationService {
+getLocationAvailability(locationId, excludeReservationToken) array
+buildClusterSnapshot() array
+verifyAvailability(nodeId, requirements, excludeReservationToken) bool
+testConnection() array
+getLocations() array
}
class AvailabilityApiTest {
+test_has_capacity_false_when_cpu_exhausted_but_memory_positive() void
+test_has_capacity_true_when_all_resources_positive() void
+bindAvailabilityServices(maxAvailable) void
}
AvailabilityController --> NodeSelectionService : "uses"
AvailabilityController --> ResourceCalculationService : "uses"
NodeSelectionService --> ResourceCalculationService : "delegates"
AvailabilityApiTest --> NodeSelectionService : "mocks"
AvailabilityApiTest --> ResourceCalculationService : "mocks"
Diagram sources
- AvailabilityController.php:9-20
- NodeSelectionService.php:5-12
- ResourceCalculationService.php:10-21
- AvailabilityApiTest.php:12-100
Section sources
- AvailabilityController.php:9-20
- NodeSelectionService.php:5-12
- ResourceCalculationService.php:10-21
- AvailabilityApiTest.php:12-100
- Real-time data fetching:
- Availability is computed by calling the Pterodactyl API on each request. There is no caching of availability results to avoid staleness and overselling risks.
- Batched API calls:
- The service batches node and server queries where possible and paginates large result sets to minimize round-trips while still reflecting current state.
- Timeouts and retries:
- Per-attempt timeouts and connect timeouts are set for Pterodactyl API calls. Connection errors trigger retries; non-retryable errors are reported and surfaced as exceptions.
- Throttling:
- 30 req/min protects against excessive load on the Pterodactyl API and mitigates abuse.
- Database reads:
- Pending reservations are summed per node to adjust available capacity accurately at query time.
- Enhanced: Security validation adds minimal overhead through automated testing but ensures long-term security posture without runtime performance impact.
Common issues and how they manifest:
- Authentication failure:
- Missing or invalid session will be rejected by the auth middleware before reaching the controller.
- Rate limiting:
- Exceeding 30 requests per minute triggers a throttle response; reduce polling frequency or implement backoff.
- Invalid location:
- If the locationId does not resolve to any nodes, the service may return empty aggregates; the controller wraps errors into a consistent failure response.
- Pterodactyl API errors:
- Network timeouts, connection failures, or non-2xx responses are caught, reported server-side, and returned as
success: falsewith only the generic availability failure message.
- Network timeouts, connection failures, or non-2xx responses are caught, reported server-side, and returned as
- Unexpected payload:
- Malformed or non-JSON responses from Pterodactyl are treated as errors and logged for diagnostics.
-
Enhanced: Security validation failures:
- If tests detect node-level data exposure, investigate the response structure and ensure proper sanitization in the controller layer.
Verification tips
- Confirm you are authenticated via a valid session cookie.
- Ensure your client respects the throttle limits and implements exponential backoff.
- Validate that the locationId exists in your Pterodactyl instance.
- Enhanced: Run security tests to verify no node-level data exposure in responses.
Section sources
- AvailabilityController.php:45-51
- ResourceCalculationService.php:452-498
- AvailabilityApiTest.php:48-49
- AvailabilityApiTest.php:77-78
The GET /api/dynamic-pterodactyl/availability/{locationId} endpoint provides a secure, rate-limited, and real-time view of aggregate capacity for a given location. It exposes only what customers need to make purchasing decisions—maximum allocatable memory, CPU, and disk, along with a simple capacity indicator—while keeping node-level internals private.
Enhanced Security: The system now includes comprehensive automated testing to ensure that node-level data never leaks to customer responses. These security measures provide confidence that the data boundary between customer and admin interfaces remains intact, protecting sensitive infrastructure information while delivering accurate capacity information to customers.
Errors are handled consistently, performance is optimized through batched API calls and careful timeout/retry policies, and security is enforced through both architectural design and comprehensive test coverage.
DynamicPterodactyl · Dynamic Resource Sliders for Paymenter × Pterodactyl · Reviewed code checkpoint · Publication commits intentionally pin their latest code-bearing predecessor because a Git commit cannot self-reference its unknown object ID.
DynamicPterodactyl
Guides
Architecture
- Architecture Overview
Core Services
API Reference
Database
System