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 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.
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_idand 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 sendsmember_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_idand 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_connectionsis 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. How to add a panel entry with the correct Key type and Admin owner member_id.
- 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. The Panel API's own view of what a reseller key can and cannot do end to end.
- Provisioning Modes. What each key type ends up doing on the wire when a lifecycle hook fires.