The addon's Bulk tools view (module 1.3.0 and newer, Addons → Xtream AI Panel → Bulk tools) covers the two situations where editing services one by one is not an option: you are moving thousands of services from another WHMCS module onto this one, or you changed a product option that should reach every customer line. It runs from the browser in batches, with a progress bar, a counter per outcome and one result row per service, and every operation can be run again without duplicating anything.
The Panel dropdown at the top selects the panel every card works on. Run the cards in order: index first, then link, then sync.
1. Index panel lines
Reads every line of the selected panel through GET /panel-api/v1/lines (100 per batch) and stores a local copy in the addon table mod_xtreamai_line_index: line id, username, expiry, enabled flag and the WHMCS service number parsed from the line's notes. The parser uses the Line Notes Template from General Settings (WHMCS:{service_id} by default): anything else in the template becomes a wildcard, and the tag can sit anywhere in the notes, so lines the panel created with the Created via panel-api | prefix are recognised too.
This card only reads from the panel. The first batch of a run clears the previous index of that panel, so the index always reflects the panel as it is now. Around 100 batches for a 10,000-line panel.
The
notesfield of line objects exists on panels updated on or after 2026-09-14. On an older panel the index is built without tags and the link step falls back to username matching only.
2. Link existing services
Candidates are WHMCS services whose product uses the xtreamai server module and that have no panel line recorded yet (no mod_xtreamai_services row, or a row without a line id). By default only Active and Suspended services are considered; tick Include Pending, Terminated and Cancelled services to widen it. Batches of 100, ordered by service id.
For each candidate the module resolves the product's panel (its Panel config option, or the first active panel when unset) and skips it when it is not the selected one. Then it looks for the line in the index, first by tag (service_tag = service id), then by username (tblhosting.username, when set). When a tag is shared by several lines, the one with the same username wins, otherwise the one with the latest expiry.
On a match the module writes the mod_xtreamai_services row (panel, line id, username, the product's package id), records the status (Active or Suspended, from the WHMCS service status) and the expiry from the index, and, when the WHMCS service has no username yet, fetches the line once and stores its username and password on the service so the client area card works. Nothing is created, changed or deleted on the panel.
| Outcome | Meaning |
|---|---|
linked_by_tag |
A line's notes carry this service number. The most reliable match. |
linked_by_username |
No tag matched; the service username equals a line username. |
not_found |
No line matched. The service was left untouched. |
ambiguous_tag |
Several lines carry this service number and none has the service's username. Nothing is linked, so a wrong line (and its password) is never attached to the service: set the username on the WHMCS service or fix the notes on the panel, then run again. The message lists the candidate line ids. |
skipped_sub_reseller |
The product is a Sub-Reseller product; there is no line to link. |
skipped_other_panel |
The product points at another panel. Run the tool with that panel selected. |
error |
The message column carries the exception text. The batch continues with the next service. |
The card refuses to start when the index of the selected panel is empty or when the last indexing run did not reach the last page, so a half-built index can never turn thousands of services into not_found. When the service username is empty, the line is read from the panel before the link is written, so a line that disappeared in between leaves the service unlinked and reported as error instead of half-linked.
3. Sync all services
Runs, for every linked service of the selected panel, exactly what the Sync line to panel button does on one service: WHMCS's local API executes the module's sync command (ModuleCustom), which recomputes bouquets, notes and the connection count (Max Connections plus any connections configurable option, see Configure) from the product and pushes them to the line with POST /lines/{id}/update. Batches of 5, one panel call each: on a panel where an update takes two seconds, that keeps every request around ten seconds.
Parallel requests (module 1.4.0 and newer, selector next to the Sync button, 1 to 4, default 3) runs that many batch requests at once, each on its own disjoint share of the services (service_id modulo the number of requests), so the run finishes roughly N times faster. Resume state is kept per request: a run that stopped must be resumed with the same value, otherwise it starts over and says so. The module releases the WHMCS admin session while a batch runs, so the parallel requests do not queue behind the session lock.
By default only Active services are synced; tick Include Suspended services to add those. Sub-Reseller products are reported as skipped_sub_reseller. Each other service ends as synced or error with the panel's message. The package list is fetched once per batch. If a request fails, the page retries it twice ten seconds apart and, if it still fails, stops and remembers where it was: clicking the button again resumes from that service instead of starting over.
Every card of the view keeps its resume position in the browser, one localStorage entry per panel and operation (module 1.4.2 and newer), so a run that stopped can be resumed after a page reload or after a new login: the card shows the services it stopped after and the button continues from there. A batch that answers Invalid security token (the admin session token rotated) is retried once with a refreshed token before the run stops, and while a run is active the page refreshes that token every four minutes, which also keeps the WHMCS admin session alive during runs that last hours.
This writes to every linked active line of the panel with the configuration its product has right now. Finish the product setup (packages, bouquets, Max Connections, configurable options) before you run it. On a reseller key the connection count is dropped by the module and only bouquets and notes are pushed.
Migrating from another WHMCS module
If the previous module wrote the WHMCS service number into the panel line notes (the common WHMCS:<service id> convention), the whole migration is: point the products at this module, index the panel, link the services, then sync. Existing lines keep their id, username, password and expiry; customers notice nothing. Services whose lines carry no tag are linked by username; the ones that end as not_found are the only manual work left, and the results table lists them.
See also
- Configure for the connections configurable option.
- Provisioning Modes for what a single Sync does on the panel.
- Troubleshooting when a service answers
This service has no panel line yet.