SDK Cheat Sheet

Every operation the SDK supports, one line of PHP + one line of Python. For the full documentation of each call (parameters, defaults, response fields, error slugs), follow the link on the right. Assumes a client already constructed as:

<?php
require __DIR__ . '/api-panel-php-sdk-1.0.0/autoload.php';

use XtreamAI\PanelApi\PanelApiClient;

$client = new PanelApiClient(
    baseUrl: 'https://<your-panel-domain>',
    token:   '<your-api-key>',
);
from xtream_ai_panel_api import PanelApiClient

client = PanelApiClient(
    base_url="https://<your-panel-domain>",
    token="<your-api-key>",
)

Identity

PHP Python What it returns
$client->me->get() client.me.get() Caller identity (type, scopes, billing snapshot). See Get caller identity.
$client->health() client.health() Public liveness probe. No auth required. See Health check.

Lines

PHP Python Docs
$client->lines->list(limit: 50) client.lines.list(limit=50) List lines
$client->lines->get(172504295) client.lines.get(172504295) Retrieve line
$client->lines->create(packageId: 42, memberId: 100) client.lines.create(package_id=42, member_id=100) Create line
$client->lines->update(172504295, notes: 'renewed') client.lines.update(172504295, notes="renewed") Update line
$client->lines->enable(172504295) client.lines.enable(172504295) Enable line
$client->lines->disable(172504295) client.lines.disable(172504295) Disable line
$client->lines->renew(172504295, packageId: 42) client.lines.renew(172504295, package_id=42) Renew line
$client->lines->resetPassword(172504295) client.lines.reset_password(172504295) Reset password
$client->lines->delete(172504295) client.lines.delete(172504295) Delete line
$client->lines->connections(172504295) client.lines.connections(172504295) List connections

Catalog

PHP Python Docs
$client->catalog->packages() client.catalog.packages() List packages
$client->catalog->bouquets() client.catalog.bouquets() List bouquets
$client->catalog->streams(limit: 100) client.catalog.streams(limit=100) List live streams
$client->catalog->stream(482) client.catalog.stream(482) Retrieve stream
$client->catalog->vods(search: 'inception') client.catalog.vods(search="inception") List VODs
$client->catalog->vod(9042) client.catalog.vod(9042) Retrieve VOD

Resellers

Admin-only for most operations. A reseller with subresellers:write can create sub-resellers under itself.

PHP Python Docs
$client->resellers->list() client.resellers.list() List resellers
$client->resellers->get(260595) client.resellers.get(260595) Retrieve reseller
$client->resellers->create(username: 'newco', memberGroupId: 3) client.resellers.create(username="newco", member_group_id=3) Create reseller
$client->resellers->update(260595, notes: '...') client.resellers.update(260595, notes="...") Update reseller
$client->resellers->billing(260595) client.resellers.billing(260595) Read billing
$client->resellers->adjustBilling(260595, delta: 100) client.resellers.adjust_billing(260595, delta=100) Adjust billing

Pagination

Every list() returns a PaginatedResponse with items and an opaque nextCursor (next_cursor). The SDK does not loop for you — pass the cursor back to fetch the next page.

<?php
$page = $client->lines->list(limit: 50);
while (true) {
    foreach ($page->items as $line) { /* ... */ }
    if ($page->nextCursor === null) break;
    $page = $client->lines->list(limit: 50, cursor: $page->nextCursor);
}
page = client.lines.list(limit=50)
while True:
    for line in page.items:
        pass  # ...
    if page.next_cursor is None:
        break
    page = client.lines.list(limit=50, cursor=page.next_cursor)

Full walk-through in SDKs Overview → Pagination.

Idempotency

Every write auto-generates a UUID. Override with a stable business key when the caller is retriable (webhooks, job queues, cron):

<?php
$client->lines->create(
    packageId: 42, memberId: 100, username: 'johndoe',
    idempotencyKey: 'invoice-INV-42',
);
client.lines.create(
    package_id=42, member_id=100, username="johndoe",
    idempotency_key="invoice-INV-42",
)

Full contract in Retry and Idempotency with the SDK.

Error handling

Catch specific first, base class last. Every exception has .slug, .request_id, .status_code, .details.

<?php
use XtreamAI\PanelApi\Exceptions\{
    InsufficientCreditsException, ValidationException, PanelApiException,
};

try {
    $client->lines->create(packageId: 42, memberId: 100);
} catch (InsufficientCreditsException $e) {
    // Reseller is broke.
} catch (ValidationException $e) {
    error_log("bad field: " . $e->field());
} catch (PanelApiException $e) {
    error_log("api error req={$e->requestId} slug={$e->slug}");
}
from xtream_ai_panel_api.exceptions import (
    InsufficientCreditsException, ValidationException, PanelApiException,
)

try:
    client.lines.create(package_id=42, member_id=100)
except InsufficientCreditsException:
    pass  # Reseller is broke.
except ValidationException as e:
    print("bad field:", e.field)
except PanelApiException as e:
    print(f"api error req={e.request_id} slug={e.slug}")

Full exception hierarchy in Errors with the SDK.

Common one-shot flows

Provision a new customer after payment

<?php
$line = $client->lines->create(
    packageId:      42,
    memberId:       100,
    email:          'johndoe@example.com',
    idempotencyKey: 'payment-'.$paymentId,
);
echo "Deliver credentials: {$line->username} / {$line->password}", PHP_EOL;
line = client.lines.create(
    package_id=42, member_id=100, email="johndoe@example.com",
    idempotency_key=f"payment-{payment_id}",
)
print(f"Deliver credentials: {line.username} / {line.password}")

Renew a subscription

<?php
$line = $client->lines->renew(
    $lineId,
    packageId: 42,
    idempotencyKey: 'renewal-'.$invoiceId,
);
echo "New expiry: {$line->expDate}", PHP_EOL;
line = client.lines.renew(
    line_id, package_id=42,
    idempotency_key=f"renewal-{invoice_id}",
)
print(f"New expiry: {line.exp_date}")

Suspend a delinquent account

<?php
$client->lines->disable($lineId, idempotencyKey: 'suspend-'.$lineId);
client.lines.disable(line_id, idempotency_key=f"suspend-{line_id}")

Rotate a compromised customer password

<?php
$newPassword = $client->lines->resetPassword($lineId);
notifyCustomer($newPassword);
new_password = client.lines.reset_password(line_id)
notify_customer(new_password)

Reconcile: is this line still active on the panel?

<?php
try {
    $line = $client->lines->get($lineId);
    $active = $line->enabled && !$line->isExpired;
} catch (\XtreamAI\PanelApi\Exceptions\NotFoundException) {
    $active = false;
}
from xtream_ai_panel_api.exceptions import NotFoundException

try:
    line = client.lines.get(line_id)
    active = line.enabled and not line.is_expired
except NotFoundException:
    active = False

Constants worth memorizing

  • Default timeout: 30 s per request.
  • Default retries: 3 attempts on top of the original.
  • Max limit on any list endpoint: 100 (some default 50).
  • Idempotency window on the server: at least 24 hours.
  • 429 Retry-After cap honored by the SDK: 60 s.

See also