GET /ext/user/find

/ext/user/find returns sub-resellers under the calling key. Its main use is looking up a specific sub-reseller by name before a follow-up call to /ext/user/{id}/update or /ext/user/{id}/credit. Called without a filter, it returns the full list.

The endpoint maps to the panel's resellers listing under the hood. In OneStream terminology the field name for the filter is name; the dialect translates it to username for the v1 API. The response objects carry the same shape the native /panel-api/v1/resellers endpoint returns, without the {"items": ...} envelope.

Endpoint

GET https://<your-panel-domain>/panel-api/onestream/ext/user/find

Authentication

Send the API key in X-Api-Key, X-Auth-User, or Authorization: Bearer. See the OneStream overview.

Required scope

resellers:read. Reseller keys typically do not carry this scope, so this endpoint is normally reachable only by admin keys.

Query parameters

Name Type Required Default Description
name string no (none) Exact-match filter on the sub-reseller's username. Case-sensitive. Translated internally to username.

If name is omitted, the endpoint returns the full paginated first page of sub-resellers the calling key can see. To list beyond the first page, use the native GET /panel-api/v1/resellers?cursor=<value> endpoint. The OneStream dialect does not project a cursor into this response.

Response

A plain JSON array. Each element has the following fields (a subset of the native resellers shape, kept identical for compatibility).

Field Type Description
id int Numeric sub-reseller id. Pass this as {id} in /ext/user/{id}/update and /ext/user/{id}/credit.
username string Sub-reseller username.
email string Sub-reseller email. May be empty.
member_group_id int Id of the member group this sub-reseller belongs to.
member_group_name string Human-readable name of the member group.
status int 1 when the sub-reseller is enabled, 0 when disabled.
billing_mode string Either "credits" or "users". Decides how the sub-reseller pays for new lines.
credits float Credit balance, when billing_mode == "credits". 0 otherwise.
max_users int Line cap, when billing_mode == "users". 0 otherwise.
active_users int or null Currently active non-trial lines counted against max_users. null in credits mode.
billing_expires int or null Unix epoch when the sub-reseller's subscription expires. null means no expiry.
created_at int or null Unix epoch when the sub-reseller was created. May be null for legacy accounts imported before the field was populated.

Example response for ?name=reseller1:

[
  {
    "id": 50,
    "username": "reseller1",
    "email": "reseller1@example.com",
    "member_group_id": 4,
    "member_group_name": "RESELLER",
    "status": 1,
    "billing_mode": "credits",
    "credits": 0.25,
    "max_users": 0,
    "active_users": null,
    "billing_expires": null,
    "created_at": 1578098423
  }
]

Example response for a name that does not match anyone:

[]

Examples

cURL

curl -H "X-Api-Key: <your-api-key>" \
     "https://<your-panel-domain>/panel-api/onestream/ext/user/find?name=reseller1"

PHP raw

$name = 'reseller1';
$url = 'https://<your-panel-domain>/panel-api/onestream/ext/user/find?name=' . urlencode($name);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['X-Api-Key: <your-api-key>']);
$rows = json_decode(curl_exec($ch), true);
curl_close($ch);

if ($rows === []) {
    echo "no match\n";
} else {
    foreach ($rows as $r) {
        echo $r['id'] . ' ' . $r['username'] . ' (' . $r['credits'] . " credits)\n";
    }
}

Python raw

import requests

r = requests.get(
    "https://<your-panel-domain>/panel-api/onestream/ext/user/find",
    headers={"X-Api-Key": "<your-api-key>"},
    params={"name": "reseller1"},
    timeout=30,
)
r.raise_for_status()
rows = r.json()

if not rows:
    print("no match")
else:
    for row in rows:
        print(row["id"], row["username"], row["credits"])

Errors

HTTP Error slug When it happens How to fix
401 invalid_key Header is missing, the token is unknown, the key was disabled, expired, deleted, or the caller IP is not on the key's IP allow-list. Check the header. If the key was rotated, mint a new one from the panel.
403 insufficient_scope The key does not carry resellers:read. Reseller keys typically hit this. Use an admin key, or regenerate the key with resellers:read.
429 rate_limited The per-key or per-IP rate limit was hit. Response carries Retry-After and X-RateLimit-* headers. Back off for the number of seconds in Retry-After.
403 api_disabled An admin has turned the Panel API off for this panel. Ask the admin to re-enable it.

See also