npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

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 pterowraptyl

Quick 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

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); // true

Nests 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:

Support

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 dev

Building

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 point

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. 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