Reseller API

Published Sep 05, 2026 · Updated Sep 05, 2026 · 5 min read

Give your resellers' own mobile app everything the agent portal can do: token login, customers, activations, wallet, payments and receipts, devices, tickets - with the same isolation and the same feature switches.

The Reseller API reference at /developers/agent: endpoint groups on the left, base URL and bearer auth on the right

The Reseller API gives your agents' own mobile app the same powers as the web agent portal at /agent: their customers, activations and renewals, the wallet, payments and receipts, discovered devices, tickets, cards and notification switches. It is a separate API from the REST API for your own integrations: there are no API keys and no scopes, an agent logs in with their portal email and password and can never do more than in the browser.

1. Base URL and login

Every request goes to your tenant URL: https://yourcompany.ispbox.net/api/agent/v1/... (custom domains work too). The app first calls POST /auth/login with the agent's email, password and a device name and receives a bearer token that lives a year; it sends the token as Authorization: Bearer <token> on every other call. The login answer already contains everything GET /auth/me returns: the agent's profile and wallet, your company name and currency, and a features block that says which switches you turned on in Settings > Agents, so the app can hide what is off. POST /auth/logout revokes the token, POST /auth/forgot-password sends the same reset mail as the portal (through your own mailbox).

curl -X POST https://yourcompany.ispbox.net/api/agent/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"...","device_name":"Ali's phone"}'

A suspended agent gets 403 account_suspended at login and on every later call, so suspending an agent in the panel cuts off their app the same second.


2. What an agent can see and do

The isolation rule is the one the portal uses: an agent sees the customers attributed to them and to their sub-agents, and every customer at their location only when you marked them a site manager. A foreign or unknown customer number is a plain 404, never a leak. Customers are addressed by the per-tenant number shown in the panel; services, notes, devices, payments and invoices by their id.

Features you switched off in Settings > Agents answer 403 with "type": "feature_disabled" and the toggle name. Business refusals (an empty wallet, a monthly cap, a customer who never ran) answer 422 with the same human message the portal shows and a stable type such as insufficient_balance or customer_limit. Every amount is an object with a two-decimal amount string and the currency; dates are ISO-8601 in UTC.


3. The endpoints

GroupEndpointsNotes
DashboardGET /dashboardWallet, today's activations and renewals, the state buckets with counts (mine or team), pending devices, the last eight things the agent did.
CustomersGET /customers, POST /customers, GET /customers/{number}, PATCH /customers/{number}The working list with the portal's search (name, phone, login, IP, MAC in any notation, number) and filters; sign-up with an optional package, connection point, PPPoE login or discovered device (each behind its switch); the customer page in one call; contact-field edits when you allow them.
NotesGET, POST /customers/{number}/notes, DELETE .../notes/{note}The same thread your office sees; an agent deletes only their own notes.
Service actionsPOST /customers/{number}/services, .../services/{service}/activate, .../package-change, .../trial, .../compensation, .../suspend, .../resume, .../redeem-cardActivate or renew from the wallet (the answer carries the transaction, the new balance and a warning when the router refused the setup), change the package with the "expired now, running at next renewal" rule, trials and compensation in hours or days, holds, scratch cards.
BillingGET /customers/{number}/invoices, POST .../invoices/{invoice}/pay, POST /customers/{number}/payments, GET /payments, GET /payments/{payment}/receipt, GET /payments/{payment}/share-links, GET /invoices/{invoice}/pdfPay an invoice or take cash from the wallet, the payment ledger (all, collected by me, one customer, search, this-month totals), receipt and invoice PDFs, the public receipt link and WhatsApp URL.
WalletGET /wallet, GET /wallet/transactions, POST /wallet/top-up-requests, DELETE /wallet/top-up-requests/{id}Balance, credit limit, this and last month's figures, the full ledger, asking the office for a top-up.
PackagesGET /packagesEvery sellable package with the agent's buy price, the customer price, the margin and the allowed range. Price edits stay in the web portal.
DevicesGET /devices, POST /devices/{device}/attachDiscovered DHCP devices in the agent's scope with their presence, plus the customers they can be attached to; a one-shot claim that reports whether the RADIUS reload worked.
TicketsGET /tickets, POST /tickets, GET /tickets/{number}, POST /tickets/{number}/replyOpen, mine, closed; the client-visible thread only; replies reopen a closed ticket.
CardsGET /cards, POST /cardsRenewal card batches paid from the wallet, with the codes and the print link.
NotificationsGET /notifications, PUT /notificationsThe agent's own email switches - only the kinds you offer can be turned on.

The full reference with request and response schemas is generated from the code and always current: open Settings > API and click Reseller API docs, or go to https://ispbox.net/developers/agent. The machine-readable spec is at /developers/agent/openapi.json.


4. Good to know

  • Tokens are per device. An agent with two phones has two tokens; revoking one leaves the other working.
  • Rate limits: 240 requests a minute per agent, 10 login attempts a minute per email and address.
  • Demo tenants answer every write with 403 demo_read_only.
  • Money never moves twice: an activation that fails on the wallet books nothing on the customer, and an activation the router refused is still paid and extended - the app gets a warning, you get the same flag on the service page, and the network side is retried automatically.