Scheduled Tasks
Manage automated server tasks including backups, restarts, command execution, and custom schedules.
List Schedules
Retrieve all scheduled tasks for a server.
GET /api/client/servers/{server}/schedules
URL Parameters
| Parameter | Type | Description |
|---|---|---|
server | string | Server identifier (UUID or short ID) |
Example Request
- cURL
- JavaScript
- Python
- PHP
- Go
- Java
- C#
- Ruby
curl "https://your-panel.com/api/client/servers/d3aac109/schedules" \
-H "Authorization: Bearer ptlc_YOUR_API_KEY" \
-H "Accept: Application/vnd.pterodactyl.v1+json" \
-H "Content-Type: application/json"
const axios = require('axios');
const serverId = 'd3aac109';
const response = await axios.get(`https://your-panel.com/api/client/servers/${serverId}/schedules`, {
headers: {
'Authorization': 'Bearer ptlc_YOUR_API_KEY',
'Accept': 'Application/vnd.pterodactyl.v1+json',
'Content-Type': 'application/json'
}
});
console.log('Server schedules:', response.data.data);
import requests
server_id = 'd3aac109'
headers = {
'Authorization': 'Bearer ptlc_YOUR_API_KEY',
'Accept': 'Application/vnd.pterodactyl.v1+json',
'Content-Type': 'application/json'
}
response = requests.get(f'https://your-panel.com/api/client/servers/{server_id}/schedules', headers=headers)
print('Server schedules:', response.json()['data'])
<?php
$serverId = 'd3aac109';
$client = new GuzzleHttp\Client();
$response = $client->get("https://your-panel.com/api/client/servers/{$serverId}/schedules", [
'headers' => [
'Authorization' => 'Bearer ptlc_YOUR_API_KEY',
'Accept' => 'Application/vnd.pterodactyl.v1+json',
'Content-Type' => 'application/json'
]
]);
$data = json_decode($response->getBody(), true);
print_r($data['data']);
?>
package main
import (
"encoding/json"
"fmt"
"net/http"
)
func main() {
serverId := "d3aac109"
url := fmt.Sprintf("https://your-panel.com/api/client/servers/%s/schedules", serverId)
client := &http.Client{}
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer ptlc_YOUR_API_KEY")
req.Header.Add("Accept", "Application/vnd.pterodactyl.v1+json")
req.Header.Add("Content-Type", "application/json")
resp, _ := client.Do(req)
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Println("Server schedules:", result["data"])
}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
String serverId = "d3aac109";
String url = String.format("https://your-panel.com/api/client/servers/%s/schedules", serverId);
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer ptlc_YOUR_API_KEY")
.header("Accept", "Application/vnd.pterodactyl.v1+json")
.header("Content-Type", "application/json")
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Server schedules: " + response.body());
using System.Net.Http;
using System.Threading.Tasks;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer ptlc_YOUR_API_KEY");
client.DefaultRequestHeaders.Add("Accept", "Application/vnd.pterodactyl.v1+json");
string serverId = "d3aac109";
var response = await client.GetAsync($"https://your-panel.com/api/client/servers/{serverId}/schedules");
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine("Server schedules: " + content);
require 'net/http'
require 'json'
server_id = 'd3aac109'
uri = URI("https://your-panel.com/api/client/servers/#{server_id}/schedules")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['Authorization'] = 'Bearer ptlc_YOUR_API_KEY'
request['Accept'] = 'Application/vnd.pterodactyl.v1+json'
request['Content-Type'] = 'application/json'
response = http.request(request)
data = JSON.parse(response.body)
puts "Server schedules: #{data['data']}"
Get Schedule Details
Retrieve detailed information about a specific schedule including all tasks.
GET /api/client/servers/{server}/schedules/{schedule}
URL Parameters
| Parameter | Type | Description |
|---|---|---|
server | string | Server identifier (UUID or short ID) |
schedule | integer | Schedule ID |
Example Request
- cURL
- JavaScript
- Python
- PHP
- Go
- Java
- C#
- Ruby
curl "https://your-panel.com/api/client/servers/d3aac109/schedules/2" \
-H "Authorization: Bearer ptlc_YOUR_API_KEY" \
-H "Accept: Application/vnd.pterodactyl.v1+json" \
-H "Content-Type: application/json"
const axios = require('axios');
const serverId = 'd3aac109';
const scheduleId = 2;
const response = await axios.get(`https://your-panel.com/api/client/servers/${serverId}/schedules/${scheduleId}`, {
headers: {
'Authorization': 'Bearer ptlc_YOUR_API_KEY',
'Accept': 'Application/vnd.pterodactyl.v1+json',
'Content-Type': 'application/json'
}
});
const schedule = response.data.attributes;
console.log(`Schedule: ${schedule.name}`);
console.log(`Cron: ${schedule.cron.minute} ${schedule.cron.hour} ${schedule.cron.day_of_month} ${schedule.cron.month} ${schedule.cron.day_of_week}`);
console.log(`Active: ${schedule.is_active}`);
console.log(`Tasks: ${schedule.relationships.tasks.data.length}`);
import requests
from datetime import datetime
server_id = 'd3aac109'
schedule_id = 2
headers = {
'Authorization': 'Bearer ptlc_YOUR_API_KEY',
'Accept': 'Application/vnd.pterodactyl.v1+json',
'Content-Type': 'application/json'
}
response = requests.get(f'https://your-panel.com/api/client/servers/{server_id}/schedules/{schedule_id}',
headers=headers)
schedule = response.json()['attributes']
print(f"Schedule: {schedule['name']}")
print(f"Cron: {schedule['cron']['minute']} {schedule['cron']['hour']} {schedule['cron']['day_of_month']} {schedule['cron']['month']} {schedule['cron']['day_of_week']}")
print(f"Active: {schedule['is_active']}")
print(f"Processing: {schedule['is_processing']}")
print(f"Last run: {schedule['last_run_at']}")
print(f"Next run: {schedule['next_run_at']}")
<?php
$serverId = 'd3aac109';
$scheduleId = 2;
$client = new GuzzleHttp\Client();
$response = $client->get("https://your-panel.com/api/client/servers/{$serverId}/schedules/{$scheduleId}", [
'headers' => [
'Authorization' => 'Bearer ptlc_YOUR_API_KEY',
'Accept' => 'Application/vnd.pterodactyl.v1+json',
'Content-Type' => 'application/json'
]
]);
$schedule = json_decode($response->getBody(), true)['attributes'];
echo "Schedule: " . $schedule['name'] . "\n";
echo "Cron: " . implode(' ', $schedule['cron']) . "\n";
echo "Active: " . ($schedule['is_active'] ? 'Yes' : 'No') . "\n";
echo "Processing: " . ($schedule['is_processing'] ? 'Yes' : 'No') . "\n";
echo "Last run: " . $schedule['last_run_at'] . "\n";
echo "Next run: " . $schedule['next_run_at'] . "\n";
?>
package main
import (
"encoding/json"
"fmt"
"net/http"
)
func main() {
serverId := "d3aac109"
scheduleId := 2
url := fmt.Sprintf("https://your-panel.com/api/client/servers/%s/schedules/%d", serverId, scheduleId)
client := &http.Client{}
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer ptlc_YOUR_API_KEY")
req.Header.Add("Accept", "Application/vnd.pterodactyl.v1+json")
req.Header.Add("Content-Type", "application/json")
resp, _ := client.Do(req)
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
schedule := result["attributes"].(map[string]interface{})
cron := schedule["cron"].(map[string]interface{})
fmt.Printf("Schedule: %s\n", schedule["name"])
fmt.Printf("Cron: %s %s %s %s %s\n",
cron["minute"], cron["hour"], cron["day_of_month"], cron["month"], cron["day_of_week"])
fmt.Printf("Active: %t\n", schedule["is_active"])
fmt.Printf("Processing: %t\n", schedule["is_processing"])
fmt.Printf("Last run: %s\n", schedule["last_run_at"])
fmt.Printf("Next run: %s\n", schedule["next_run_at"])
}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
String serverId = "d3aac109";
int scheduleId = 2;
String url = String.format("https://your-panel.com/api/client/servers/%s/schedules/%d", serverId, scheduleId);
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer ptlc_YOUR_API_KEY")
.header("Accept", "Application/vnd.pterodactyl.v1+json")
.header("Content-Type", "application/json")
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
ObjectMapper mapper = new ObjectMapper();
JsonNode data = mapper.readTree(response.body());
JsonNode schedule = data.get("attributes");
JsonNode cron = schedule.get("cron");
System.out.println("Schedule: " + schedule.get("name").asText());
System.out.printf("Cron: %s %s %s %s %s\n",
cron.get("minute").asText(),
cron.get("hour").asText(),
cron.get("day_of_month").asText(),
cron.get("month").asText(),
cron.get("day_of_week").asText());
System.out.println("Active: " + schedule.get("is_active").asBoolean());
System.out.println("Processing: " + schedule.get("is_processing").asBoolean());
System.out.println("Last run: " + schedule.get("last_run_at").asText());
System.out.println("Next run: " + schedule.get("next_run_at").asText());
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer ptlc_YOUR_API_KEY");
client.DefaultRequestHeaders.Add("Accept", "Application/vnd.pterodactyl.v1+json");
string serverId = "d3aac109";
int scheduleId = 2;
string url = $"https://your-panel.com/api/client/servers/{serverId}/schedules/{scheduleId}";
var response = await client.GetAsync(url);
var content = await response.Content.ReadAsStringAsync();
JObject data = JObject.Parse(content);
var schedule = data["attributes"];
var cron = schedule["cron"];
Console.WriteLine($"Schedule: {schedule["name"]}");
Console.WriteLine($"Cron: {cron["minute"]} {cron["hour"]} {cron["day_of_month"]} {cron["month"]} {cron["day_of_week"]}");
Console.WriteLine($"Active: {schedule["is_active"]}");
Console.WriteLine($"Processing: {schedule["is_processing"]}");
Console.WriteLine($"Last run: {schedule["last_run_at"]}");
Console.WriteLine($"Next run: {schedule["next_run_at"]}");
require 'net/http'
require 'uri'
require 'json'
server_id = 'd3aac109'
schedule_id = 2
uri = URI("https://your-panel.com/api/client/servers/#{server_id}/schedules/#{schedule_id}")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['Authorization'] = 'Bearer ptlc_YOUR_API_KEY'
request['Accept'] = 'Application/vnd.pterodactyl.v1+json'
request['Content-Type'] = 'application/json'
response = http.request(request)
schedule = JSON.parse(response.body)['attributes']
cron = schedule['cron']
puts "Schedule: #{schedule['name']}"
puts "Cron: #{cron['minute']} #{cron['hour']} #{cron['day_of_month']} #{cron['month']} #{cron['day_of_week']}"
puts "Active: #{schedule['is_active']}"
puts "Processing: #{schedule['is_processing']}"
puts "Last run: #{schedule['last_run_at']}"
puts "Next run: #{schedule['next_run_at']}"
Create Schedule
Create a new scheduled task for the server.
POST /api/client/servers/{server}/schedules
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Schedule name (max 255 characters) |
minute | string | Yes | Cron minute (0-59 or *) |
hour | string | Yes | Cron hour (0-23 or *) |
day_of_month | string | Yes | Cron day of month (1-31 or *) |
month | string | Yes | Cron month (1-12 or *) |
day_of_week | string | Yes | Cron day of week (0-6 or *) |
is_active | boolean | No | Enable schedule immediately (default: true) |
only_when_online | boolean | No | Only run when server is online (default: false) |
Example Request
- cURL
- JavaScript
- Python
- PHP
- Go
- Java
- C#
- Ruby
curl -X POST "https://your-panel.com/api/client/servers/d3aac109/schedules" \
-H "Authorization: Bearer ptlc_YOUR_API_KEY" \
-H "Accept: Application/vnd.pterodactyl.v1+json" \
-H "Content-Type: application/json" \
-d '{
"name": "Daily Backup",
"minute": "0",
"hour": "3",
"day_of_month": "*",
"month": "*",
"day_of_week": "*",
"is_active": true,
"only_when_online": false
}'
const axios = require('axios');
const serverId = 'd3aac109';
const scheduleData = {
name: 'Daily Backup',
minute: '0',
hour: '3',
day_of_month: '*',
month: '*',
day_of_week: '*',
is_active: true,
only_when_online: false
};
const response = await axios.post(`https://your-panel.com/api/client/servers/${serverId}/schedules`, scheduleData, {
headers: {
'Authorization': 'Bearer ptlc_YOUR_API_KEY',
'Accept': 'Application/vnd.pterodactyl.v1+json',
'Content-Type': 'application/json'
}
});
const schedule = response.data.attributes;
console.log(`Created schedule: ${schedule.name} (ID: ${schedule.id})`);
console.log(`Next run: ${schedule.next_run_at}`);
import requests
server_id = 'd3aac109'
headers = {
'Authorization': 'Bearer ptlc_YOUR_API_KEY',
'Accept': 'Application/vnd.pterodactyl.v1+json',
'Content-Type': 'application/json'
}
schedule_data = {
'name': 'Daily Backup',
'minute': '0',
'hour': '3',
'day_of_month': '*',
'month': '*',
'day_of_week': '*',
'is_active': True,
'only_when_online': False
}
response = requests.post(f'https://your-panel.com/api/client/servers/{server_id}/schedules',
headers=headers, json=schedule_data)
schedule = response.json()['attributes']
print(f"Created schedule: {schedule['name']} (ID: {schedule['id']})")
print(f"Cron expression: {schedule['cron']['minute']} {schedule['cron']['hour']} {schedule['cron']['day_of_month']} {schedule['cron']['month']} {schedule['cron']['day_of_week']}")
print(f"Next run: {schedule['next_run_at']}")
<?php
$serverId = 'd3aac109';
$client = new GuzzleHttp\Client();
$scheduleData = [
'name' => 'Daily Backup',
'minute' => '0',
'hour' => '3',
'day_of_month' => '*',
'month' => '*',
'day_of_week' => '*',
'is_active' => true,
'only_when_online' => false
];
$response = $client->post("https://your-panel.com/api/client/servers/{$serverId}/schedules", [
'headers' => [
'Authorization' => 'Bearer ptlc_YOUR_API_KEY',
'Accept' => 'Application/vnd.pterodactyl.v1+json',
'Content-Type' => 'application/json'
],
'json' => $scheduleData
]);
$schedule = json_decode($response->getBody(), true)['attributes'];
echo "Created schedule: " . $schedule['name'] . " (ID: " . $schedule['id'] . ")\n";
echo "Cron: " . implode(' ', $schedule['cron']) . "\n";
echo "Next run: " . $schedule['next_run_at'] . "\n";
?>
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
serverId := "d3aac109"
scheduleData := map[string]interface{}{
"name": "Daily Backup",
"minute": "0",
"hour": "3",
"day_of_month": "*",
"month": "*",
"day_of_week": "*",
"is_active": true,
"only_when_online": false,
}
jsonData, _ := json.Marshal(scheduleData)
url := fmt.Sprintf("https://your-panel.com/api/client/servers/%s/schedules", serverId)
client := &http.Client{}
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
req.Header.Add("Authorization", "Bearer ptlc_YOUR_API_KEY")
req.Header.Add("Accept", "Application/vnd.pterodactyl.v1+json")
req.Header.Add("Content-Type", "application/json")
resp, _ := client.Do(req)
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
schedule := result["attributes"].(map[string]interface{})
id := schedule["id"].(float64)
name := schedule["name"].(string)
nextRun := schedule["next_run_at"].(string)
fmt.Printf("Created schedule: %s (ID: %.0f)\n", name, id)
fmt.Printf("Next run: %s\n", nextRun)
}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
String serverId = "d3aac109";
String jsonData = """
{
"name": "Daily Backup",
"minute": "0",
"hour": "3",
"day_of_month": "*",
"month": "*",
"day_of_week": "*",
"is_active": true,
"only_when_online": false
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(String.format("https://your-panel.com/api/client/servers/%s/schedules", serverId)))
.header("Authorization", "Bearer ptlc_YOUR_API_KEY")
.header("Accept", "Application/vnd.pterodactyl.v1+json")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonData))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Schedule created: " + response.body());
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer ptlc_YOUR_API_KEY");
client.DefaultRequestHeaders.Add("Accept", "Application/vnd.pterodactyl.v1+json");
string serverId = "d3aac109";
var scheduleData = new {
name = "Daily Backup",
minute = "0",
hour = "3",
day_of_month = "*",
month = "*",
day_of_week = "*",
is_active = true,
only_when_online = false
};
var json = JsonSerializer.Serialize(scheduleData);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync($"https://your-panel.com/api/client/servers/{serverId}/schedules", content);
var responseContent = await response.Content.ReadAsStringAsync();
JObject data = JObject.Parse(responseContent);
var schedule = data["attributes"];
Console.WriteLine($"Created schedule: {schedule["name"]} (ID: {schedule["id"]})");
Console.WriteLine($"Next run: {schedule["next_run_at"]}");
require 'net/http'
require 'json'
server_id = 'd3aac109'
schedule_data = {
name: 'Daily Backup',
minute: '0',
hour: '3',
day_of_month: '*',
month: '*',
day_of_week: '*',
is_active: true,
only_when_online: false
}
uri = URI("https://your-panel.com/api/client/servers/#{server_id}/schedules")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer ptlc_YOUR_API_KEY'
request['Accept'] = 'Application/vnd.pterodactyl.v1+json'
request['Content-Type'] = 'application/json'
request.body = schedule_data.to_json
response = http.request(request)
schedule = JSON.parse(response.body)['attributes']
puts "Created schedule: #{schedule['name']} (ID: #{schedule['id']})"
puts "Next run: #{schedule['next_run_at']}"
Success Response
{
"object": "server_schedule",
"attributes": {
"id": 12,
"name": "Daily Backup",
"cron": {
"day_of_week": "*",
"day_of_month": "*",
"hour": "3",
"minute": "0",
"month": "*"
},
"is_active": true,
"is_processing": false,
"only_when_online": false,
"last_run_at": null,
"next_run_at": "2023-10-21T03:00:00+00:00",
"created_at": "2023-10-20T16:45:00+00:00",
"updated_at": "2023-10-20T16:45:00+00:00",
"relationships": {
"tasks": {
"object": "list",
"data": []
}
}
}
}
Cron Expression Examples
| Schedule | Minute | Hour | Day Month | Month | Day Week | Description |
|---|---|---|---|---|---|---|
| Every hour | 0 | * | * | * | * | Run at minute 0 of every hour |
| Daily at 3 AM | 0 | 3 | * | * | * | Run daily at 3:00 AM |
| Weekly on Sunday | 0 | 2 | * | * | 0 | Run Sundays at 2:00 AM |
| Monthly on 1st | 30 | 4 | 1 | * | * | Run 1st of month at 4:30 AM |
| Every 15 minutes | */15 | * | * | * | * | Run every 15 minutes |
| Weekdays only | 0 | 8 | * | * | 1-5 | Run weekdays at 8:00 AM |
Error Responses
Schedule Limit Reached (400)
{
"errors": [
{
"code": "TooManySchedulesException",
"status": "400",
"detail": "This server has reached its schedule limit."
}
]
}
Invalid Cron Expression (422)
{
"errors": [
{
"code": "ValidationException",
"status": "422",
"detail": "The provided cron expression is invalid.",
"meta": {
"rule": "cron_expression",
"source_field": "minute"
}
}
]
}
Update Schedule
Modify an existing schedule's configuration.
POST /api/client/servers/{server}/schedules/{schedule}
URL Parameters
| Parameter | Type | Description |
|---|---|---|
server | string | Server identifier (UUID or short ID) |
schedule | integer | Schedule ID |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Schedule name |
minute | string | No | Cron minute |
hour | string | No | Cron hour |
day_of_month | string | No | Cron day of month |
month | string | No | Cron month |
day_of_week | string | No | Cron day of week |
is_active | boolean | No | Enable/disable schedule |
only_when_online | boolean | No | Only run when server is online |
Example Request
- cURL
- JavaScript
- Python
- PHP
- Go
- Java
- C#
- Ruby
curl -X POST "https://your-panel.com/api/client/servers/d3aac109/schedules/12" \
-H "Authorization: Bearer ptlc_YOUR_API_KEY" \
-H "Accept: Application/vnd.pterodactyl.v1+json" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated Daily Backup",
"hour": "2",
"is_active": false
}'
const axios = require('axios');
const serverId = 'd3aac109';
const scheduleId = 12;
const updateData = {
name: 'Updated Daily Backup',
hour: '2',
is_active: false
};
const response = await axios.post(`https://your-panel.com/api/client/servers/${serverId}/schedules/${scheduleId}`, updateData, {
headers: {
'Authorization': 'Bearer ptlc_YOUR_API_KEY',
'Accept': 'Application/vnd.pterodactyl.v1+json',
'Content-Type': 'application/json'
}
});
if (response.status === 204) {
console.log('Schedule updated successfully');
} else {
console.error('Failed to update schedule');
}
import requests
server_id = 'd3aac109'
schedule_id = 12
headers = {
'Authorization': 'Bearer ptlc_YOUR_API_KEY',
'Accept': 'Application/vnd.pterodactyl.v1+json',
'Content-Type': 'application/json'
}
update_data = {
'name': 'Updated Daily Backup',
'hour': '2',
'is_active': False
}
response = requests.post(f'https://your-panel.com/api/client/servers/{server_id}/schedules/{schedule_id}',
headers=headers, json=update_data)
if response.status_code == 204:
print("Schedule updated successfully")
else:
print(f"Failed to update schedule: {response.status_code}")
if response.content:
print(f"Error: {response.json()}")
<?php
$serverId = 'd3aac109';
$scheduleId = 12;
$client = new GuzzleHttp\Client();
$updateData = [
'name' => 'Updated Daily Backup',
'hour' => '2',
'is_active' => false
];
try {
$response = $client->post("https://your-panel.com/api/client/servers/{$serverId}/schedules/{$scheduleId}", [
'headers' => [
'Authorization' => 'Bearer ptlc_YOUR_API_KEY',
'Accept' => 'Application/vnd.pterodactyl.v1+json',
'Content-Type' => 'application/json'
],
'json' => $updateData
]);
if ($response->getStatusCode() === 204) {
echo "Schedule updated successfully\n";
}
} catch (GuzzleHttp\Exception\ClientException $e) {
echo "Failed to update schedule: " . $e->getCode() . "\n";
echo "Error: " . $e->getResponse()->getBody() . "\n";
}
?>
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
serverId := "d3aac109"
scheduleId := 12
updateData := map[string]interface{}{
"name": "Updated Daily Backup",
"hour": "2",
"is_active": false,
}
jsonData, _ := json.Marshal(updateData)
url := fmt.Sprintf("https://your-panel.com/api/client/servers/%s/schedules/%d", serverId, scheduleId)
client := &http.Client{}
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
req.Header.Add("Authorization", "Bearer ptlc_YOUR_API_KEY")
req.Header.Add("Accept", "Application/vnd.pterodactyl.v1+json")
req.Header.Add("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
defer resp.Body.Close()
if resp.StatusCode == 204 {
fmt.Println("Schedule updated successfully")
} else {
fmt.Printf("Failed to update schedule: %d\n", resp.StatusCode)
}
}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
String serverId = "d3aac109";
int scheduleId = 12;
String jsonData = """
{
"name": "Updated Daily Backup",
"hour": "2",
"is_active": false
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(String.format("https://your-panel.com/api/client/servers/%s/schedules/%d", serverId, scheduleId)))
.header("Authorization", "Bearer ptlc_YOUR_API_KEY")
.header("Accept", "Application/vnd.pterodactyl.v1+json")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonData))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 204) {
System.out.println("Schedule updated successfully");
} else {
System.out.println("Failed to update schedule: " + response.statusCode());
if (!response.body().isEmpty()) {
System.out.println("Error: " + response.body());
}
}
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer ptlc_YOUR_API_KEY");
client.DefaultRequestHeaders.Add("Accept", "Application/vnd.pterodactyl.v1+json");
string serverId = "d3aac109";
int scheduleId = 12;
var updateData = new {
name = "Updated Daily Backup",
hour = "2",
is_active = false
};
var json = JsonSerializer.Serialize(updateData);
var content = new StringContent(json, Encoding.UTF8, "application/json");
try
{
var response = await client.PostAsync($"https://your-panel.com/api/client/servers/{serverId}/schedules/{scheduleId}", content);
if (response.StatusCode == System.Net.HttpStatusCode.NoContent)
{
Console.WriteLine("Schedule updated successfully");
}
else
{
Console.WriteLine($"Failed to update schedule: {(int)response.StatusCode}");
string errorContent = await response.Content.ReadAsStringAsync();
if (!string.IsNullOrEmpty(errorContent))
{
Console.WriteLine($"Error: {errorContent}");
}
}
}
catch (HttpRequestException ex)
{
Console.WriteLine($"Error updating schedule: {ex.Message}");
}
require 'net/http'
require 'json'
server_id = 'd3aac109'
schedule_id = 12
update_data = {
name: 'Updated Daily Backup',
hour: '2',
is_active: false
}
uri = URI("https://your-panel.com/api/client/servers/#{server_id}/schedules/#{schedule_id}")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer ptlc_YOUR_API_KEY'
request['Accept'] = 'Application/vnd.pterodactyl.v1+json'
request['Content-Type'] = 'application/json'
request.body = update_data.to_json
response = http.request(request)
if response.code == '204'
puts "Schedule updated successfully"
else
puts "Failed to update schedule: #{response.code}"
puts "Error: #{response.body}" unless response.body.empty?
end
Success Response (204)
Returns empty response body with status code 204.
Delete Schedule
Permanently delete a schedule and all its tasks.
DELETE /api/client/servers/{server}/schedules/{schedule}
URL Parameters
| Parameter | Type | Description |
|---|---|---|
server | string | Server identifier (UUID or short ID) |
schedule | integer | Schedule ID |
Example Request
- cURL
- JavaScript
- Python
- PHP
- Go
- Java
- C#
- Ruby
curl -X DELETE "https://your-panel.com/api/client/servers/d3aac109/schedules/12" \
-H "Authorization: Bearer ptlc_YOUR_API_KEY" \
-H "Accept: Application/vnd.pterodactyl.v1+json" \
-H "Content-Type: application/json"
const axios = require('axios');
const serverId = 'd3aac109';
const scheduleId = 12;
const response = await axios.delete(`https://your-panel.com/api/client/servers/${serverId}/schedules/${scheduleId}`, {
headers: {
'Authorization': 'Bearer ptlc_YOUR_API_KEY',
'Accept': 'Application/vnd.pterodactyl.v1+json',
'Content-Type': 'application/json'
}
});
if (response.status === 204) {
console.log('Schedule deleted successfully');
} else {
console.error('Failed to delete schedule');
}
import requests
server_id = 'd3aac109'
schedule_id = 12
headers = {
'Authorization': 'Bearer ptlc_YOUR_API_KEY',
'Accept': 'Application/vnd.pterodactyl.v1+json',
'Content-Type': 'application/json'
}
response = requests.delete(f'https://your-panel.com/api/client/servers/{server_id}/schedules/{schedule_id}',
headers=headers)
if response.status_code == 204:
print("Schedule deleted successfully")
else:
print(f"Failed to delete schedule: {response.status_code}")
if response.content:
print(f"Error: {response.json()}")
<?php
$serverId = 'd3aac109';
$scheduleId = 12;
$client = new GuzzleHttp\Client();
try {
$response = $client->delete("https://your-panel.com/api/client/servers/{$serverId}/schedules/{$scheduleId}", [
'headers' => [
'Authorization' => 'Bearer ptlc_YOUR_API_KEY',
'Accept' => 'Application/vnd.pterodactyl.v1+json',
'Content-Type' => 'application/json'
]
]);
if ($response->getStatusCode() === 204) {
echo "Schedule deleted successfully\n";
}
} catch (GuzzleHttp\Exception\ClientException $e) {
echo "Failed to delete schedule: " . $e->getCode() . "\n";
echo "Error: " . $e->getResponse()->getBody() . "\n";
}
?>
package main
import (
"fmt"
"net/http"
)
func main() {
serverId := "d3aac109"
scheduleId := 12
url := fmt.Sprintf("https://your-panel.com/api/client/servers/%s/schedules/%d", serverId, scheduleId)
client := &http.Client{}
req, _ := http.NewRequest("DELETE", url, nil)
req.Header.Add("Authorization", "Bearer ptlc_YOUR_API_KEY")
req.Header.Add("Accept", "Application/vnd.pterodactyl.v1+json")
req.Header.Add("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
defer resp.Body.Close()
if resp.StatusCode == 204 {
fmt.Println("Schedule deleted successfully")
} else {
fmt.Printf("Failed to delete schedule: %d\n", resp.StatusCode)
}
}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
String serverId = "d3aac109";
int scheduleId = 12;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(String.format("https://your-panel.com/api/client/servers/%s/schedules/%d", serverId, scheduleId)))
.header("Authorization", "Bearer ptlc_YOUR_API_KEY")
.header("Accept", "Application/vnd.pterodactyl.v1+json")
.header("Content-Type", "application/json")
.DELETE()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 204) {
System.out.println("Schedule deleted successfully");
} else {
System.out.println("Failed to delete schedule: " + response.statusCode());
if (!response.body().isEmpty()) {
System.out.println("Error: " + response.body());
}
}
using System.Net.Http;
using System.Threading.Tasks;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer ptlc_YOUR_API_KEY");
client.DefaultRequestHeaders.Add("Accept", "Application/vnd.pterodactyl.v1+json");
string serverId = "d3aac109";
int scheduleId = 12;
try
{
var response = await client.DeleteAsync($"https://your-panel.com/api/client/servers/{serverId}/schedules/{scheduleId}");
if (response.StatusCode == System.Net.HttpStatusCode.NoContent)
{
Console.WriteLine("Schedule deleted successfully");
}
else
{
Console.WriteLine($"Failed to delete schedule: {(int)response.StatusCode}");
string errorContent = await response.Content.ReadAsStringAsync();
if (!string.IsNullOrEmpty(errorContent))
{
Console.WriteLine($"Error: {errorContent}");
}
}
}
catch (HttpRequestException ex)
{
Console.WriteLine($"Error deleting schedule: {ex.Message}");
}
require 'net/http'
require 'uri'
require 'json'
server_id = 'd3aac109'
schedule_id = 12
uri = URI("https://your-panel.com/api/client/servers/#{server_id}/schedules/#{schedule_id}")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(uri)
request['Authorization'] = 'Bearer ptlc_YOUR_API_KEY'
request['Accept'] = 'Application/vnd.pterodactyl.v1+json'
request['Content-Type'] = 'application/json'
response = http.request(request)
if response.code == '204'
puts "Schedule deleted successfully"
else
puts "Failed to delete schedule: #{response.code}"
puts "Error: #{response.body}" unless response.body.empty?
end
Success Response (204)
Returns empty response body with status code 204.
:::danger Warning Schedule deletion is permanent and irreversible. All associated tasks will also be deleted. :::
Execute Schedule
Manually trigger a schedule to run immediately.
POST /api/client/servers/{server}/schedules/{schedule}/execute
URL Parameters
| Parameter | Type | Description |
|---|---|---|
server | string | Server identifier (UUID or short ID) |
schedule | integer | Schedule ID |
Example Request
- cURL
- JavaScript
- Python
- PHP
- Go
- Java
- C#
- Ruby
curl -X POST "https://your-panel.com/api/client/servers/d3aac109/schedules/2/execute" \
-H "Authorization: Bearer ptlc_YOUR_API_KEY" \
-H "Accept: Application/vnd.pterodactyl.v1+json" \
-H "Content-Type: application/json"
const axios = require('axios');
const serverId = 'd3aac109';
const scheduleId = 2;
const response = await axios.post(`https://your-panel.com/api/client/servers/${serverId}/schedules/${scheduleId}/execute`, {}, {
headers: {
'Authorization': 'Bearer ptlc_YOUR_API_KEY',
'Accept': 'Application/vnd.pterodactyl.v1+json',
'Content-Type': 'application/json'
}
});
if (response.status === 204) {
console.log('Schedule executed successfully');
} else {
console.error('Failed to execute schedule');
}
import requests
server_id = 'd3aac109'
schedule_id = 2
headers = {
'Authorization': 'Bearer ptlc_YOUR_API_KEY',
'Accept': 'Application/vnd.pterodactyl.v1+json',
'Content-Type': 'application/json'
}
response = requests.post(f'https://your-panel.com/api/client/servers/{server_id}/schedules/{schedule_id}/execute',
headers=headers)
if response.status_code == 204:
print("Schedule executed successfully")
elif response.status_code == 409:
print("Schedule is already running")
elif response.status_code == 400:
print("Cannot execute inactive schedule")
else:
print(f"Failed to execute schedule: {response.status_code}")
if response.content:
print(f"Error: {response.json()}")
<?php
$serverId = 'd3aac109';
$scheduleId = 2;
$client = new GuzzleHttp\Client();
try {
$response = $client->post("https://your-panel.com/api/client/servers/{$serverId}/schedules/{$scheduleId}/execute", [
'headers' => [
'Authorization' => 'Bearer ptlc_YOUR_API_KEY',
'Accept' => 'Application/vnd.pterodactyl.v1+json',
'Content-Type' => 'application/json'
]
]);
if ($response->getStatusCode() === 204) {
echo "Schedule executed successfully\n";
}
} catch (GuzzleHttp\Exception\ClientException $e) {
$statusCode = $e->getCode();
if ($statusCode === 409) {
echo "Schedule is already running\n";
} elseif ($statusCode === 400) {
echo "Cannot execute inactive schedule\n";
} else {
echo "Failed to execute schedule: " . $statusCode . "\n";
echo "Error: " . $e->getResponse()->getBody() . "\n";
}
}
?>
package main
import (
"fmt"
"net/http"
)
func main() {
serverId := "d3aac109"
scheduleId := 2
url := fmt.Sprintf("https://your-panel.com/api/client/servers/%s/schedules/%d/execute", serverId, scheduleId)
client := &http.Client{}
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer ptlc_YOUR_API_KEY")
req.Header.Add("Accept", "Application/vnd.pterodactyl.v1+json")
req.Header.Add("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
defer resp.Body.Close()
switch resp.StatusCode {
case 204:
fmt.Println("Schedule executed successfully")
case 409:
fmt.Println("Schedule is already running")
case 400:
fmt.Println("Cannot execute inactive schedule")
default:
fmt.Printf("Failed to execute schedule: %d\n", resp.StatusCode)
}
}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
String serverId = "d3aac109";
int scheduleId = 2;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(String.format("https://your-panel.com/api/client/servers/%s/schedules/%d/execute", serverId, scheduleId)))
.header("Authorization", "Bearer ptlc_YOUR_API_KEY")
.header("Accept", "Application/vnd.pterodactyl.v1+json")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
switch (response.statusCode()) {
case 204:
System.out.println("Schedule executed successfully");
break;
case 409:
System.out.println("Schedule is already running");
break;
case 400:
System.out.println("Cannot execute inactive schedule");
break;
default:
System.out.println("Failed to execute schedule: " + response.statusCode());
if (!response.body().isEmpty()) {
System.out.println("Error: " + response.body());
}
}
using System.Net.Http;
using System.Threading.Tasks;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer ptlc_YOUR_API_KEY");
client.DefaultRequestHeaders.Add("Accept", "Application/vnd.pterodactyl.v1+json");
string serverId = "d3aac109";
int scheduleId = 2;
try
{
var response = await client.PostAsync($"https://your-panel.com/api/client/servers/{serverId}/schedules/{scheduleId}/execute", new StringContent(""));
switch ((int)response.StatusCode)
{
case 204:
Console.WriteLine("Schedule executed successfully");
break;
case 409:
Console.WriteLine("Schedule is already running");
break;
case 400:
Console.WriteLine("Cannot execute inactive schedule");
break;
default:
Console.WriteLine($"Failed to execute schedule: {(int)response.StatusCode}");
string errorContent = await response.Content.ReadAsStringAsync();
if (!string.IsNullOrEmpty(errorContent))
{
Console.WriteLine($"Error: {errorContent}");
}
break;
}
}
catch (HttpRequestException ex)
{
Console.WriteLine($"Error executing schedule: {ex.Message}");
}
require 'net/http'
require 'uri'
require 'json'
server_id = 'd3aac109'
schedule_id = 2
uri = URI("https://your-panel.com/api/client/servers/#{server_id}/schedules/#{schedule_id}/execute")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer ptlc_YOUR_API_KEY'
request['Accept'] = 'Application/vnd.pterodactyl.v1+json'
request['Content-Type'] = 'application/json'
response = http.request(request)
case response.code
when '204'
puts "Schedule executed successfully"
when '409'
puts "Schedule is already running"
when '400'
puts "Cannot execute inactive schedule"
else
puts "Failed to execute schedule: #{response.code}"
puts "Error: #{response.body}" unless response.body.empty?
end
Success Response (204)
Returns empty response body with status code 204.
Error Responses
Schedule Already Running (409)
{
"errors": [
{
"code": "ConflictingServerStateException",
"status": "409",
"detail": "This schedule is already running and cannot be executed again."
}
]
}
Schedule Inactive (400)
{
"errors": [
{
"code": "BadRequestHttpException",
"status": "400",
"detail": "Cannot execute an inactive schedule."
}
]
}
Schedule Tasks Management
List Schedule Tasks
GET /api/client/servers/{server}/schedules/{schedule}/tasks
Create Schedule Task
POST /api/client/servers/{server}/schedules/{schedule}/tasks
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
action | string | Yes | Task action: command, power, backup |
payload | string | Yes | Action payload (command text, power action, etc.) |
time_offset | integer | Yes | Delay in seconds from previous task |
continue_on_failure | boolean | No | Continue if task fails (default: false) |
Task Actions
| Action | Payload | Description |
|---|---|---|
command | Command string | Execute console command |
power | start, stop, restart, kill | Power management action |
backup | Empty string or backup name | Create server backup |
Example Create Task
- cURL
- JavaScript
- Python
- PHP
- Go
- Java
- C#
- Ruby
curl -X POST "https://your-panel.com/api/client/servers/d3aac109/schedules/12/tasks" \
-H "Authorization: Bearer ptlc_YOUR_API_KEY" \
-H "Accept: Application/vnd.pterodactyl.v1+json" \
-H "Content-Type: application/json" \
-d '{
"action": "backup",
"payload": "Scheduled backup",
"time_offset": 0,
"continue_on_failure": false
}'
const axios = require('axios');
const serverId = 'd3aac109';
const scheduleId = 12;
const taskData = {
action: 'backup',
payload: 'Scheduled backup',
time_offset: 0,
continue_on_failure: false
};
const response = await axios.post(`https://your-panel.com/api/client/servers/${serverId}/schedules/${scheduleId}/tasks`, taskData, {
headers: {
'Authorization': 'Bearer ptlc_YOUR_API_KEY',
'Accept': 'Application/vnd.pterodactyl.v1+json',
'Content-Type': 'application/json'
}
});
const task = response.data.attributes;
console.log(`Created task: ${task.action} (ID: ${task.id})`);
console.log(`Sequence: ${task.sequence_id}, Offset: ${task.time_offset}s`);
import requests
server_id = 'd3aac109'
schedule_id = 12
headers = {
'Authorization': 'Bearer ptlc_YOUR_API_KEY',
'Accept': 'Application/vnd.pterodactyl.v1+json',
'Content-Type': 'application/json'
}
task_data = {
'action': 'backup',
'payload': 'Scheduled backup',
'time_offset': 0,
'continue_on_failure': False
}
response = requests.post(f'https://your-panel.com/api/client/servers/{server_id}/schedules/{schedule_id}/tasks',
headers=headers, json=task_data)
task = response.json()['attributes']
print(f"Created task: {task['action']} (ID: {task['id']})")
print(f"Sequence: {task['sequence_id']}, Offset: {task['time_offset']}s")
print(f"Payload: {task['payload']}")
<?php
$serverId = 'd3aac109';
$scheduleId = 12;
$client = new GuzzleHttp\Client();
$taskData = [
'action' => 'backup',
'payload' => 'Scheduled backup',
'time_offset' => 0,
'continue_on_failure' => false
];
$response = $client->post("https://your-panel.com/api/client/servers/{$serverId}/schedules/{$scheduleId}/tasks", [
'headers' => [
'Authorization' => 'Bearer ptlc_YOUR_API_KEY',
'Accept' => 'Application/vnd.pterodactyl.v1+json',
'Content-Type' => 'application/json'
],
'json' => $taskData
]);
$task = json_decode($response->getBody(), true)['attributes'];
echo "Created task: " . $task['action'] . " (ID: " . $task['id'] . ")\n";
echo "Sequence: " . $task['sequence_id'] . ", Offset: " . $task['time_offset'] . "s\n";
echo "Payload: " . $task['payload'] . "\n";
?>
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
serverId := "d3aac109"
scheduleId := 12
taskData := map[string]interface{}{
"action": "backup",
"payload": "Scheduled backup",
"time_offset": 0,
"continue_on_failure": false,
}
jsonData, _ := json.Marshal(taskData)
url := fmt.Sprintf("https://your-panel.com/api/client/servers/%s/schedules/%d/tasks", serverId, scheduleId)
client := &http.Client{}
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
req.Header.Add("Authorization", "Bearer ptlc_YOUR_API_KEY")
req.Header.Add("Accept", "Application/vnd.pterodactyl.v1+json")
req.Header.Add("Content-Type", "application/json")
resp, _ := client.Do(req)
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
task := result["attributes"].(map[string]interface{})
id := task["id"].(float64)
action := task["action"].(string)
sequenceId := task["sequence_id"].(float64)
timeOffset := task["time_offset"].(float64)
fmt.Printf("Created task: %s (ID: %.0f)\n", action, id)
fmt.Printf("Sequence: %.0f, Offset: %.0fs\n", sequenceId, timeOffset)
}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
String serverId = "d3aac109";
int scheduleId = 12;
String jsonData = """
{
"action": "backup",
"payload": "Scheduled backup",
"time_offset": 0,
"continue_on_failure": false
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(String.format("https://your-panel.com/api/client/servers/%s/schedules/%d/tasks", serverId, scheduleId)))
.header("Authorization", "Bearer ptlc_YOUR_API_KEY")
.header("Accept", "Application/vnd.pterodactyl.v1+json")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonData))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Schedule task created: " + response.body());
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer ptlc_YOUR_API_KEY");
client.DefaultRequestHeaders.Add("Accept", "Application/vnd.pterodactyl.v1+json");
string serverId = "d3aac109";
int scheduleId = 12;
var taskData = new {
action = "backup",
payload = "Scheduled backup",
time_offset = 0,
continue_on_failure = false
};
var json = JsonSerializer.Serialize(taskData);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync($"https://your-panel.com/api/client/servers/{serverId}/schedules/{scheduleId}/tasks", content);
var responseContent = await response.Content.ReadAsStringAsync();
JObject data = JObject.Parse(responseContent);
var task = data["attributes"];
Console.WriteLine($"Created task: {task["action"]} (ID: {task["id"]})");
Console.WriteLine($"Sequence: {task["sequence_id"]}, Offset: {task["time_offset"]}s");
require 'net/http'
require 'json'
server_id = 'd3aac109'
schedule_id = 12
task_data = {
action: 'backup',
payload: 'Scheduled backup',
time_offset: 0,
continue_on_failure: false
}
uri = URI("https://your-panel.com/api/client/servers/#{server_id}/schedules/#{schedule_id}/tasks")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer ptlc_YOUR_API_KEY'
request['Accept'] = 'Application/vnd.pterodactyl.v1+json'
request['Content-Type'] = 'application/json'
request.body = task_data.to_json
response = http.request(request)
task = JSON.parse(response.body)['attributes']
puts "Created task: #{task['action']} (ID: #{task['id']})"
puts "Sequence: #{task['sequence_id']}, Offset: #{task['time_offset']}s"
puts "Payload: #{task['payload']}"
Update Schedule Task
PATCH /api/client/servers/{server}/schedules/{schedule}/tasks/{task}
Delete Schedule Task
DELETE /api/client/servers/{server}/schedules/{schedule}/tasks/{task}
Common Schedule Patterns
Daily Server Restart
{
"name": "Daily Restart",
"minute": "0",
"hour": "4",
"day_of_month": "*",
"month": "*",
"day_of_week": "*",
"tasks": [
{
"action": "command",
"payload": "say Server restarting in 30 seconds!",
"time_offset": 0
},
{
"action": "power",
"payload": "restart",
"time_offset": 30
}
]
}
Weekly Backup with Cleanup
{
"name": "Weekly Maintenance",
"minute": "0",
"hour": "3",
"day_of_month": "*",
"month": "*",
"day_of_week": "0",
"tasks": [
{
"action": "command",
"payload": "save-all",
"time_offset": 0
},
{
"action": "backup",
"payload": "Weekly backup",
"time_offset": 10
},
{
"action": "command",
"payload": "say Weekly backup completed",
"time_offset": 300
}
]
}
Hourly Resource Check
{
"name": "Resource Monitor",
"minute": "0",
"hour": "*",
"day_of_month": "*",
"month": "*",
"day_of_week": "*",
"only_when_online": true,
"tasks": [
{
"action": "command",
"payload": "memory",
"time_offset": 0
},
{
"action": "command",
"payload": "tps",
"time_offset": 5
}
]
}
Schedule Best Practices
Timing Considerations
- Avoid peak hours: Schedule intensive tasks during low usage periods
- Stagger schedules: Don't run multiple heavy tasks simultaneously
- Time zones: All times are in server timezone (usually UTC)
- Buffer time: Add delays between tasks to prevent conflicts
Task Sequencing
- Order matters: Tasks execute in sequence_id order
- Use time_offset: Add delays between tasks for proper execution
- Error handling: Use continue_on_failure appropriately
- Test first: Execute schedules manually before enabling
Resource Management
- Monitor performance: Watch server performance during scheduled tasks
- Backup timing: Schedule backups when server load is low
- Restart coordination: Notify users before automated restarts
- Cleanup tasks: Regular cleanup of logs and temporary files
Security
- Limit permissions: Only grant schedule permissions to trusted users
- Validate commands: Ensure scheduled commands are safe
- Monitor execution: Review schedule logs regularly
- Disable unused: Deactivate schedules that are no longer needed
Schedule Limits and Quotas
Default Limits
| Resource | Default Limit | Description |
|---|---|---|
| Schedules per server | 10-50 | Varies by hosting plan |
| Tasks per schedule | 20 | Maximum tasks in one schedule |
| Execution timeout | 900 seconds | Maximum task execution time |
| Concurrent schedules | 3 | Maximum simultaneous executions |
Performance Considerations
- Heavy operations: Backups and restarts consume significant resources
- Command execution: Long-running commands may timeout
- Schedule overlap: Prevent schedules from overlapping execution
- Resource monitoring: Monitor CPU and memory during scheduled tasks
Common Error Codes
| Status | Code | Description |
|---|---|---|
| 400 | TooManySchedulesException | Schedule limit reached |
| 400 | BadRequestHttpException | Invalid schedule configuration |
| 401 | InvalidCredentialsException | Invalid API key |
| 403 | InsufficientPermissionsException | Missing required permissions |
| 404 | NotFoundHttpException | Schedule not found |
| 409 | ConflictingServerStateException | Schedule already running |
| 422 | ValidationException | Invalid request data |
Required Permissions
Schedule operations require specific permissions:
| Permission | Description |
|---|---|
schedule.read | View schedules and tasks |
schedule.create | Create new schedules |
schedule.update | Modify existing schedules |
schedule.delete | Delete schedules |
schedule.execute | Manually trigger schedules |
Monitoring Schedule Execution
Execution Tracking
Monitor schedule execution through:
last_run_at: Last successful execution timenext_run_at: Next scheduled execution timeis_processing: Current execution status- Task logs: Individual task execution results
Troubleshooting
Common schedule issues:
- Cron expression errors: Validate cron syntax
- Permission issues: Ensure proper API permissions
- Resource conflicts: Check for overlapping schedules
- Server state: Verify server is in correct state for tasks
Source References
Controller: ScheduleController
Task Controller: ScheduleTaskController
Routes: api-client.php - Schedule endpoints
Schedule Model: Schedule.php
Task Model: Task.php
Schedule Service: ScheduleCreationService
Next Steps
- Explore Backup Management for automated backup creation
- Check Server Management for power and command operations
- Review File Management for scheduled file operations