PL

Ploi PHP SDK Expert

Provides best practices and code patterns for the Ploi PHP SDK.

Install

mkdir -p .claude/skills/ploi-php-sdk-expert && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/13424" && unzip -o skill.zip -d .claude/skills/ploi-php-sdk-expert && rm skill.zip

Installs to .claude/skills/ploi-php-sdk-expert

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Best practices for using the Ploi PHP SDK to interact with the Ploi.io server management API
92 charsno explicit “when” trigger
Intermediate

Key capabilities

  • Initialize the Ploi PHP SDK client with an API token
  • Access resources using fluent parent-child chaining
  • Perform CRUD operations on Ploi API resources
  • Handle pagination for resource listings
  • Manage server-level resources like sites, databases, and cronjobs
  • Manage site-level resources such as certificates, repositories, and deployments

How it works

The skill provides best practices for using the Ploi PHP SDK, covering client initialization, fluent resource chaining, CRUD operations, pagination, and error handling for interacting with the Ploi.io API.

Inputs & outputs

You give it
Request to interact with the Ploi.io server management API using the Ploi PHP SDK
You get back
PHP code examples for client initialization, resource chaining, and API operations

When to use Ploi PHP SDK Expert

  • Automating server provisioning
  • Managing site deployments
  • Listing server databases
  • Managing SSL certificates

About this skill

Ploi PHP SDK Expert

Context

This skill covers the Ploi PHP SDK (ploi/ploi-php-sdk), a PHP wrapper around the Ploi.io server management REST API. It uses Guzzle HTTP under the hood and provides a fluent, chainable interface for managing servers, sites, databases, deployments, and more.

Scope: Initializing the SDK client, chaining resources, performing CRUD operations on all Ploi API resources, handling pagination, error handling, and understanding the resource hierarchy.

Rules

Initialization

  • Always instantiate the client with an API token: $ploi = new \Ploi\Ploi($apiToken);
  • The token can also be set after construction: $ploi->setApiToken($token);
  • The SDK auto-configures a Guzzle client pointing at https://ploi.io/api/ with JSON content headers.

Fluent Resource Chaining

  • Access resources using the fluent parent-child chain. Always start from the $ploi instance and drill down:
    • $ploi->server($serverId) to target a server
    • $ploi->server($serverId)->sites($siteId) to target a site on a server
    • $ploi->server($serverId)->sites($siteId)->certificates() to access certificates on a site
  • Pass the resource ID when you first access the resource in the chain, not as a separate call.
  • Singular and plural method names are interchangeable on the entry point: $ploi->server() and $ploi->servers() both return a Server resource.

Resource Hierarchy

  • Server-level resources (accessed from $ploi->server($id)->): sites(), databases(), cronjobs(), daemons(), sshKeys(), services(), networkRules(), systemUsers(), opcache(), insights(), loadBalancer()
  • Site-level resources (accessed from ->sites($id)->): certificates(), repository(), queues(), deployment(), app(), environment(), alias(), redirects(), fastCgi(), authUser(), robots(), tenants(), monitors(), nginxConfiguration()
  • Database-level resources (accessed from ->databases($id)->): backups(), users()
  • Top-level resources (accessed from $ploi->): project(), scripts(), statusPage(), user(), webserverTemplates(), fileBackup()

Fetching Data

  • Use ->get() to list all resources or fetch a single one by ID.
  • ->get() returns a Ploi\Http\Response object. Use ->getJson() for a stdClass, ->getData() for the data property, or ->toArray() for the full structure.
  • When calling ->get($id), the ID parameter is optional if you already passed it during chaining.

Creating Resources

  • Each resource has a create() method with named parameters matching the API. Always check the method signature for required vs. optional parameters.
  • Pass options as method arguments, not as raw arrays (unless the method signature accepts one).

Pagination

  • Resources with HasPagination support ->page($pageNumber, $perPage) and ->perPage($amount).
  • Example: $ploi->server($id)->sites()->page(2, 15);

