Schedules and tasks
9 source-verified client API operations in Aquadactyl.
Generated from Aquadactyl 2bfd6ae2a30c. Read authentication and conventions first.
GET /api/client/servers/{server}/schedules
Returns all the schedules belonging to a given server.
Access: Client API key or authenticated panel session; schedule.read.
Source: Route · Controller · Request validation
Validation is inherited from ApplicationApiRequest.php.
Path parameters: server. See identifiers.
Additional authorization checks
if (!parent::authorize()) {
return false;
}
$server = $this->route()->parameter('server');
$schedule = $this->route()->parameter('schedule');
if ($server instanceof Server && $schedule instanceof Schedule) {
$task = $this->route()->parameter('task');
if ($schedule->server_id !== $server->id || ($task instanceof Task && $task->schedule_id !== $schedule->id)) {
throw new NotFoundHttpException('The requested resource does not exist on the system.');
}
}
return true;Response
Success: 200. Response attributes: Client ScheduleTransformer. Collections use the list envelope described in conventions.
Response construction and endpoint behavior
This source excerpt includes conditional responses, metadata, pagination, and service calls for this operation.
$schedules = $server->schedules->loadMissing('tasks');
return $this->fractal->collection($schedules)
->transformWith($this->getTransformer(ScheduleTransformer::class))
->toArray();Example request
curl --get "${PANEL_URL}/api/client/servers/SERVER_UUID/schedules" \
--header "Authorization: Bearer ${CLIENT_API_KEY}" \
--header "Accept: application/json"POST /api/client/servers/{server}/schedules
Store a new schedule for a server.
Access: Client API key or authenticated panel session; schedule.create.
Source: Route · Controller · Request validation
Model constraints: Schedule.php (including runtime rules and uniqueness checks for updates).
Path parameters: server. See identifiers.
Input fields
Rules use Laravel validation syntax. Dotted keys describe nested objects; * describes each array member. Model-derived rules are shown as their source expressions; model methods can add runtime constraints.
| Field | Validation |
|---|---|
name | ['required', 'string', 'max:191'] |
is_active | array_merge(['filled'], ['boolean']) |
minute | ['required', 'string'] |
hour | ['required', 'string'] |
day_of_month | ['required', 'string'] |
day_of_week | ['required', 'string'] |
Other controller inputs: month, only_when_online.
Additional authorization checks
if (!parent::authorize()) {
return false;
}
$server = $this->route()->parameter('server');
$schedule = $this->route()->parameter('schedule');
if ($server instanceof Server && $schedule instanceof Schedule) {
$task = $this->route()->parameter('task');
if ($schedule->server_id !== $server->id || ($task instanceof Task && $task->schedule_id !== $schedule->id)) {
throw new NotFoundHttpException('The requested resource does not exist on the system.');
}
}
return true;Response
Success: 200. Response attributes: Client ScheduleTransformer. Collections use the list envelope described in conventions.
Response construction and endpoint behavior
This source excerpt includes conditional responses, metadata, pagination, and service calls for this operation.
$model = $this->repository->create([
'server_id' => $server->id,
'name' => $request->input('name'),
'cron_day_of_week' => $request->input('day_of_week'),
'cron_month' => $request->input('month'),
'cron_day_of_month' => $request->input('day_of_month'),
'cron_hour' => $request->input('hour'),
'cron_minute' => $request->input('minute'),
'is_active' => (bool) $request->input('is_active'),
'only_when_online' => (bool) $request->input('only_when_online'),
'next_run_at' => $this->getNextRunAt($request),
]);
Activity::event('server:schedule.create')
->subject($model)
->property('name', $model->name)
->log();
return $this->fractal->item($model)
->transformWith($this->getTransformer(ScheduleTransformer::class))
->toArray();GET /api/client/servers/{server}/schedules/{schedule}
Returns a specific schedule for the server.
Access: Client API key or authenticated panel session; schedule.read.
Source: Route · Controller · Request validation
Validation is inherited from ApplicationApiRequest.php.
Path parameters: server, schedule. See identifiers.
Additional authorization checks
if (!parent::authorize()) {
return false;
}
$server = $this->route()->parameter('server');
$schedule = $this->route()->parameter('schedule');
if ($server instanceof Server && $schedule instanceof Schedule) {
$task = $this->route()->parameter('task');
if ($schedule->server_id !== $server->id || ($task instanceof Task && $task->schedule_id !== $schedule->id)) {
throw new NotFoundHttpException('The requested resource does not exist on the system.');
}
}
return true;Response
Success: 200. Response attributes: Client ScheduleTransformer. Collections use the list envelope described in conventions.
Response construction and endpoint behavior
This source excerpt includes conditional responses, metadata, pagination, and service calls for this operation.
if ($schedule->server_id !== $server->id) {
throw new NotFoundHttpException();
}
$schedule->loadMissing('tasks');
return $this->fractal->item($schedule)
->transformWith($this->getTransformer(ScheduleTransformer::class))
->toArray();Example request
curl --get "${PANEL_URL}/api/client/servers/SERVER_UUID/schedules/RESOURCE_ID" \
--header "Authorization: Bearer ${CLIENT_API_KEY}" \
--header "Accept: application/json"POST /api/client/servers/{server}/schedules/{schedule}
Updates a given schedule with the new data provided.
Access: Client API key or authenticated panel session; schedule.update.
Source: Route · Controller · Request validation
Validation is inherited from StoreScheduleRequest.php.
Model constraints: Schedule.php (including runtime rules and uniqueness checks for updates).
Path parameters: server, schedule. See identifiers.
Input fields
Rules use Laravel validation syntax. Dotted keys describe nested objects; * describes each array member. Model-derived rules are shown as their source expressions; model methods can add runtime constraints.
| Field | Validation |
|---|---|
name | ['required', 'string', 'max:191'] |
is_active | array_merge(['filled'], ['boolean']) |
minute | ['required', 'string'] |
hour | ['required', 'string'] |
day_of_month | ['required', 'string'] |
day_of_week | ['required', 'string'] |
Other controller inputs: month, only_when_online.
Additional authorization checks
if (!parent::authorize()) {
return false;
}
$server = $this->route()->parameter('server');
$schedule = $this->route()->parameter('schedule');
if ($server instanceof Server && $schedule instanceof Schedule) {
$task = $this->route()->parameter('task');
if ($schedule->server_id !== $server->id || ($task instanceof Task && $task->schedule_id !== $schedule->id)) {
throw new NotFoundHttpException('The requested resource does not exist on the system.');
}
}
return true;Response
Success: 200. Response attributes: Client ScheduleTransformer. Collections use the list envelope described in conventions.
Response construction and endpoint behavior
This source excerpt includes conditional responses, metadata, pagination, and service calls for this operation.
$active = (bool) $request->input('is_active');
$data = [
'name' => $request->input('name'),
'cron_day_of_week' => $request->input('day_of_week'),
'cron_month' => $request->input('month'),
'cron_day_of_month' => $request->input('day_of_month'),
'cron_hour' => $request->input('hour'),
'cron_minute' => $request->input('minute'),
'is_active' => $active,
'only_when_online' => (bool) $request->input('only_when_online'),
'next_run_at' => $this->getNextRunAt($request),
];
if ($schedule->is_active !== $active) {
$data['is_processing'] = false;
}
$this->repository->update($schedule->id, $data);
Activity::event('server:schedule.update')
->subject($schedule)
->property(['name' => $schedule->name, 'active' => $active])
->log();
return $this->fractal->item($schedule->refresh())
->transformWith($this->getTransformer(ScheduleTransformer::class))
->toArray();POST /api/client/servers/{server}/schedules/{schedule}/execute
Executes a given schedule immediately rather than waiting on it's normally scheduled time to pass. This does not care about the schedule state. Tasks are not checked against their action permissions here. They cannot be created or modified without that permission, and anyone reaching this endpoint can already run them by re-pointing the cron expression.
Access: Client API key or authenticated panel session; schedule.update.
Source: Route · Controller · Request validation
Path parameters: server, schedule. See identifiers.
Response
Success: 202.
Response construction and endpoint behavior
This source excerpt includes conditional responses, metadata, pagination, and service calls for this operation.
$this->service->handle($schedule, true);
Activity::event('server:schedule.execute')->subject($schedule)->property('name', $schedule->name)->log();
return new JsonResponse([], JsonResponse::HTTP_ACCEPTED);DELETE /api/client/servers/{server}/schedules/{schedule}
Deletes a schedule and it's associated tasks.
Access: Client API key or authenticated panel session; schedule.delete.
Source: Route · Controller · Request validation
Validation is inherited from ApplicationApiRequest.php.
Path parameters: server, schedule. See identifiers.
Additional authorization checks
if (!parent::authorize()) {
return false;
}
$server = $this->route()->parameter('server');
$schedule = $this->route()->parameter('schedule');
if ($server instanceof Server && $schedule instanceof Schedule) {
$task = $this->route()->parameter('task');
if ($schedule->server_id !== $server->id || ($task instanceof Task && $task->schedule_id !== $schedule->id)) {
throw new NotFoundHttpException('The requested resource does not exist on the system.');
}
}
return true;Response
Success: 204 (empty body).
Response construction and endpoint behavior
This source excerpt includes conditional responses, metadata, pagination, and service calls for this operation.
$this->repository->delete($schedule->id);
Activity::event('server:schedule.delete')->subject($schedule)->property('name', $schedule->name)->log();
return new JsonResponse([], Response::HTTP_NO_CONTENT);POST /api/client/servers/{server}/schedules/{schedule}/tasks
Create a new task for a given schedule and store it in the database.
Access: Client API key or authenticated panel session; schedule.update.
Source: Route · Controller · Request validation
Path parameters: server, schedule. See identifiers.
Input fields
Rules use Laravel validation syntax. Dotted keys describe nested objects; * describes each array member. Model-derived rules are shown as their source expressions; model methods can add runtime constraints.
| Field | Validation |
|---|---|
action | 'required|in:command,power,backup' |
payload | [ 'required_unless:action,backup', 'string', 'nullable', Rule::when($this->input('action') === Task::ACTION_POWER, [Rule::in(Task::POWER_ACTIONS)]), ] |
time_offset | 'required|numeric|min:0|max:900' |
sequence_id | 'sometimes|required|numeric|min:1' |
continue_on_failure | 'sometimes|required|boolean' |
Additional authorization checks
if (!parent::authorize()) {
return false;
}
$permission = Task::permissionForAction((string) $this->input('action'), $this->input('payload'));
if (is_null($permission)) {
return true;
}
$server = $this->route()->parameter('server');
return $server instanceof Server && $this->user()->can($permission, $server);Response
Success: 200. Response attributes: Client TaskTransformer. Collections use the list envelope described in conventions.
Response construction and endpoint behavior
This source excerpt includes conditional responses, metadata, pagination, and service calls for this operation.
$limit = config('pterodactyl.client_features.schedules.per_schedule_task_limit', 10);
if ($schedule->tasks()->count() >= $limit) {
throw new ServiceLimitExceededException("Schedules may not have more than $limit tasks associated with them. Creating this task would put this schedule over the limit.");
}
if ($server->backup_limit === 0 && $request->action === 'backup') {
throw new HttpForbiddenException("A backup task cannot be created when the server's backup limit is set to 0.");
}
$lastTask = $schedule->tasks()->orderByDesc('sequence_id')->first();
$task = $this->connection->transaction(function () use ($request, $schedule, $lastTask) {
$sequenceId = ($lastTask->sequence_id ?? 0) + 1;
$requestSequenceId = $request->integer('sequence_id', $sequenceId);
if ($requestSequenceId < 1) {
$requestSequenceId = 1;
}
if ($requestSequenceId < $sequenceId) {
$schedule->tasks()
->where('sequence_id', '>=', $requestSequenceId)
->increment('sequence_id');
$sequenceId = $requestSequenceId;
}
return $this->repository->create([
'schedule_id' => $schedule->id,
'sequence_id' => $sequenceId,
'action' => $request->input('action'),
'payload' => $request->input('payload') ?? '',
'time_offset' => $request->input('time_offset'),
'continue_on_failure' => $request->boolean('continue_on_failure'),
]);
});
Activity::event('server:task.create')
->subject($schedule, $task)
->property(['name' => $schedule->name, 'action' => $task->action, 'payload' => $task->payload])
->log();
return $this->fractal->item($task)
->transformWith($this->getTransformer(TaskTransformer::class))
->toArray();POST /api/client/servers/{server}/schedules/{schedule}/tasks/{task}
Updates a given task for a server.
Access: Client API key or authenticated panel session; schedule.update.
Source: Route · Controller · Request validation
Path parameters: server, schedule, task. See identifiers.
Input fields
Rules use Laravel validation syntax. Dotted keys describe nested objects; * describes each array member. Model-derived rules are shown as their source expressions; model methods can add runtime constraints.
| Field | Validation |
|---|---|
action | 'required|in:command,power,backup' |
payload | [ 'required_unless:action,backup', 'string', 'nullable', Rule::when($this->input('action') === Task::ACTION_POWER, [Rule::in(Task::POWER_ACTIONS)]), ] |
time_offset | 'required|numeric|min:0|max:900' |
sequence_id | 'sometimes|required|numeric|min:1' |
continue_on_failure | 'sometimes|required|boolean' |
Additional authorization checks
if (!parent::authorize()) {
return false;
}
$permission = Task::permissionForAction((string) $this->input('action'), $this->input('payload'));
if (is_null($permission)) {
return true;
}
$server = $this->route()->parameter('server');
return $server instanceof Server && $this->user()->can($permission, $server);Response
Success: 200. Response attributes: Client TaskTransformer. Collections use the list envelope described in conventions.
Response construction and endpoint behavior
This source excerpt includes conditional responses, metadata, pagination, and service calls for this operation.
if ($schedule->id !== $task->schedule_id || $server->id !== $schedule->server_id) {
throw new NotFoundHttpException();
}
if ($server->backup_limit === 0 && $request->action === 'backup') {
throw new HttpForbiddenException("A backup task cannot be created when the server's backup limit is set to 0.");
}
$this->connection->transaction(function () use ($request, $schedule, $task) {
$sequenceId = $request->integer('sequence_id', $task->sequence_id);
if ($sequenceId < 1) {
$sequenceId = 1;
}
if ($sequenceId < $task->sequence_id) {
$schedule->tasks()
->where('sequence_id', '>=', $sequenceId)
->where('sequence_id', '<', $task->sequence_id)
->increment('sequence_id');
} elseif ($sequenceId > $task->sequence_id) {
$schedule->tasks()
->where('sequence_id', '>', $task->sequence_id)
->where('sequence_id', '<=', $sequenceId)
->decrement('sequence_id');
}
$this->repository->update($task->id, [
'sequence_id' => $sequenceId,
'action' => $request->input('action'),
'payload' => $request->input('payload') ?? '',
'time_offset' => $request->input('time_offset'),
'continue_on_failure' => $request->boolean('continue_on_failure'),
]);
});
Activity::event('server:task.update')
->subject($schedule, $task)
->property(['name' => $schedule->name, 'action' => $task->action, 'payload' => $task->payload])
->log();
return $this->fractal->item($task->refresh())
->transformWith($this->getTransformer(TaskTransformer::class))
->toArray();DELETE /api/client/servers/{server}/schedules/{schedule}/tasks/{task}
Delete a given task for a schedule. If there are subsequent tasks stored in the database for this schedule their sequence IDs are decremented properly.
Access: Client API key or authenticated panel session.
Source: Route · Controller · Request validation
Validation is inherited from ApplicationApiRequest.php.
Path parameters: server, schedule, task. See identifiers.
Response
Success: 204 (empty body).
Response construction and endpoint behavior
This source excerpt includes conditional responses, metadata, pagination, and service calls for this operation.
if ($task->schedule_id !== $schedule->id || $schedule->server_id !== $server->id) {
throw new NotFoundHttpException();
}
if (!$request->user()->can(Permission::ACTION_SCHEDULE_UPDATE, $server)) {
throw new HttpForbiddenException('You do not have permission to perform this action.');
}
$schedule->tasks()
->where('sequence_id', '>', $task->sequence_id)
->decrement('sequence_id');
$task->delete();
Activity::event('server:task.delete')->subject($schedule, $task)->property('name', $schedule->name)->log();
return new JsonResponse(null, Response::HTTP_NO_CONTENT);