pterowraptyl
v0.3.2
Published
A TypeScript wrapper for the Pterodactyl API, providing a simple and type-safe interface for interacting with Pterodactyl servers.
Readme
Pterowraptyl
A TypeScript wrapper for the Pterodactyl API, providing a simple and type-safe interface for interacting with Pterodactyl servers.
⚠️ Development Status
- ✅ Application API - Fully implemented and ready for production use
- ⚠️ Client API - Limited implementation (only a few methods available - this part is currently discontinued/on hold)
Features
- 🔒 Type-safe - Full TypeScript support with comprehensive type definitions
- 🚀 Easy to use - Simple and intuitive API design
- 📦 Modular - Organized into logical modules for different API endpoints
- ⚡ Rate limiting - Built-in rate limit handling
- 🛡️ Error handling - Comprehensive error handling with custom error types
- 📚 Well documented - Complete API documentation
Installation
npm i pterowraptylQuick Start
import { Ptero, PteroClient, PteroApp } from 'pterowraptyl';
// Initialize clients
const client = new PteroClient(
process.env.PTERO_BASE_URL!,
process.env.PTERO_CLIENT_KEY!
);
const app = new PteroApp(
process.env.PTERO_BASE_URL!,
process.env.PTERO_APP_KEY!
);
// Create main Ptero instance
const ptero = new Ptero(client, app);
// Now you can use all modules!Table of Contents
- Installation
- Quick Start
- Configuration
- Rate Limiting
- Application API Modules
- Client API Modules
- Error Handling
- TypeScript Support
- NestJS Integration
Configuration
Basic Configuration
import { PteroClient, PteroApp } from 'pterowraptyl';
const client = new PteroClient(
'https://panel.example.com',
'ptlc_client_xxxxxxxxxxxxx'
);
const app = new PteroApp(
'https://panel.example.com',
'ptlc_app_xxxxxxxxxxxxx'
);Advanced Configuration with Rate Limiting
import { PteroClient, PteroApp } from 'pterowraptyl';
const client = new PteroClient(
'https://panel.example.com',
'ptlc_client_xxxxxxxxxxxxx',
{
enableAutoRetry: true, // Automatically retry on 429 errors (default: true)
maxRetries: 5, // Maximum retry attempts (default: 3)
baseDelay: 2000 // Base delay for exponential backoff in ms (default: 1000)
}
);
const app = new PteroApp(
'https://panel.example.com',
'ptlc_app_xxxxxxxxxxxxx',
{
enableAutoRetry: true,
maxRetries: 3,
baseDelay: 1500
}
);Rate Limiting
The library automatically handles rate limiting with configurable retry behavior.
Monitoring Rate Limits
import { Ptero, PteroClient, PteroApp } from 'pterowraptyl';
const client = new PteroClient(process.env.BASE_URL!, process.env.CLIENT_KEY!);
const app = new PteroApp(process.env.BASE_URL!, process.env.APP_KEY!);
const ptero = new Ptero(client, app);
// Check current rate limit status
const clientRateLimit = ptero.getClientRateLimit();
const appRateLimit = ptero.getAppRateLimit();
if (clientRateLimit) {
console.log(`Client API: ${clientRateLimit.remaining}/${clientRateLimit.limit} requests remaining`);
console.log(`Resets at: ${clientRateLimit.resetDate}`);
}
if (appRateLimit) {
console.log(`App API: ${appRateLimit.remaining}/${appRateLimit.limit} requests remaining`);
console.log(`Resets at: ${appRateLimit.resetDate}`);
}
// Check if approaching limits
if (ptero.isClientApproachingRateLimit()) {
console.warn("Warning: Client API is approaching rate limit!");
}
if (ptero.isAppApproachingRateLimit()) {
console.warn("Warning: Application API is approaching rate limit!");
}Advanced Rate Limit Handling
import { Ptero, PteroClient, PteroApp, RateLimitInfo } from 'pterowraptyl';
const client = new PteroClient(process.env.BASE_URL!, process.env.CLIENT_KEY!);
const ptero = new Ptero(client);
async function smartAPICall() {
// Check rate limit before making expensive operations
const rateLimit = ptero.getClientRateLimit();
if (rateLimit && rateLimit.remaining < 10) {
const timeUntilReset = rateLimit.resetDate.getTime() - Date.now();
console.log(`Low on API calls (${rateLimit.remaining} remaining)`);
console.log(`Waiting ${Math.ceil(timeUntilReset / 1000)}s until reset...`);
// Wait until rate limit resets
await new Promise(resolve => setTimeout(resolve, timeUntilReset + 1000));
}
// Now make the API call
const account = await ptero.accounts?.getAccount();
return account;
}Application API Modules
Servers Module
Complete server management including creation, updates, suspension, and deletion.
Fetch All Servers
// Get all servers
const servers = await ptero.servers?.fetchAll();
// With sorting
const servers = await ptero.servers?.fetchAll('id');
// With include parameters
const servers = await ptero.servers?.fetchAll(
'id',
['allocations', 'user', 'subusers', 'nest', 'egg']
);
// With filtering
const servers = await ptero.servers?.fetchAll(
'id',
[],
{ uuid: '30591422-fa31-4991-9265-28a30fb033c4' }
);
// With pagination
const servers = await ptero.servers?.fetchAll(
'id',
[],
{},
{ page: 1, per_page: 25 }
);Fetch One Server
// Get a single server by ID
const server = await ptero.servers?.fetchOne({ id: '1' });
// With include parameters
const server = await ptero.servers?.fetchOne(
{ id: '1' },
['allocations', 'user', 'subusers', 'nest', 'egg']
);
console.log(server.name);
console.log(server.limits.memory);
console.log(server.feature_limits.databases);Create Server
const newServer = await ptero.servers?.createServer({
name: "My New Server",
user: 1,
egg: 5,
docker_image: "quay.io/pterodactyl/core:java",
startup: "java -Xms128M -Xmx{{SERVER_MEMORY}}M -jar {{SERVER_JARFILE}}",
environment: {
MINECRAFT_VERSION: "latest",
SERVER_JARFILE: "server.jar",
BUILD_NUMBER: "recommended"
},
limits: {
memory: 1024,
swap: 0,
disk: 2048,
io: 500,
cpu: 100,
oom_disabled: false
},
feature_limits: {
databases: 2,
allocations: 1,
backups: 5,
splits: 0 // Optional
},
allocation: {
default: 1,
additional: [2, 3] // Optional additional allocations
},
deploy: { // Optional deployment configuration
locations: [1],
dedicated_ip: false,
port_range: ["25565-25570"]
}
});
console.log(`Server created: ${newServer.attributes.name}`);Update Server
// Update basic server information
const updatedServer = await ptero.servers?.updateServer({
id: 1,
user_id: 1,
name: "Updated Server Name",
description: "Updated description.",
external_id: "external-123" // Optional
});Update Server Build
// Update server build configuration
const updatedServer = await ptero.servers?.updateServerBuild({
id: 1,
allocation: 1,
memory: 2048,
swap: 0,
disk: 4096,
io: 500,
cpu: 200,
threads: "1,2", // Optional CPU thread pinning
feature_limits: {
databases: 5,
allocations: 2,
backups: 10,
splits: 0 // Optional
},
add_allocations: [4, 5], // Optional
remove_allocations: [2, 3], // Optional
oom_disabled: false // Optional
});Update Server Startup
// Update server startup configuration
const updatedServer = await ptero.servers?.updateServerStartup({
id: 1,
startup: "java -Xms128M -Xmx{{SERVER_MEMORY}}M -jar {{SERVER_JARFILE}}",
environment: {
MINECRAFT_VERSION: "1.19.4",
SERVER_JARFILE: "server.jar",
BUILD_TYPE: "recommended"
},
egg: 5,
image: "quay.io/pterodactyl/core:java", // Optional
skip_scripts: false // Optional
});Suspend/Unsuspend Server
// Suspend a server
const success = await ptero.servers?.suspendServer({ id: '1' });
console.log(success ? "Server suspended" : "Failed to suspend");
// Unsuspend a server
const success = await ptero.servers?.unsuspendServer({ id: '1' });
console.log(success ? "Server unsuspended" : "Failed to unsuspend");Reinstall Server
// Reinstall a server
const success = await ptero.servers?.reinstallServer({
id: 1,
force: true // Optional, force reinstall
});Delete Server
// Delete a server
const success = await ptero.servers?.deleteServer({ id: '1' });
console.log(success ? "Server deleted" : "Failed to delete");Users Module
Complete user management including creation, updates, and deletion.
Fetch All Users
// Get all users
const users = await ptero.users?.fetchAll();
// With sorting
const users = await ptero.users?.fetchAll('id');
// With include parameters
const users = await ptero.users?.fetchAll(
'id',
['servers']
);
// With filtering
const users = await ptero.users?.fetchAll(
'id',
['servers'],
{
uuid: '30591422-fa31-4991-9265-28a30fb033c4',
username: 'john_doe',
email: '[email protected]'
}
);
// With pagination
const users = await ptero.users?.fetchAll(
'id',
['servers'],
{},
{ page: 1, per_page: 25 }
);Fetch One User
// Get a single user by ID
const user = await ptero.users?.fetchOne({ id: 1 });
// With include parameters
const user = await ptero.users?.fetchOne(
{ id: 1 },
['servers']
);
console.log(user.username);
console.log(user.email);Create User
const newUser = await ptero.users?.createUser({
email: "[email protected]",
username: "newuser",
first_name: "John",
last_name: "Doe",
password: "secure_password_123",
external_id: "external-123" // Optional
});
console.log(`User created: ${newUser.username}`);Update User
const updatedUser = await ptero.users?.updateUser({
id: 1,
email: "[email protected]", // Optional
username: "updated_username", // Optional
first_name: "Jane", // Optional
last_name: "Smith", // Optional
password: "new_password", // Optional
external_id: "external-456" // Optional
});Delete User
const success = await ptero.users?.deleteUser({ id: 1 });
console.log(success ? "User deleted" : "Failed to delete");Nodes Module
Complete node management including creation, updates, configuration, and allocation management.
Fetch All Nodes
// Get all nodes
const nodes = await ptero.nodes?.fetchAll();
// With include parameters
const nodes = await ptero.nodes?.fetchAll(
['allocations', 'servers', 'location']
);
// With pagination
const nodes = await ptero.nodes?.fetchAll(
['allocations', 'servers', 'location'],
{ page: 1, per_page: 25 }
);Fetch One Node
// Get a single node by ID
const node = await ptero.nodes?.fetchOne({ id: 1 });
// With include parameters
const node = await ptero.nodes?.fetchOne(
{ id: 1 },
['allocations', 'servers', 'location']
);
console.log(node.name);
console.log(node.fqdn);
console.log(node.memory);Fetch Node Configuration
// Get node configuration
const config = await ptero.nodes?.fetchConfiguration({ id: 1 });
console.log(config.token);
console.log(config.listen);Create Node
const newNode = await ptero.nodes?.createNode({
name: "New Node",
location_id: 1,
fqdn: "node2.example.com",
scheme: "https",
memory: 10240,
memory_overallocate: 0,
disk: 50000,
disk_overallocate: 0,
upload_size: 100,
daemon_sftp: 2022,
daemon_listen: 8080,
behind_proxy: false, // Optional
maintenance_mode: false, // Optional
daemon_base: "/var/lib/pterodactyl/volumes" // Optional
});
console.log(`Node created: ${newNode.name}`);Update Node
const updatedNode = await ptero.nodes?.updateNode({
id: 2,
name: "Updated_Node",
location_id: 1,
fqdn: "node2.example.com",
scheme: "https",
memory: 10240,
memory_overallocate: 0,
disk: 50000,
disk_overallocate: 0,
daemon_sftp: 2022,
daemon_listen: 8080,
behind_proxy: false, // Optional
maintenance_mode: false, // Optional
daemon_base: "/var/lib/pterodactyl/volumes" // Optional
});Delete Node
const success = await ptero.nodes?.deleteNode({ id: 1 });
console.log(success ? "Node deleted" : "Failed to delete");Node Allocations
// Fetch all allocations for a node
const allocations = await ptero.nodes?.fetchAllocations(
{ id: 1 },
{ page: 1, per_page: 25 } // Optional pagination
);
// Create allocation
const created = await ptero.nodes?.createAllocation({
id: 1,
ip: "127.0.0.1",
port: ["8080", "8081", "8082"] // Array of ports
});
// Delete allocation
const deleted = await ptero.nodes?.deleteAllocation({
id: 1,
allocation_id: 123
});Locations Module
Complete location management including creation, updates, and deletion.
Fetch All Locations
// Get all locations
const locations = await ptero.locations?.fetchAll();
// With sorting
const locations = await ptero.locations?.fetchAll('id');
// With include parameters
const locations = await ptero.locations?.fetchAll(
'id',
['nodes', 'servers']
);
// With filtering
const locations = await ptero.locations?.fetchAll(
'id',
['nodes'],
{ short: 'us-east' }
);
// With pagination
const locations = await ptero.locations?.fetchAll(
'id',
['nodes'],
{},
{ page: 1, per_page: 25 }
);Fetch One Location
// Get a single location by ID
const location = await ptero.locations?.fetchOne({ id: 1 });
// With include parameters
const location = await ptero.locations?.fetchOne(
{ id: 1 },
['nodes', 'servers']
);
console.log(location.short);
console.log(location.long);Create Location
const newLocation = await ptero.locations?.createLocation({
short: "ap-south",
long: "Asia Pacific South"
});
console.log(`Location created: ${newLocation.attributes.short}`);Update Location
const updatedLocation = await ptero.locations?.updateLocation({
id: 3,
short: "apac-south",
long: "Asia Pacific South Region"
});Delete Location
// Note: Location can only be deleted if it has no associated nodes
const deleted = await ptero.locations?.deleteLocation({ id: 3 });
console.log(deleted); // trueNests Module
Nest management for organizing eggs.
Fetch All Nests
// Get all nests
const nests = await ptero.nests?.fetchAll();
// With include parameters
const nests = await ptero.nests?.fetchAll(
['eggs', 'servers']
);
// With pagination
const nests = await ptero.nests?.fetchAll(
['eggs'],
{ page: 1, per_page: 25 }
);Fetch One Nest
// Get a single nest by ID
const nest = await ptero.nests?.fetchOne({ id: 1 });
// With include parameters
const nest = await ptero.nests?.fetchOne(
{ id: 1 },
['eggs', 'servers']
);
console.log(nest.name);
console.log(nest.description);Eggs Module
Egg management within nests.
Fetch All Eggs
// Get all eggs in a nest
const eggs = await ptero.eggs?.fetchAll({ id: 1 });
// With include parameters
const eggs = await ptero.eggs?.fetchAll(
{ id: 1 },
['nest', 'servers', 'config', 'script', 'variables']
);
// With pagination
const eggs = await ptero.eggs?.fetchAll(
{ id: 1 },
['nest'],
{ page: 1, per_page: 25 }
);Fetch One Egg
// Get a single egg by nest ID and egg ID
const egg = await ptero.eggs?.fetchOne({ nestId: 1, eggId: 1 });
// With include parameters
const egg = await ptero.eggs?.fetchOne(
{ nestId: 1, eggId: 1 },
['nest', 'servers', 'config', 'script', 'variables']
);
console.log(egg.name);
console.log(egg.description);Client API Modules
Accounts Module
Account management for authenticated users (Client API).
Get Account
const account = await ptero.accounts?.getAccount();
console.log(account.username);
console.log(account.email);Two-Factor Authentication
// Get 2FA QR code data
const twoFa = await ptero.accounts?.getTwoFa();
console.log(twoFa.image_url_data); // Use this to generate QR code
// Enable 2FA
const tokens = await ptero.accounts?.enableTwoFa({
code: "123456", // Code from authenticator app
password: "user_password"
});
console.log("Recovery tokens:", tokens.tokens);
// Disable 2FA
const disabled = await ptero.accounts?.disableTwoFa({
password: "user_password"
});
console.log(disabled ? "2FA disabled" : "Failed to disable");Client Servers Module
Server management from client perspective (Client API).
Get Server
// Get server by identifier
const server = await ptero.clientServers?.getServer(
{ identifier: "server-identifier" },
['egg', 'subusers'] // Optional include parameters
);
console.log(server.attributes.name);
console.log(server.attributes.limits.memory);Get Server Websocket
// Get websocket connection details
const socket = await ptero.clientServers?.getWebsocket({
identifier: "server-identifier"
});
console.log(socket.token);
console.log(socket.socket);Get Server Usage
// Get server resource usage
const usage = await ptero.clientServers?.getUsage({
identifier: "server-identifier"
});
console.log(usage.resources.memory_bytes);
console.log(usage.resources.cpu_absolute);
console.log(usage.resources.disk_bytes);
console.log(usage.current_state);Error Handling
The library provides comprehensive error handling with custom error types.
import { PteroError } from 'pterowraptyl';
try {
const server = await ptero.servers?.fetchOne({ id: 999 });
} catch (error) {
if (error instanceof PteroError) {
console.error('Pterodactyl API Error:', error.message);
console.error('Status Code:', error.statusCode);
console.error('Response:', error.response);
} else {
console.error('Unexpected error:', error);
}
}TypeScript Support
This package is written in TypeScript and includes complete type definitions. No additional @types packages are needed.
All types are exported and can be imported:
import {
Server,
ServerAttributes,
CreateServerRequest,
UserAttributes,
NodeAttributes,
LocationAttributes,
// ... and many more
} from 'pterowraptyl';NestJS Integration
The library is fully compatible with NestJS. Here's how to use it:
Basic Service
import { Injectable } from '@nestjs/common';
import { Ptero, PteroClient, PteroApp } from 'pterowraptyl';
@Injectable()
export class PterodactylService {
private ptero: Ptero;
constructor() {
const client = new PteroClient(
process.env.PTERO_BASE_URL!,
process.env.PTERO_CLIENT_KEY!
);
const app = new PteroApp(
process.env.PTERO_BASE_URL!,
process.env.PTERO_APP_KEY!
);
this.ptero = new Ptero(client, app);
}
async getServers() {
return await this.ptero.servers?.fetchAll();
}
async createServer(data: CreateServerRequest) {
return await this.ptero.servers?.createServer(data);
}
}Using as Provider
// ptero.provider.ts
import { Provider } from '@nestjs/common';
import { Ptero, PteroClient, PteroApp } from 'pterowraptyl';
export const PTERO_PROVIDER = 'PTERO';
export const pteroProvider: Provider = {
provide: PTERO_PROVIDER,
useFactory: () => {
const client = new PteroClient(
process.env.PTERO_BASE_URL!,
process.env.PTERO_CLIENT_KEY!
);
const app = new PteroApp(
process.env.PTERO_BASE_URL!,
process.env.PTERO_APP_KEY!
);
return new Ptero(client, app);
},
};
// app.module.ts
import { Module } from '@nestjs/common';
import { pteroProvider } from './ptero.provider';
@Module({
providers: [pteroProvider],
exports: [pteroProvider],
})
export class AppModule {}API Modules Summary
✅ Application API Modules (Fully Implemented)
- 🖥️ Servers - Complete server management (create, update, delete, suspend, reinstall)
- 👥 Users - User management (create, update, delete, fetch)
- 🏗️ Nodes - Node management (create, update, delete, allocations)
- 🥚 Eggs - Egg management (fetch eggs within nests)
- 🏠 Nests - Nest management (fetch nests)
- 📍 Locations - Location management (create, update, delete)
- 🏷️ Allocations - Allocation management (via Nodes module)
⚠️ Client API Modules (Limited Implementation)
- 🌐 Client Servers - Basic server access (get server, websocket, usage)
- 👤 Account - Account management (get account, 2FA)
Note: The Client API implementation is incomplete and currently discontinued. We recommend using the Application API for full functionality.
Documentation
Complete API documentation is automatically generated from the source code.
You can find it here:
- 🌎 Docs: Documentation
Support
- 📧 Email: [email protected]
- 🐛 Issues: GitHub Issues
Development
Prerequisites
- Node.js 16 or higher
- npm or yarn
Setup
# Clone the repository
git clone https://github.com/GlydeByte/ptero-wrapper.git
cd ptero-wrapper
# Install dependencies
npm install
# Build the project
npm run build
# Run dev mode
npm run devBuilding
The project supports multiple output formats:
- CommonJS -
npm run build:cjs - ES Modules -
npm run build:esm - Both -
npm run build
Project Structure
src/
├── core/ # Core client functionality
├── modules/ # API endpoint modules
├── types/ # TypeScript type definitions
├── utils/ # Utility functions
└── index.ts # Main entry pointContributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
License
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.
Acknowledgments
- Pterodactyl Panel - The game server management panel this wrapper interfaces with
- Axios - HTTP client library used for API requests
Made with ❤️ by Jakub30cz
