Delete a line

Permanently delete a line. Related rows (bouquet assignments in user_bouquets, and contact info in admin_user_contact_info / reseller_user_contact_info) are cleaned up in the same operation, so no orphan rows are left behind.

Deletion does not refund credits, matching the panel UI. In users billing mode the slot is released automatically because the active-users count reads live from the users table.

Reseller keys are subject to the member_groups.delete_users permission: if the reseller's group is not allowed to delete customers, the endpoint returns 403 delete_not_allowed. This mirrors the guard the reseller UI applies, so a POST from an API integration cannot bypass what the UI itself would block.

The response has a compact shape, not the full line object: just {id, username, deleted}. Use it to confirm the row is gone before you take a follow-up action in your billing system.

Endpoint

POST https://<your-panel-domain>/panel-api/v1/lines/{id}/delete

Authentication

Bearer token in the Authorization header. See Panel API authentication.

Required scope

lines:write.

Idempotency

Required. Send an Idempotency-Key header on every call. Retrying the same key returns the cached response; a missing header returns 400 missing_idempotency_key. A retry of the same delete after the row is gone (with the same idempotency key) returns the original deleted: true payload, not a 404.

Path parameters

Name Type Description
id int The line id to delete.

Request body

Empty. Send an empty JSON body {} (or no body at all).

Response

200 OK with the compact shape:

{
  "id": 172504297,
  "username": "u_a1b2c3d4",
  "deleted": true
}

The panel confirms the row is gone before responding with deleted: true. If the underlying cascade left the row in place for any reason, the endpoint returns 500 delete_failed and the row is not reported as deleted.

Examples

cURL

curl -X POST https://<your-panel-domain>/panel-api/v1/lines/172504297/delete \
  -H "Authorization: Bearer <your-api-key>" \
  -H "Idempotency-Key: line-172504297-delete-2026-08-08"

PHP SDK

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>');

// delete returns a bool: true once the panel confirms the row is gone.
$deleted = $client->lines->delete(
    id:             172504297,
    idempotencyKey: 'line-172504297-delete-2026-08-08',
);
echo $deleted ? 'gone' : 'still there', PHP_EOL;

Python SDK

from xtream_ai_panel_api import PanelApiClient

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

# delete returns a bool: True once the panel confirms the row is gone.
deleted = client.lines.delete(
    id=172504297,
    idempotency_key="line-172504297-delete-2026-08-08",
)
print(deleted)  # True

Errors

HTTP Error slug When it happens How to fix
400 missing_idempotency_key The Idempotency-Key header was not sent. Send a per-intent key on every write.
401 invalid_key Token is unknown, expired, disabled, or deleted. Check the token or issue a new one.
403 delete_not_allowed Reseller group has delete_users=0. Change the setting on the member group, or call from an admin key.
403 insufficient_scope Token lacks lines:write. Issue a key with the scope.
404 not_found The line id does not exist (never did, or was already deleted with a different idempotency key), or a reseller key targeted a line it does not own. Verify the id and ownership.
409 idempotency_conflict Same key was reused with a different body. Use a fresh key.
409 idempotency_in_flight Same key is still processing. Retry after a moment.
429 rate_limited The key hit its per-minute cap. Back off and retry after Retry-After seconds.
500 delete_failed The cascade did not remove the row (deadlock, permission issue). Retry with a fresh key; if it persists, contact support.

See also