API Changes in 9770, broken MSP Control
Problem reported by Bruce - 10/5/2026 at 12:39 AM
Submitted
I am having a problem with MSP Control communicating with SmarterMail 9770 after upgrading to the latest version. I am seeing the following error and wonder if there are any API changes or what needs to be changed so MSP Control can connect to 9770.

The rror I see if:

Error: Internal Server Error.
NO_PERMISSIONS.
Bruce Replied
Bit more info on this. MSP Control logs in to the API fine as the primary admin, it's the impersonation step that fails. From the Administrative log:

[2026.10.05] 10:15:02.057 [::1] Webmail Login successful: With user admin
[2026.10.05] 10:15:02.059 [::1] User admin@ as admin calling manage (impersonate) domain, domain: 000-test.com

Straight after that MSP Control gets NO_PERMISSIONS back.

Impersonating the same domain as the same admin in the web interface works fine, so the domain and admin account look OK. It's just impersonation via the API that's broken since 9770.

I'm guessing it's related to this item in the 9770 release notes:

"Security: Fixed an issue where user-impersonation sessions were not always revoked correctly."

Possibly the impersonation token is now being revoked before the API client gets to use it, or the API impersonation flow needs something different now? It was working on the previous build.

This is the primary administrator, no 2FA, no IP restrictions, impersonation allowed, as I am working on a dev machine to reproduce the error. 
Kyle Kerst Replied
Employee Post
Hi @Bruce - sorry to hear you're having trouble with this. Can I have you DM me the control panel name and/or an example of the API call thats being used for impersonation here? I'd like to do some testing here as I'm not seeing these behaviors in any of our in-house test control panels. Thanks!
Kyle Kerst
Lead Internal Network/System Administrator
SmarterTools Inc.
Sébastien Riccio Replied
We ran into the same thing on our own control panel right after upgrading to 9770, and tracked it down. It isn't a revocation race. 9770 changed what impersonation requires from the session that calls it.

The API reference served by a 9770 server now says this about ImpersonateUser (POST /api/v1/settings/domain/impersonate-user):

"The caller must hold a refresh-capable session (one with a clientId)."

A refresh-capable session is one opened by calling auth/authenticate-user with a clientId. Our integration logged in without one, as yours probably does. That login still works, and so do all the normal sysadmin calls. But every impersonation is refused with 400 NO_PERMISSIONS, both impersonate-user and manage-domain (POST /api/v1/settings/sysadmin/manage-domain/{domain}). That's the step in your log.

We fixed it by sending a clientId at login, unique per client instance, for example myapp- plus 16 random hex characters, generated for each API client object or process:

POST /api/v1/auth/authenticate-user
{ "username": "admin", "password": "…", "clientId": "myapp-3f9c1a7e5b2d4c60" }

Don't use one fixed clientId for every process. SmarterMail keys its sessions by (user, clientId), so with a shared constant each new login replaces the previous session for that user.
All your other workers then start getting 401 Token not found.We learned that the hard way on an earlier build.
Log out when you're done (POST /api/v1/auth/logout-user with that session's token).
On our install, a session opened with a clientId gets a 15-minute access token but a refresh token valid for 60 days.
A client that logs in on every request without logging out would pile up sessions on the server. Logging out ends that session and every impersonation made from it, so do it after you've finished using the impersonation tokens, not right after obtaining them.
We tested that logging out one session doesn't affect the others, as long as each one has its own clientId.

Keep the impersonation token separate from the login token. The docs also say an impersonation session is tied to the session that created it. It ends when that admin logs out, loses impersonation rights, or is disabled, or 24 hours after it started.
If your client overwrites its main token with the impersonation token (ours did in one place), log out with the original login token, or you'll end only the impersonation and leave the admin session open.

For MSP Control
The login request has to change, so the fix needs to come from the MSP Control developers, they need to send a clientId when authenticating. I don't know of a server-side setting that turns the old behaviour back on.
Until they release an update, it may be worth pointing them to the ImpersonateUser entry in the 9770 API docs.
Sébastien Riccio
System & Network Admin