Error Handling

  • Wrap API calls in try/catch blocks. The SDK throws typed exceptions based on HTTP status codes:
    • Ploi\Exceptions\Http\Unauthenticated (401)
    • Ploi\Exceptions\Http\NotFound (404)
    • Ploi\Exceptions\Http\NotAllowed (405)
    • Ploi\Exceptions\Http\NotValid (422)
    • Ploi\Exceptions\Http\TooManyAttempts (429)
    • Ploi\Exceptions\Http\InternalServerError (500)
    • Ploi\Exceptions\Http\PerformingMaintenance (503)
  • A Ploi\Exceptions\Resource\RequiresId is thrown when a resource method needs an ID but none was provided.

Deployment

  • Use the deployment() resource on a site: $ploi->server($id)->sites($siteId)->deployment()->deploy();
  • Access and update deploy scripts: ->deployment()->deployScript() and ->deployment()->updateDeployScript($script).
  • Quick deploy toggle is on the repository resource: ->repository()->toggleQuickDeploy().

API Call Options

  • When making raw API calls or extending the SDK, pass body data as ['body' => json_encode([...])] (Guzzle options format).
  • Only get, post, patch, and delete HTTP methods are supported.

Examples

Initialize the client

use Ploi\Ploi;

$ploi = new Ploi('your-api-token');

List all servers with pagination

$response = $ploi->servers()->page(1, 10);
$servers = $response->getData();

Get a single server

$server = $ploi->server(123)->get();
echo $server->getData()->name;

Create a site on a server

$response = $ploi->server(123)->sites()->create(
    domain: 'example.com',
    webDirectory: '/public',
    projectRoot: '/',
    systemUser: 'ploi'
);

Install a repository and deploy

$ploi->server(123)->sites(456)->repository()->install(
    provider: 'github',
    branch: 'main',
    name: 'owner/repo'
);

$ploi->server(123)->sites(456)->deployment()->deploy();

Manage SSL certificates

// List certificates
$certs = $ploi->server(123)->sites(456)->certificates()->get();

// Create a Let's Encrypt certificate
$ploi->server(123)->sites(456)->certificates()->create(
    certificate: 'example.com',
    type: 'letsencrypt'
);

Database management

// Create a database
$ploi->server(123)->databases()->create(
    name: 'my_app',
    user: 'my_user',
    password: 'secret'
);

// Set up automated backups
$ploi->server(123)->databases(789)->backups()->create(
    interval: 1440,
    type: 'to_server'
);

Queue and worker management

$ploi->server(123)->sites(456)->queues()->create(
    connection: 'redis',
    queue: 'default',
    maximumSeconds: 60,
    sleep: 30,
    processes: 3,
    maximumTries: 3
);

Update environment variables

$ploi->server(123)->sites(456)->environment()->update(
    content: "APP_ENV=production\nAPP_DEBUG=false\nAPP_KEY=base64:..."
);

Error handling

use Ploi\Exceptions\Http\NotFound;
use Ploi\Exceptions\Http\NotValid;
use Ploi\Exceptions\Http\Unauthenticated;

try {
    $server = $ploi->server(999)->get();
} catch (Unauthenticated $e) {
    // Invalid API token
} catch (NotFound $e) {
    // Server not found
} catch (NotValid $e) {
    // Validation error - check the response body for details
}

Manage daemons

// Create a daemon
$ploi->server(123)->daemons()->create(
    command: 'php artisan horizon',
    systemUser: 'ploi',
    processes: 1,
    directory: '/home/ploi/example.com'
);

// Restart a daemon
$ploi->server(123)->daemons(789)->restart();

Manage cron jobs

$ploi->server(123)->cronjobs()->create(
    command: 'php /home/ploi/example.com/artisan schedule:run',
    frequency: '* * * * *',
    user: 'ploi'
);

Service management

// Restart nginx
$ploi->server(123)->services('nginx')->restart();

// Restart MySQL
$ploi->server(123)->services('mysql')->restart();

Anti-patterns

Do not re-fetch the client for every call

// Bad - creating multiple instances
$servers = (new Ploi($token))->servers()->get();
$sites = (new Ploi($token))->server(1)->sites()->get();

// Good - reuse the client
$ploi = new Ploi($token);
$servers = $ploi->servers()->get();
$sites = $ploi->server(1)->sites()->get();

