Skip to content

Instantly share code, notes, and snippets.

@ollieread
Created February 24, 2026 14:42
Show Gist options
  • Select an option

  • Save ollieread/17459bcd4e7a20c198e5f1de014a05f0 to your computer and use it in GitHub Desktop.

Select an option

Save ollieread/17459bcd4e7a20c198e5f1de014a05f0 to your computer and use it in GitHub Desktop.
Backwards engineered JSON schema for the Pterodactyl egg format
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ollieread.com/schemas/egg/config-files.schema.json",
"title": "Egg Config Files",
"description": "Schema for the parsed content of the 'config.files' field. This is the structure that exists after decoding the stringified JSON. Each key is a file path relative to the server root, and the value defines how Wings should modify that file.",
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/config_file_entry"
},
"$defs": {
"config_file_entry": {
"type": "object",
"required": ["parser", "find"],
"additionalProperties": false,
"properties": {
"parser": {
"type": "string",
"enum": ["properties", "yaml", "json", "ini", "xml", "file"],
"description": "The parser Wings uses to read and modify this file. 'properties' = Java .properties format. 'yaml' = YAML. 'json' = JSON (supports dot-notation keys). 'ini' = INI format. 'xml' = XML. 'file' = raw regex-based find/replace."
},
"find": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Key-value pairs where the key is the config property to find (format depends on parser) and the value is the replacement. Values may use {{server.build.*}} placeholders (e.g. '{{server.build.default.port}}', '{{server.build.env.VARIABLE}}')."
}
}
}
}
}
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ollieread.com/schemas/egg/config-logs.schema.json",
"title": "Egg Config Logs",
"description": "Schema for the parsed content of the 'config.logs' field. This is the structure that exists after decoding the stringified JSON. It defines custom log file locations for the server.",
"type": "object",
"additionalProperties": false,
"properties": {
"custom": {
"type": "boolean",
"description": "Whether this egg uses a custom log file location rather than relying on console output capture.",
"default": false
},
"location": {
"type": "string",
"description": "The path to the log file, relative to the server root directory (e.g. 'logs/latest.log')."
}
}
}
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ollieread.com/schemas/egg/config-startup.schema.json",
"title": "Egg Config Startup",
"description": "Schema for the parsed content of the 'config.startup' field. This is the structure that exists after decoding the stringified JSON. It defines how Wings detects that a server has finished starting.",
"type": "object",
"required": ["done"],
"additionalProperties": false,
"properties": {
"done": {
"oneOf": [
{
"type": "string",
"description": "A string or regex pattern that Wings watches for in the server's console output to determine the server has started successfully (e.g. ')! For help, type \"help\"')."
},
{
"type": "array",
"items": {
"type": "string"
},
"description": "An array of patterns, any of which will signal that the server has started."
}
]
},
"userInteraction": {
"type": "array",
"items": {
"type": "string"
},
"description": "Patterns in the console output that indicate the server requires user interaction (e.g. EULA acceptance prompts). When detected, Wings can notify the panel."
},
"strip_ansi": {
"type": "boolean",
"description": "Whether to strip ANSI escape codes from the console output before pattern matching.",
"default": false
}
}
}
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ollieread.com/schemas/egg/ptdl.schema.json",
"title": "Pterodactyl Egg Export",
"description": "Combined schema that validates either PTDL_v1 or PTDL_v2 egg export format. Version is determined by the 'meta.version' field.",
"oneOf": [
{ "$ref": "ptdl_v1.schema.json" },
{ "$ref": "ptdl_v2.schema.json" }
]
}
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ollieread.com/schemas/egg/ptdl_v1.schema.json",
"title": "Pterodactyl Egg Export — PTDL_v1",
"description": "Schema for the legacy PTDL_v1 egg export format used by Pterodactyl Panel. This format uses 'image' (string) or 'images' (array) for Docker image definitions and does not include 'field_type' on variables.",
"type": "object",
"required": [
"meta",
"name",
"author",
"startup",
"config",
"scripts",
"variables"
],
"additionalProperties": false,
"properties": {
"_comment": {
"type": "string",
"description": "Auto-generated comment from the Pterodactyl Panel export process."
},
"meta": {
"$ref": "#/$defs/meta"
},
"exported_at": {
"type": "string",
"format": "date-time",
"description": "ISO 8601 timestamp of when the egg was exported."
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 191,
"description": "The display name of the egg."
},
"author": {
"type": "string",
"format": "email",
"description": "The email address of the egg author."
},
"description": {
"type": ["string", "null"],
"description": "A human-readable description of what this egg provides."
},
"features": {
"oneOf": [
{
"type": "array",
"items": {
"type": "string"
},
"description": "Feature flags that enable specific frontend functionality (e.g. 'eula', 'java_version', 'pid_limit')."
},
{
"type": "null"
}
]
},
"image": {
"type": "string",
"description": "A single Docker image string. Mutually exclusive with 'images'. At least one of 'image' or 'images' must be present."
},
"images": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"description": "An array of Docker image strings. Mutually exclusive with 'image'. At least one of 'image' or 'images' must be present."
},
"file_denylist": {
"type": "array",
"items": {
"type": "string"
},
"description": "List of file patterns that should be blocked from access. Rarely present in v1 exports but technically possible."
},
"startup": {
"type": "string",
"description": "The startup command template. Supports {{VARIABLE}} placeholders for environment variable interpolation and {{SERVER_MEMORY}} / {{SERVER_IP}} for built-in server values."
},
"config": {
"$ref": "#/$defs/config"
},
"scripts": {
"$ref": "#/$defs/scripts"
},
"variables": {
"type": "array",
"items": {
"$ref": "#/$defs/variable_v1"
},
"description": "Environment variables that can be configured for servers using this egg."
}
},
"anyOf": [
{ "required": ["image"] },
{ "required": ["images"] }
],
"$defs": {
"meta": {
"type": "object",
"required": ["version"],
"additionalProperties": false,
"properties": {
"version": {
"type": "string",
"const": "PTDL_v1",
"description": "The export format version identifier."
},
"update_url": {
"type": ["string", "null"],
"description": "An optional URL that the panel can use to check for egg updates."
}
}
},
"config": {
"type": "object",
"required": ["files", "startup", "logs", "stop"],
"additionalProperties": false,
"description": "Server process configuration. The 'files', 'startup', and 'logs' fields contain stringified JSON that the panel stores as-is and passes to Wings for processing.",
"properties": {
"files": {
"type": "string",
"description": "Stringified JSON defining configuration file modifications. When parsed, yields an object keyed by file path, each containing a 'parser' (e.g. 'properties', 'yaml', 'json', 'ini', 'xml') and a 'find' object mapping config keys to replacement values. Values may use {{server.build.*}} placeholders."
},
"startup": {
"type": "string",
"description": "Stringified JSON defining startup detection. When parsed, yields an object with 'done' (regex/string pattern indicating the server has started) and optionally 'userInteraction' (array of patterns requiring user input)."
},
"logs": {
"type": "string",
"description": "Stringified JSON defining log configuration. When parsed, yields an object optionally containing 'custom' (boolean) and 'location' (string path to log file)."
},
"stop": {
"type": "string",
"description": "The stop command or signal sent to gracefully stop the server process. Common values: 'stop', 'quit', 'end', '^C' (SIGINT), '^^' (SIGTERM). A plain string is a console command; caret-prefixed values are signals."
}
}
},
"scripts": {
"type": "object",
"required": ["installation"],
"additionalProperties": false,
"properties": {
"installation": {
"$ref": "#/$defs/installation_script"
}
}
},
"installation_script": {
"type": "object",
"required": ["container", "entrypoint"],
"additionalProperties": false,
"properties": {
"script": {
"type": ["string", "null"],
"description": "The shell script content that runs during server installation. Executed inside the installation container with the server directory mounted at /mnt/server."
},
"container": {
"type": "string",
"description": "The Docker image used to run the installation script (e.g. 'ghcr.io/pterodactyl/installers:alpine', 'alpine:3.9')."
},
"entrypoint": {
"type": "string",
"description": "The shell entrypoint for the installation script (e.g. 'ash', 'bash')."
}
}
},
"variable_v1": {
"type": "object",
"required": [
"name",
"description",
"env_variable",
"default_value",
"user_viewable",
"user_editable",
"rules"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"description": "The human-readable display name for this variable."
},
"description": {
"type": "string",
"description": "A description explaining the purpose of this variable and any constraints."
},
"env_variable": {
"type": "string",
"pattern": "^[A-Za-z_][A-Za-z0-9_]*$",
"description": "The environment variable name injected into the server container (e.g. 'SERVER_JARFILE', 'MINECRAFT_VERSION')."
},
"default_value": {
"type": "string",
"description": "The default value assigned when no override is provided."
},
"user_viewable": {
"type": "boolean",
"description": "Whether non-admin users can see this variable in the server settings."
},
"user_editable": {
"type": "boolean",
"description": "Whether non-admin users can modify this variable's value."
},
"rules": {
"type": "string",
"description": "Laravel-style validation rules as a pipe-delimited string (e.g. 'required|string|max:20', 'nullable|regex:/^[\\w\\d._-]+$/')."
}
}
}
}
}
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ollieread.com/schemas/egg/ptdl_v2.schema.json",
"title": "Pterodactyl Egg Export — PTDL_v2",
"description": "Schema for the current PTDL_v2 egg export format used by Pterodactyl Panel. This format uses 'docker_images' (label-to-image object) for Docker image definitions and includes 'field_type' on variables.",
"type": "object",
"required": [
"meta",
"name",
"author",
"docker_images",
"startup",
"config",
"scripts",
"variables"
],
"additionalProperties": false,
"properties": {
"_comment": {
"type": "string",
"description": "Auto-generated comment from the Pterodactyl Panel export process."
},
"meta": {
"$ref": "#/$defs/meta"
},
"exported_at": {
"type": "string",
"format": "date-time",
"description": "ISO 8601 timestamp of when the egg was exported."
},
"uuid": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
"description": "The egg's UUID. Not normally present in panel exports but may appear in manually constructed or API-sourced egg files."
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 191,
"description": "The display name of the egg."
},
"author": {
"type": "string",
"format": "email",
"description": "The email address of the egg author."
},
"description": {
"type": ["string", "null"],
"description": "A human-readable description of what this egg provides."
},
"features": {
"oneOf": [
{
"type": "array",
"items": {
"type": "string"
},
"description": "Feature flags that enable specific frontend functionality (e.g. 'eula', 'java_version', 'pid_limit')."
},
{
"type": "null"
}
]
},
"docker_images": {
"type": "object",
"minProperties": 1,
"additionalProperties": {
"type": "string"
},
"description": "A map of human-readable labels to Docker image URIs. The label is displayed in the UI as a selectable option (e.g. { \"Java 17\": \"ghcr.io/pterodactyl/yolks:java_17\" })."
},
"file_denylist": {
"type": "array",
"items": {
"type": "string"
},
"description": "List of file patterns that should be blocked from access via the file manager."
},
"startup": {
"type": "string",
"description": "The startup command template. Supports {{VARIABLE}} placeholders for environment variable interpolation and {{SERVER_MEMORY}} / {{SERVER_IP}} for built-in server values."
},
"config": {
"$ref": "#/$defs/config"
},
"scripts": {
"$ref": "#/$defs/scripts"
},
"variables": {
"type": "array",
"items": {
"$ref": "#/$defs/variable_v2"
},
"description": "Environment variables that can be configured for servers using this egg."
}
},
"$defs": {
"meta": {
"type": "object",
"required": ["version"],
"additionalProperties": false,
"properties": {
"version": {
"type": "string",
"const": "PTDL_v2",
"description": "The export format version identifier."
},
"update_url": {
"type": ["string", "null"],
"description": "An optional URL that the panel can use to check for egg updates."
}
}
},
"config": {
"type": "object",
"required": ["files", "startup", "logs", "stop"],
"additionalProperties": false,
"description": "Server process configuration. The 'files', 'startup', and 'logs' fields contain stringified JSON that the panel stores as-is and passes to Wings for processing.",
"properties": {
"files": {
"type": "string",
"description": "Stringified JSON defining configuration file modifications. When parsed, yields an object keyed by file path, each containing a 'parser' (e.g. 'properties', 'yaml', 'json', 'ini', 'xml') and a 'find' object mapping config keys to replacement values. Values may use {{server.build.*}} placeholders."
},
"startup": {
"type": "string",
"description": "Stringified JSON defining startup detection. When parsed, yields an object with 'done' (regex/string pattern indicating the server has started) and optionally 'userInteraction' (array of patterns requiring user input)."
},
"logs": {
"type": "string",
"description": "Stringified JSON defining log configuration. When parsed, yields an object optionally containing 'custom' (boolean) and 'location' (string path to log file)."
},
"stop": {
"type": "string",
"description": "The stop command or signal sent to gracefully stop the server process. Common values: 'stop', 'quit', 'end', '^C' (SIGINT), '^^' (SIGTERM). A plain string is a console command; caret-prefixed values are signals."
}
}
},
"scripts": {
"type": "object",
"required": ["installation"],
"additionalProperties": false,
"properties": {
"installation": {
"$ref": "#/$defs/installation_script"
}
}
},
"installation_script": {
"type": "object",
"required": ["container", "entrypoint"],
"additionalProperties": false,
"properties": {
"script": {
"type": ["string", "null"],
"description": "The shell script content that runs during server installation. Executed inside the installation container with the server directory mounted at /mnt/server."
},
"container": {
"type": "string",
"description": "The Docker image used to run the installation script (e.g. 'ghcr.io/pterodactyl/installers:alpine', 'alpine:3.9')."
},
"entrypoint": {
"type": "string",
"description": "The shell entrypoint for the installation script (e.g. 'ash', 'bash')."
}
}
},
"variable_v2": {
"type": "object",
"required": [
"name",
"description",
"env_variable",
"default_value",
"user_viewable",
"user_editable",
"rules",
"field_type"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"description": "The human-readable display name for this variable."
},
"description": {
"type": "string",
"description": "A description explaining the purpose of this variable and any constraints."
},
"env_variable": {
"type": "string",
"pattern": "^[A-Za-z_][A-Za-z0-9_]*$",
"description": "The environment variable name injected into the server container (e.g. 'SERVER_JARFILE', 'MINECRAFT_VERSION')."
},
"default_value": {
"type": "string",
"description": "The default value assigned when no override is provided."
},
"user_viewable": {
"type": "boolean",
"description": "Whether non-admin users can see this variable in the server settings."
},
"user_editable": {
"type": "boolean",
"description": "Whether non-admin users can modify this variable's value."
},
"rules": {
"type": "string",
"description": "Laravel-style validation rules as a pipe-delimited string (e.g. 'required|string|max:20', 'nullable|regex:/^[\\w\\d._-]+$/')."
},
"field_type": {
"type": "string",
"description": "The form field type for rendering this variable in the UI. Currently only 'text' is used by Pterodactyl, but the field exists for future extensibility.",
"default": "text"
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment