---
title: "Reseller vs Admin Keys"
description: "The module supports both reseller and admin Panel API keys. Each key type unlocks a different set of product features. This page maps every module capability to the key type that can execute it."
---

The module accepts two kinds of Panel API keys, and the difference is not cosmetic. Every request the module sends to the panel is authorized by that key, and the panel enforces different rules depending on the key type. As a result, some module features light up on both key types, some are admin-only, and a small number are unreachable today with either key. This page is the full map.

If you have not yet read the Panel API's take on the same distinction, [For Resellers](/docs/?page=panel-api-for-resellers) covers the underlying API model in detail. What follows here is that model applied to what the WHMCS module actually does with it.

## The capability matrix

Rows are module features. Columns are the two key types. **Yes** means the module executes the feature normally. **No** means the panel refuses the underlying call for that key type and the module surfaces a clear error. The Why column explains where each restriction comes from.

| Capability | Reseller key | Admin key | Why |
|---|---|---|---|
| Provision a Line on CreateAccount | Yes (owner inferred from the key) | Yes (owner sent as `member_id` from the panel entry) | The panel infers the caller from the token on a reseller key. Admin keys can create lines under any reseller, so the module has to say which one; the Admin owner member_id you set on the panel entry is exactly that value. |
| Renew a Line | Yes | Yes | `POST /lines/{id}/renew` accepts both key types. |
| Suspend / Unsuspend a Line | Yes | Yes | `POST /lines/{id}/enable` and `/disable` accept both key types. No credit is charged. |
| Change Password on a Line | Yes | Yes | `POST /lines/{id}/reset-password` accepts both key types. |
| Terminate a Line | Yes | Yes | `POST /lines/{id}/delete` accepts both key types. |
| Show Active Connections in the client area | Yes | Yes | `GET /lines/{id}/connections` accepts both key types. |
| Reflect panel expiry into `tblhosting.nextduedate` after CreateAccount and Renew | Yes | Yes | Purely a WHMCS-side write; the source value comes from the panel response in both cases. |
| Change the panel Package on an existing line | No | No | The panel API does not accept `package_id` on `POST /lines/{id}/update`. When a WHMCS product change swaps to a different panel package, the module refuses the change with a readable error and preserves the WHMCS to panel link so you can terminate and re-provision. |
| Change **bouquets** or **notes** on an existing line | Yes | Yes | `POST /lines/{id}/update` accepts both fields for both key types. |
| Change **max_connections**, `exp_date`, `is_restreamer`, `allowed_ips`, `allowed_ua`, `is_isplock` on an existing line | No (fields silently dropped, warning logged) | Yes | These are admin-only fields on the panel side. On a reseller key the panel would return `403 admin_only_field`; the module drops them client-side to avoid the round trip and records the drop as a `last_update_warning` in module settings. |
| Set per-line `max_connections` on CreateAccount | No | Yes | Admin-only on the panel. Non-zero values in the product's **Max Connections** option are silently ignored on a reseller key, and the line is created with the package default. |
| Create a Sub-Reseller product on CreateAccount | No | Yes | Requires `member_group_id` on the body, which the panel demands for admin keys and computes automatically for reseller keys. Reseller keys can technically create sub-resellers through their own sub-reseller setup, but the module's Sub-Reseller product flow requires an admin key so that all downstream credit operations remain reachable. |
| Adjust Sub-Reseller credits (on renewal or manually from the addon) | No | Yes | `POST /resellers/{id}/billing/adjust` requires `resellers:write`, which is admin-only. |
| Suspend / Unsuspend / Terminate a Sub-Reseller | No | No | The panel API does not currently expose a reseller status field on `POST /resellers/{id}/update`. Neither key type can toggle a reseller from the API. The module surfaces a clear error for these actions and preserves the WHMCS to panel link so an operator can complete the action manually from the panel and retry. |
| Change Password on a Sub-Reseller | No | Yes | `POST /resellers/{id}/update` with `password` requires `resellers:write` (admin-only). |
| Read the panel Catalog (packages, bouquets, streams, VODs) | Yes | Yes | Read-only endpoints; both key types work. Reseller keys see the catalog their member group has been granted; admin keys see everything. |
| Sub-Resellers view in the addon (list + credit adjust) | No | Yes | Lists via `GET /resellers`, which requires `resellers:read` (admin-only). |
| Dashboard reseller counters | No (skipped) | Yes | Same underlying call as the Sub-Resellers view. On a reseller key the module hides the counter row rather than firing a call that would 403. |
| Test Connection button | Yes | Yes | Hits `GET /me`, which every authenticated key can reach with no scope required. |

## Why the admin-only rows are admin-only

Every "admin-only" row in the table above traces back to a scope on the panel. The Panel API divides its capabilities into nine scopes; two of them are admin-only and refused at issuance if you attach them to a reseller key:

- `resellers:read`. Reading the reseller list, or reading another reseller's record. Would expose peers and their customers if reseller keys could hold it.
- `resellers:write`. Writing changes to a reseller (credits, notes, member group, password). Would let a reseller escalate itself, or step on another reseller's balance, if reseller keys could hold it.

Because the module reaches those scopes on the Sub-Resellers view, on `adjustResellerCredits` (renewal and manual), and on `resetResellerPassword`, every feature that depends on them is admin-only from the module's perspective as well.

For the reserved handful of admin-only Line fields (`max_connections`, `exp_date`, `is_restreamer`, `allowed_ips`, `allowed_ua`, `is_isplock`), the split is enforced field-by-field by the panel's `POST /lines/{id}/update` handler. A reseller key hitting the update endpoint with those fields would receive `403 admin_only_field`. The module drops them before sending and records the drop in `last_update_warning` so the operator can see the reseller key silently ignored the field.

## Which key should I use?

The decision tree is short.

**Do you plan to sell Sub-Reseller products?** If yes, you need an admin key. There is no reseller-key path to the Sub-Reseller product flow. Stop here and issue an admin key.

**Do you need per-line `max_connections` overrides?** If yes, you need an admin key. On a reseller key the Max Connections field on your products is silently ignored and every line uses the package default.

**Otherwise, a reseller key is enough.** The complete Line lifecycle (create, suspend, unsuspend, renew, change password, terminate) runs unchanged on a reseller key. Bouquet updates and notes updates work. The client-area card, active connections, and the module logs work. Everything a typical IPTV WHMCS deployment needs is reachable without an admin key.

> [!NOTE]
> If you already run on a reseller key and later realize you need an admin-only capability, you do not have to re-provision existing services. Add a second panel entry with an admin key, or edit the existing panel entry and swap the token and the Key type. Existing lines keep their `line_id` and continue to renew normally through the new key. The panel entry is a WHMCS-side record; the panel does not care which WHMCS install holds which token as long as the token is valid.

## What happens when the wrong key type is attached

The module cross-checks the Key type you selected on the panel entry against the token you pasted only at Test Connection time. If Test Connection succeeds and you save the entry, the module trusts the Key type you set from then on.

A mismatch produces two distinct symptoms depending on the direction:

- **Reseller token attached as Admin.** Line CreateAccount fails with a message such as `The panel rejected the request. Admin key requires field 'member_id'` because the module dutifully sends `member_id`, which the panel refuses to accept from a reseller key. Fix: edit the panel entry, switch Key type to **Reseller**, clear the **Admin owner member_id** field.
- **Admin token attached as Reseller.** Line CreateAccount works (the panel is happy to accept a line without `member_id` and it will simply own the line under the reseller behind the token), but every admin-only feature is gated off in the module UI. The Sub-Resellers view is hidden, `max_connections` is ignored, and Sub-Reseller products fail at CreateAccount. Fix: edit the panel entry, switch Key type to **Admin**, set **Admin owner member_id** to the id of the reseller that should own the lines created by this WHMCS.

## See also

- **[Configure](/docs/?page=whmcs-module-configure).** How to add a panel entry with the correct Key type and Admin owner member_id.
- **[Panel API Authentication](/docs/?page=panel-api-authentication).** Full scope taxonomy on the panel side, including the two admin-only scopes and how the panel refuses to attach them to a reseller key.
- **[For Resellers](/docs/?page=panel-api-for-resellers).** The Panel API's own view of what a reseller key can and cannot do end to end.
- **[Provisioning Modes](/docs/?page=whmcs-module-provisioning-modes).** What each key type ends up doing on the wire when a lifecycle hook fires.
