For Resellers

The Panel API is the same for admins and resellers — same base URL, same JSON shapes, same errors. What changes is which endpoints you can reach and what data those endpoints see. This page is the map: what your reseller key can do end to end, what it cannot, and where each restriction comes from.

If you are the panel admin, the Overview is a better starting point — it walks the API from the admin's angle. This page assumes you own a reseller account and want to build something against your slice of the panel.

Getting a key

Your admin has to opt your member group in before you can issue API keys. This is off by default. Ask them to enable Reseller settings → Member groups → Can create API keys for your group. Once enabled:

  1. Log into your reseller area on the panel.
  2. Open Settings → Panel API Keys.
  3. Click New key, name it (for your own bookkeeping — the panel does not use the name), pick the scopes it needs, and optionally restrict it to specific source IPs.
  4. Copy the token — it is shown once. Store it in a secret manager, an environment variable, or your billing system's credential vault. Not in code.

The token is a long random string prefixed with something like pk_live_. That prefix is the only part safe to log; the rest is the secret. Full token contract lives in Authentication.

Reseller keys carry two extra restrictions the admin cannot override:

  • They cannot include the admin-only scopes (resellers:read, resellers:write). The panel refuses to attach them at issuance.
  • They are tied to your reseller account. If your account gets banned, disabled, or your member group is banned, every call from your key comes back 401 caller_disabled. Admin keys are not tied to any reg_user and are immune to that.

What you can do

Everything in the table below is reachable with the standard reseller scope set. The scope column names the exact scope required — the key you issue must carry it or the panel returns 403 insufficient_scope.

Lines (your own customers)

You see and manage only lines you created. Lines owned by other resellers are invisible to you — they don't appear in GET /lines, and directly fetching GET /lines/{id} for an unowned line returns 404.

Endpoint Scope What you can do
List lines lines:read Paginate your lines. Filter by username, package, expiry.
Create line lines:write Provision a new customer against one of your packages. Consumes credits (credits mode) or a user slot (users mode).
Retrieve line lines:read Full record for one of your lines.
Update line lines:write Partial update: notes, package, bouquets, expiry, contact info.
Enable / disable lines:write Suspend or reactivate a line without deleting it. Free — no billing side effects.
Renew lines:write Extend a line's expiry by the package's cycle. Consumes credits (credits mode) or is free (users mode).
Reset password lines:write Rotate a customer's password after a compromise.
Delete line lines:write Permanent — frees the user slot (users mode) but does not refund credits.
List connections lines:read See who is streaming right now on that line. Useful for suspending abusers.

Catalog (what you can sell)

Read-only. You see only the packages and bouquets your admin has assigned to you.

Endpoint Scope Notes
List packages packages:read Every package the admin made available to your group.
List bouquets bouquets:read Every bouquet you can assign to a line.
List / get streams streams:read Live channel catalogue.
List / get VODs vods:read Movie catalogue.

If a package you expect to see is missing, that is an admin config issue — the API just reflects what your member group is allowed to sell.

Yourself

One endpoint returns your identity. Includes your billing snapshot (mode, balance, user cap), which is the recommended way to check credits before a bulk of writes.

Endpoint Scope Notes
Get caller identity none Type (reseller), member group, scope list, key prefix, billing snapshot.

Sub-resellers (opt-in)

If — and only if — your admin has enabled sub-reseller creation for your member group AND your key was issued with subresellers:write, you can create sub-resellers underneath yourself. This is a single endpoint:

Endpoint Scope Notes
Create reseller subresellers:write Creates a reseller in one of the sub-reseller member groups the admin exposed to you. The new reseller is your child in the ownership tree.

You cannot list, read, update or manage billing of your sub-resellers via the API v1 — those flows live in the panel UI today (Users section). See What you cannot do below.

What you cannot do

The following endpoints exist but require admin-only scopes. Attempting them with a reseller key returns 403 insufficient_scope.