Bruce Replied
Thanks, Sébastien. I will let the MSP Control developers know. 
Michael Replied
We encountered a problem: the impersonation token was unexpectedly revoked.

Steps to reproduce:

curl -d '{"username": "admin", "password": "password", "clientId": "app-id"}' -H "Content-Type: application/json" -X POST /api/v1/auth/authenticate-user
curl -d '{"email": "user@example.com", "clientId": "app-id"}' -H "Content-Type: application/json" -H "Authorization: Bearer ADMIN_TOKEN" -X POST /api/v1/settings/domain/impersonate-user
curl -H "Authorization: Bearer USER_TOKEN" /api/v1/settings/mailbox-forward-list
curl -d '{}' -H "Content-Type: application/json" -H "Authorization: Bearer ADMIN_TOKEN" -X POST /api/v1/settings/sysadmin/manage-domain/example.com
After that, the USER_TOKEN has revoked!!!

curl -H "Authorization: Bearer USER_TOKEN" /api/v1/settings/mailbox-forward-list

{"success":false,"resultCode":401,"message":"Token revoked"}
Ben Replied
This is affecting SolidCP too.
Tony Scholz Replied
Employee Post
Hello, 

The behavior you are observing stems from a recent security update implemented in Build 9770 (October 1, 2026). This release addressed a vulnerability that allowed user-impersonation sessions to remain active when they should have been revoked.

Under the updated protocol, starting a new impersonation session from the same administrative account invalidates previous tokens, ensuring only the current session remains active.

Thank you for your understanding.


Tony Scholz
Lead Network/System Administrator
SmarterTools Inc.
Ben Replied
I think if an update brings breaking changes to an existing API call, there needs to be a way to disable it. (Like a debug toggle or something)

As it stands, everyone using SolidCP who updated their Smart mail can no longer control it 😔
Michael Replied
Please describe the token revocation process in the public API documentation.
Sven Replied
I agree, a description in the public API documentation would be very helpful.

One point in particular is unclear, at least to me: if multiple automated tools use the same admin user for impersonation, will they revoke each other's tokens? Or is the token also bound to the client ID, so that user Admin with client ID A and user Admin with client ID B do not interfere with each other? If it is the first case, this would break a lot of existing integrations.
Webio Replied
Soooo ... I've added:

clientId = "MSPControl"
to auth/authenticate-user and settings/domain/impersonate-user operations in MSPControl and sent Bruce provider for testing and it looks like it is working. My question here is: when clientId param was introduced and how it can affect pre 9770 builds? It would be good to have API changelog or possibility to see some snapshots of API documentation from various of builds.
Sérgio Rocha Replied
Hi,

We use SolidCP as well, but we were lucky enough to be alerted by Ben in time, so we haven't been affected.

Is this issue still ongoing, or has it been resolved only for MSPControl?

Regards,

SR
Andrew Barker Replied
Employee Post
To answer @Webio 's question, clientId was added back in February 2024, I believe it was included in build 8818. At that time, the APIs were modified so that if a clientId was not supplied when authenticating, the refresh token would not be registered so the access token could not be refreshed. Since then, we have made adjustments so that a refresh token isn't even returned if a clientId isn't included in the authentication.

Prior to introducing clientId, we had several tickets involving performance issues for some accounts. In each case, we determined that the issues were linked to how SmarterMail persists registered refresh tokens. When we dug further, we discovered that affected accounts were using third party software to access SmarterMail's APIs. The software involved was authenticating every time it wanted to make API calls, never reusing or refreshing tokens across separate runs. As a result, the refresh tokens stayed registered until they expired.  Depending on the frequency the software ran, this could result in tens of thousands of registered refresh tokens for a single account.

Andrew Barker
Lead Software Developer
SmarterTools Inc.
www.smartertools.com 

Ben Replied
Ok, but is there a way to get this working with older systems that aren't passing the clientID, as now everything is broken, which is pretty bad for a control panel. 

Yes you could argue they should update, but also a breaking change on an API shouldn't just happen...

Reply to Thread

Enter the verification text