action=user_info
Returns the identity of the API key that made the call. Admin keys get a small identity block (type, key metadata, scopes). Reseller keys additionally get their reg_user_id, member_group_id, member_group_name, the current billing snapshot (mode, credits or slots), and the effective permissions object.
This is the safest first request to make against a freshly issued key. It exercises the full auth pipeline (token lookup, IP allow-list, scope filter, rate limit), it has no side effects, and it echoes back exactly the information the panel has about the key.
Endpoint
GET https://<your-panel-domain>/panel-api/xc/{accesscode}/admin/index.php?action=user_info
POST https://<your-panel-domain>/panel-api/xc/{accesscode}/admin/index.php (with action=user_info in the body)
The {accesscode} segment is decorative. Both /admin/index.php and /reseller/index.php accept the same key types; the caller identity is inferred from the API key, not from the sub-path.
Authentication
Send the API key one of three ways.
?api_key=<token>query parameter.api_key=<token>in the POST body.Authorization: Bearer <token>header.
Required scope
None. Every valid API key can call user_info regardless of its scope set.
Query parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
action |
string | Yes | Must be user_info. |
|
api_key |
string | Yes (if not using Bearer) | The API key. Alternative: Authorization: Bearer. |
Response
The data object depends on the calling key type.
For an admin key, type is "admin" and the reseller-specific fields are null.
{
"status": "STATUS_SUCCESS",
"data": {
"type": "admin",
"reg_user_id": null,
"member_group_id": null,
"member_group_name": null,
"billing": null,
"permissions": null,
"key": {
"id": 4211,
"prefix": "pk_live_examplekey42",
"scopes": [
"lines:read",
"lines:write",
"packages:read",
"bouquets:read",
"streams:read",
"vods:read",
"resellers:read",
"resellers:write",
"subresellers:write"
]
}
}
}
For a reseller key, type is "reseller" and every reseller field is populated.
{
"status": "STATUS_SUCCESS",
"data": {
"type": "reseller",
"reg_user_id": 512,
"member_group_id": 4,
"member_group_name": "Silver reseller",
"billing": {
"mode": "credits",
"credits": 187,
"max_users": null,
"active_users": 42,
"billing_expires": null
},
"permissions": {
"create_sub_resellers": true,
"create_trials": true,
"create_lines": true
},
"key": {
"id": 4287,
"prefix": "pk_live_examplekey87",
"scopes": ["lines:read", "lines:write", "packages:read"]
}
}
}
The full identity shape is described on the Panel API Authentication page. This action maps to the native GET /panel-api/v1/me endpoint, and the payload above is the native data returned unchanged inside the XC envelope.
Examples
cURL
curl "https://<your-panel-domain>/panel-api/xc/panel_api/admin/index.php?api_key=<your-api-key>&action=user_info"
PHP raw
$url = 'https://<your-panel-domain>/panel-api/xc/panel_api/admin/index.php'
. '?' . http_build_query([
'api_key' => '<your-api-key>',
'action' => 'user_info',
]);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$raw = curl_exec($ch);
curl_close($ch);
$body = json_decode($raw, true);
if (!is_array($body) || ($body['status'] ?? '') !== 'STATUS_SUCCESS') {
throw new RuntimeException('user_info failed: ' . ($body['data']['message'] ?? 'unknown'));
}
$identity = $body['data'];
echo $identity['type'], "\n"; // 'admin' or 'reseller'
echo implode(',', $identity['key']['scopes']); // scope list
Python raw
import requests
r = requests.get(
"https://<your-panel-domain>/panel-api/xc/panel_api/admin/index.php",
params={"api_key": "<your-api-key>", "action": "user_info"},
timeout=30,
)
r.raise_for_status()
body = r.json()
if body["status"] != "STATUS_SUCCESS":
raise RuntimeError(f"user_info failed: {body['data'].get('message')}")
identity = body["data"]
print(identity["type"], identity["key"]["prefix"], identity["key"]["scopes"])
Errors
Every response is HTTP 200. The status field carries the outcome.
status |
error slug |
When it happens | How to fix |
|---|---|---|---|
STATUS_INVALID_DATA |
validation_error |
The action parameter is missing. |
Include action=user_info in the query or body. |
STATUS_FAILURE |
invalid_key |
The API key was not sent, is not recognized, has been revoked, or is malformed. | Verify the key value and that it was not rotated in the panel. |
STATUS_FAILURE |
caller_disabled |
The reseller behind the key is banned or their license expired. | Contact the panel admin. |
STATUS_FAILURE |
rate_limited |
The key exceeded its per-minute request budget. | Slow down and read the X-RateLimit-* response headers. See Rate limits & Idempotency. |
STATUS_FAILURE |
api_disabled |
The panel operator flipped the Panel API kill switch. | Wait for the API to be re-enabled by the admin. |
See also
- XC and XUI API Reference. Envelope, authentication, and the full action list.
- Panel API Authentication. Full identity shape and scope reference.
- Panel API Errors. The catalog of native error slugs.