Endpoint Why admin-only
List resellers Requires resellers:read. Would expose peers and other admin's customers.
Retrieve reseller Same as above.
Update reseller Requires resellers:write. Can change scopes, group, quotas — trust-boundary crossing.
Read billing Requires resellers:read. Your OWN billing is exposed via GET /me.
Adjust billing Requires resellers:write. Credit adjustments for sub-resellers happen in the panel UI in v1.

If your workflow genuinely needs to manage a sub-reseller's credits programmatically and the panel UI is not enough, talk to your admin — they can call POST /resellers/{sub_id}/billing/adjust from an admin key on your behalf.

Ownership: what your key sees

Every read endpoint returns only rows you are allowed to see. This is enforced at the panel side, not client-side — you cannot bypass it by omitting a filter or crafting a URL.

  • GET /lines returns your lines. Owned-by filter is baked in.
  • GET /lines/{id} returns 404 for a line owned by anyone else (even if the numeric ID is valid). The 404 is deliberate — the panel does not tell you "that line exists but is not yours". Same-shaped error whether it was never created, was deleted, or belongs to a peer.
  • Catalogue endpoints return what your member group is allowed to see. Two resellers on different groups can get different catalogues from the same call.
  • Sub-reseller resources are visible to their creator (via the panel UI), but the API v1 does not currently expose them.

Billing modes

Your reseller account is in one of two billing modes: credits or users. Which one applies is set by your admin on your member group. Both are visible in GET /me.

Credits mode

You consume credits when you POST /lines (creating a line) and when you POST /lines/{id}/renew (renewing). The credit cost per operation is defined per package — see official_credits in the package payload from GET /packages.

  • If your balance is insufficient, the write returns 402 insufficient_credits (mapped to InsufficientCreditsException in the SDK).
  • Deleting or disabling a line does NOT refund credits.
  • Enabling a disabled line is free — the credit was already spent when the line was created.
  • Only the admin can top up your credits. POST /resellers/{id}/billing/adjust is admin-only.

Users mode

You have a hard cap on the number of active users. Each POST /lines uses one slot. Deleting a line frees the slot immediately; disabling does NOT — a disabled line still counts against the cap.

  • If your cap is full, the write returns 422 insufficient_slots (mapped in the SDK to the same InsufficientCreditsException, so a single catch handles both modes).
  • Renewals are free in users mode — the slot is already counted for as long as the line exists.
  • Only the admin can raise your cap.

Both flavors return the same exception class in the SDK, so one catch handles both. See Errors with the SDK for the details.

Rate limits

Reseller keys share the same per-key rate limit contract as admin keys — a burst budget per minute, refilled linearly. Hitting the limit returns 429 rate_limited with a Retry-After header. The SDK honors it automatically up to a 60-second cap.

The exact numbers are set per member group by your admin. GET /me includes the effective limit for the caller. If your integration bumps into it regularly, the fix is usually to batch (fetch pages of 100 instead of 10) or to serialize concurrent bursts, not to ask for a limit bump — sustained high volume usually means the caller is doing something that should be a bulk operation, not many singletons.

Scope selection: less is more

Every key you issue should carry the minimum scopes it actually needs. That "billing-system-only" key that just creates lines does not need streams:read or vods:read. Fewer scopes means:

  • The blast radius of a leaked key is smaller.
  • The panel-side rate limit is not shared across purposes — one integration hitting its limit does not stall the other.
  • Rotating one key does not break every integration you own.

For a WHMCS-style billing integration, a typical minimal scope set is:

lines:write, lines:read, packages:read, bouquets:read

For a reseller portal that also lets end users pick between packages:

lines:read, lines:write, packages:read, bouquets:read, streams:read, vods:read

For sub-reseller provisioning:

Add subresellers:write to whichever key does the provisioning.

See also

  • Authentication. Full auth contract including scopes, IP allow-lists, and rotation.
  • Quickstart. Get your first line created in five minutes.
  • SDKs Overview. The official PHP and Python SDKs give you typed models, typed exceptions, and automatic retry.
  • Common Tasks. Cookbook recipes — payment-triggered provisioning, renewal after invoice, month-end reconciliation.
  • Get caller identity. One endpoint that answers "what am I, what can I do, and how much do I have left".