Do not manually build API URLs

// Bad - constructing URLs by hand
$ploi->makeAPICall('servers/123/sites/456/certificates', 'get');

// Good - use the fluent chain
$ploi->server(123)->sites(456)->certificates()->get();

Do not ignore typed exceptions

// Bad - catching generic exceptions
try {
    $ploi->server(123)->get();
} catch (\Exception $e) {
    echo "Something went wrong";
}

// Good - catch specific exceptions for proper handling
try {
    $ploi->server(123)->get();
} catch (TooManyAttempts $e) {
    sleep(60); // Wait and retry for rate limiting
} catch (NotFound $e) {
    // Handle missing resource
} catch (Unauthenticated $e) {
    // Handle invalid token
}

Do not pass IDs twice

// Bad - redundant ID passing
$ploi->server(123)->sites(456)->certificates()->get(789);
// And then again:
$ploi->server(123)->sites(456)->certificates(789)->get(789);

// Good - pass the ID once, either in the chain or in the method
$ploi->server(123)->sites(456)->certificates(789)->get();
// or
$ploi->server(123)->sites(456)->certificates()->get(789);

Do not access raw Guzzle responses when the SDK provides helpers

// Bad - decoding manually
$response = $ploi->servers()->get();
$body = json_decode($response->getResponse()->getBody()->getContents());

// Good - use the Response helper methods
$response = $ploi->servers()->get();
$data = $response->getData();      // Parsed data property
$json = $response->getJson();      // Full parsed JSON
$array = $response->toArray();     // Array with json + response

References

When not to use it

  • When not using the Ploi PHP SDK
  • When manually building API URLs is preferred
  • When generic exception handling is used instead of typed exceptions

Limitations

  • The SDK uses Guzzle HTTP under the hood.
  • Only `get`, `post`, `patch`, and `delete` HTTP methods are supported.
  • Requires an API token for client initialization.

How it compares

This skill provides specific best practices and fluent chaining examples for the Ploi PHP SDK, unlike generic API interaction or manual HTTP requests.

Compared to similar skills

Ploi PHP SDK Expert side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
Ploi PHP SDK Expert (this skill)05moNo flagsIntermediate
laravel-specialist123moNo flagsIntermediate
developing-with-turbo-streams15moNo flagsIntermediate
payment-integration16moReviewIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

You might also like

laravel-specialist

Jeffallan

Use when building Laravel 10+ applications requiring Eloquent ORM, API resources, or queue systems. Invoke for Laravel models, Livewire components, Sanctum authentication, Horizon queues.

1215

developing-with-turbo-streams

hotwired-laravel

Basics of developing with Turbo Streams in web applications. Activate when working on projects that utilize Turbo Streams for enhancing user experience through real-time updates, dynamic content changes, and partial page updates without full reloads.

15

payment-integration

mrgoonie

Integrate payments with SePay (VietQR), Polar, Stripe, Paddle (MoR subscriptions), Creem.io (licensing). Checkout, webhooks, subscriptions, QR codes, multi-provider orders.

13

developing-with-prism

prism-php

Guide for developing with Prism PHP package - a Laravel package for integrating LLMs. Activate or use when working with Prism features including text generation, structured output, embeddings, image generation, audio processing, streaming, tools/function calling, or any LLM provider integration (OpenAI, Anthropic, Gemini, Mistral, Groq, XAI, DeepSeek, OpenRouter, Ollama, VoyageAI, ElevenLabs). Activate for any Prism-related development tasks.

12

laravel-query-builder

relaticle

Build filtered, sorted, and included API endpoints using spatie/laravel-query-builder. Activates when working with QueryBuilder, AllowedFilter, AllowedSort, AllowedInclude, or when the user mentions query parameters, API filtering, sorting, includes, or spatie/laravel-query-builder.

00

echo-development

WageFolabessy

Develops real-time broadcasting with Laravel Echo. Activates when setting up broadcasting (Reverb, Pusher, Ably); creating ShouldBroadcast events; defining broadcast channels (public, private, presence, encrypted); authorizing channels; configuring Echo; listening for events; implementing client eve

00

Search skills

Search the agent skills registry