Enable a line

If you are starting a new integration instead of migrating an existing one, prefer the native v1 API with the official SDKs. The XC dialect keeps compatibility with legacy tooling; the native dialect gives you typed models, header-based idempotency, and structured HTTP status codes.

action=enable_line flips the reseller-visible enabled flag on a subscriber line to true. The request is translated to the native POST /panel-api/v1/lines/{id}/enable and rewrapped in the classic {"status": "STATUS_SUCCESS", "data": {...}} envelope.

Two flags govern whether a line serves traffic:

  • enabled is the reseller-visible toggle. enable_line and disable_line move it.
  • admin_enabled is the admin override. If it is false, the line stays blocked no matter what enabled says. Only edit_line on an admin key can change it.

Enabling a line does not extend its expiry. If the line is already past exp_date, it remains effectively unusable until extend_line or an edit sets a future exp_date.

If the caller is a reseller in users billing mode and the line is not a trial, the endpoint re-checks the slot cap before flipping. Enabling a line that would push the reseller over the slot limit returns STATUS_INSUFFICIENT_CREDITS with slot_limit_exceeded. This is the same guard create_line runs. Reseller in credits mode and admin keys skip this check.

Endpoint

POST https://<your-panel-domain>/panel-api/xc/{accesscode}/admin/index.php?action=enable_line

Both /admin/index.php and /reseller/index.php are accepted. The admin-versus-reseller decision comes from the key.

Authentication

Any one of these three forms:

  • ?api_key=<your-api-key> in the query string.
  • api_key=<your-api-key> in the POST body form field.
  • Authorization: Bearer <your-api-key> HTTP header.

See Authentication.

Required scope

lines:write.

Idempotency

Optional. Pass rid=<unique-per-operation> to opt in. Since enabling is naturally idempotent (twice-enabled stays enabled), the practical benefit is limited to replaying the response payload; the underlying flag is already at target. See the idempotency section.

Request body

Field Type Required Default Description
id int yes The line to enable.
rid string no Idempotency identifier.

Response

data is the full Line object with enabled=true. Same shape used by action=get_line.

{
  "status": "STATUS_SUCCESS",
  "data": {
    "id": 172511994,
    "username": "u_a1b2c3d4",
    "password": "Sup3rSecret1",
    "member_id": 100,
    "exp_date": 1849365538,
    "max_connections": 3,
    "is_trial": false,
    "is_restreamer": false,
    "enabled": true,
    "admin_enabled": true,
    "bouquets": [2, 4],
    "created_at": 1786207138
  }
}

HTTP status is always 200, even on failure.

Examples

cURL

curl -X POST "https://<your-panel-domain>/panel-api/xc/panel_api/admin/index.php?api_key=<your-api-key>&action=enable_line" \
  -d "id=172511994" \
  -d "rid=en-172511994-2026-01-15"

PHP (raw HTTP)

$url = 'https://<your-panel-domain>/panel-api/xc/panel_api/admin/index.php'
     . '?' . http_build_query(['api_key' => '<your-api-key>', 'action' => 'enable_line']);
$body = http_build_query([
    'id'  => 172511994,
    'rid' => 'en-172511994-' . bin2hex(random_bytes(8)),
]);
$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => $body,
]);
$resp = json_decode(curl_exec($ch), true);
curl_close($ch);
if (($resp['status'] ?? '') !== 'STATUS_SUCCESS') {
    throw new RuntimeException($resp['data']['message'] ?? 'enable_line failed');
}

Python (raw HTTP)

import requests, secrets

r = requests.post(
    "https://<your-panel-domain>/panel-api/xc/panel_api/admin/index.php",
    params={"api_key": "<your-api-key>", "action": "enable_line"},
    data={
        "id":  172511994,
        "rid": f"en-172511994-{secrets.token_hex(8)}",
    },
    timeout=30,
)
r.raise_for_status()
body = r.json()
if body.get("status") != "STATUS_SUCCESS":
    raise RuntimeError(body["data"].get("message", "enable_line failed"))

Errors

Response is always HTTP 200. Branch on status, then data.error.

status Error slug When it happens How to fix
STATUS_INVALID_DATA validation_error id is missing or empty. data.details.field is "id". Send a numeric id.
STATUS_FAILURE not_found The id does not exist, or a reseller key targeted a line owned by another reseller. Verify the id and ownership.
STATUS_INSUFFICIENT_CREDITS slot_limit_exceeded Reseller in users billing mode; enabling this non-trial line would push the reseller over its slot cap. Delete unused lines, disable a peer line, or raise the cap.
STATUS_NO_PERMISSIONS insufficient_scope The key does not have lines:write. Grant the scope.
STATUS_FAILURE idempotency_conflict Same rid reused with a different body. Pick a new rid.
STATUS_FAILURE idempotency_in_flight Same rid is still processing. Retry after a moment.
STATUS_FAILURE invalid_key Token missing, unknown, disabled, expired, or IP not in allow-list. Verify the token and the IP allow-list.
STATUS_FAILURE rate_limited Per-minute cap or per-IP cap exceeded. Back off.
STATUS_FAILURE api_disabled Panel API is switched off. Contact the panel admin.

See also