Get identity
/me is the introspection endpoint. It answers the question "who am I to this panel?" from the point of view of the API key that made the request. It is the first call most new integrations make, because it lets you confirm three things at once: the key was accepted, the panel recognizes it, and the scopes you expected are actually granted.
The response shape depends on the type of key you use. An admin key gets a compact object with the key's granted scopes and null billing and permissions fields (there is no reseller behind an admin key). A reseller key gets the reseller's reg_user_id, member group name, the current billing snapshot (credits balance or slot usage), the group-level permissions that gate every write, and the trial-quota window. This is the same data the panel UI shows the reseller in their own dashboard, expressed in a form your code can act on.
Both variants include a key object with the key's numeric id, its pk_live_<prefix> (the safe half you can share in bug reports), and the list of granted scopes.
Endpoint
GET https://<your-panel-domain>/panel-api/v1/me
Authentication
Bearer token in the Authorization header. Any valid, enabled key works, regardless of scope. See Authentication.
Required scope
None. Every authenticated key can call /me. This is deliberate. Introspection has to work before the caller knows what scopes they have.
Response
Two shapes, distinguished by the type field.
Admin key
| Field | Type | Description |
|---|---|---|
type |
string | Fixed value "admin". |
reg_user_id |
null | Admins have no reg_user_id. |
member_group_id |
null | Admins have no member group. |
member_group_name |
null | Admins have no member group. |
billing |
null | Admins have no billing state. |
permissions |
null | Admins are not gated by member-group permissions. |
key |
object | See "Key object" below. |
{
"type": "admin",
"reg_user_id": null,
"member_group_id": null,
"member_group_name": null,
"billing": null,
"permissions": null,
"key": {
"id": 1974,
"prefix": "pk_live_examplekey00",
"scopes": [
"lines:read",
"lines:write",
"packages:read",
"bouquets:read",
"streams:read",
"vods:read",
"resellers:read",
"resellers:write",
"subresellers:write"
]
}
}
Reseller key
| Field | Type | Description |
|---|---|---|
type |
string | Fixed value "reseller". |
reg_user_id |
int | The reseller's numeric id in your panel. Same value you would use as member_id from an admin key. |
member_group_id |
int | Id of the member group this reseller belongs to. |
member_group_name |
string | Human-readable name of the member group. |
billing |
object | Snapshot of the reseller's billing state. See "Billing object" below. |
permissions |
object | Group-level permissions that gate writes. See "Permissions object" below. |
key |
object | See "Key object" below. |
{
"type": "reseller",
"reg_user_id": 42,
"member_group_id": 4,
"member_group_name": "RESELLER",
"billing": {
"mode": "credits",
"credits": 0.25,
"max_users": null,
"active_users": null,
"billing_expires": null
},
"permissions": {
"allow_change_pass": false,
"edit_isplock": true,
"trial_quota": {
"total_allowed": 100,
"period": "day",
"consumed_in_window": 0,
"window_seconds": 86400
}
},
"key": {
"id": 1976,
"prefix": "pk_live_examplekey00",
"scopes": [
"lines:read",
"lines:write",
"packages:read",
"bouquets:read",
"streams:read",
"vods:read",
"subresellers:write"
]
}
}
Key object
Present on both variants.
| Field | Type | Description |
|---|---|---|
id |
int | Numeric id of the API key row. |
prefix |
string | The pk_live_<12chars> public half of the token. Safe to log or paste in support tickets. |
scopes |
string[] | List of scopes granted to this key. See Authentication for the full catalog. |
Billing object (reseller keys only)
| Field | Type | Description |
|---|---|---|
mode |
string | Either "credits" or "users". Decides how new lines are paid for. |
credits |
number or null | Current credit balance (only set when mode == "credits"). |
max_users |
int or null | Slot cap for active non-trial lines (only set when mode == "users"). |
active_users |
int or null | Currently active non-trial lines counted against max_users (only set when mode == "users"). |
billing_expires |
int or null | UTC Unix epoch when the reseller's subscription expires. null means no expiry configured. Past values block create and renew for this reseller with 402 billing_expired. |
Permissions object (reseller keys only)
| Field | Type | Description |
|---|---|---|
allow_change_pass |
bool | If false, the reseller cannot set a custom password on create or reset. Attempting to do so returns 403 password_change_not_allowed. |
edit_isplock |
bool | If false, the reseller cannot toggle the per-line ISP lock. Attempting to do so returns 403 isplock_not_allowed. |
trial_quota.total_allowed |
int | Maximum trials the reseller can create inside the rolling window. 0 means unlimited. |
trial_quota.period |
string | Either "day" or "month". Names the size of the rolling window. |
trial_quota.consumed_in_window |
int | Trials already created in the current window. |
trial_quota.window_seconds |
int | Length of the rolling window in seconds (86400 or 2592000). |
Examples
cURL
curl -X GET "https://<your-panel-domain>/panel-api/v1/me" \
-H "Authorization: Bearer <your-api-key>"
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>');
$identity = $client->me->get();
echo $identity->type . "\n";
foreach ($identity->key->scopes as $scope) {
echo " - " . $scope . "\n";
}
Python SDK
from xtream_ai_panel_api import PanelApiClient
client = PanelApiClient(base_url="https://<your-panel-domain>", token="<your-api-key>")
identity = client.me.get()
print(identity.type)
for scope in identity.key.scopes:
print(f" - {scope}")
Errors
| HTTP | Error slug | When it happens | How to fix |
|---|---|---|---|
| 401 | invalid_key |
The Authorization header is missing, malformed, points to an unknown key, or the key is disabled, expired, deleted, or its IP allow-list excludes the caller. |
Verify the token you copied from the panel. Reissue if the key was rotated. |
| 404 | not_found |
Only on reseller keys, and only in the very rare case where the reseller row was deleted after the key was issued. | Rotate the key from an admin account. |
| 429 | rate_limited |
You exceeded the per-key or per-IP rate limit. | Back off (see the Retry-After header) and lower the call frequency. Cache the result of /me per key, it does not change often. |
| 503 | api_disabled |
An admin has turned the Panel API off for this panel (via the global or tenant kill switch). | Ask the admin to re-enable it. |