User accounts and profiles
Replace a user’s CRM access mask
/a/User_setCrmAccess
Store the complete legacy CRM access mask for another account user.
When to use this endpoint
Use alongside general User permissions when configuring legacy CRM module visibility. val replaces crm_access only and does not toggle role grants or app permissions.
Authentication and permissions
Authenticate with signed API-key fields or a logged-in CRM session. Session requests use the dispatcher’s CSRF protection when configured; signed requests follow the API-key authentication flow.
Client administrator access is required. No separate Users edit role is consulted by this handler.
The dispatcher applies configured TeamAccess user-record scope before the handler. An explicit target outside that scope returns an error; omitted targets use the current user for the scope check. Active/deleted filtering and additional target checks are described below.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | Integer string | Yes | Existing positive user ID owned by the current account, with a matching global identity. Missing or unmatched targets return an error. Existing self/main-account restrictions below still apply. |
val | Integer string | Yes | Complete nonnegative integer mask, at most PHP integer maximum. Missing, blank, negative, fractional, nonnumeric or nested values are rejected. Zero is valid; no per-bit role grant is inferred. |
Example request
$result = FM_api('User_setCrmAccess', [
'id'=>'1042',
'val'=>'0',
]);
Example response
{
"ok": 1
}
Errors and unusual responses
| Response | Condition |
|---|---|
{"error":"not logged in"} | No authenticated tenant context is available. Invalid signed credentials can be rejected by the dispatcher before the handler runs. |
{"error": "only admins can edit user CRM access"} | Caller is not a client administrator. |
{"error": "missing parameter: val"} | val is omitted or null. |
{"error": "you cannot edit your own CRM access"} | Caller targets self and is not the account owner. |
{"error": "user does not exist or is not in your company"} | No matching tenant-parent user. |
{"error":"missing or invalid parameter: id"} | Target ID is missing or invalid. |
{"error":"user does not exist"} | Owned tenant/global target is absent. |
{"error":"missing or invalid parameter: val"} | Mask is omitted or outside the supported integer range. |
{"error":"Unable to save user changes. Check the saved state before retrying."} | A checked update failed. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- Client-admin-only. The owned tenant user and global identity must exist. Non-admin callers receive an explicit JSON permission error; an absent target never receives a success acknowledgement.
- Requires a tenant user with the authenticated parent; no active/deleted filter is applied. The account-owner identity is exempt from the non-owner self-edit prohibition.
- Several mask bits are restrictions, while others grant special behavior. Do not interpret all nonzero masks as enabled access or zero as a complete authorization contract.
- CRM1’s admin toggle separately calls this route with 17408 when granting admin and 0 when removing it. Those extra writes are frontend behavior; User_setPermissions does not perform them itself.
- When department hierarchy and team access is enabled, the dispatcher wraps this User write in its access-relationship validation and can reject changes that would strand outstanding Jobs. This does not make file storage, session updates or separate global identity writes one atomic operation. Without that wrapper the handler itself has no enclosing transaction; read back saved state after an uncertain failure.
- No collection filtering, pagination, ordering or batch result is provided. Parameters on this page describe the supported scalar/encoded input; malformed nested values are not a supported contract.
- Both persistence results are checked. There is no distributed transaction across global/tenant storage; after an uncertain error inspect the saved mask before retrying.
Side effects
- Updates the global identity row and the tenant user row, with last_edited and an operation-specific edited_uuid; invalidates the employees cache. Both updates are limited by user ID and the authenticated parent account.
- Writes an entry in tenant user activity logs. It does not send an email, notification or password-reset message.
- Does not refresh the target user’s active session or explicitly revoke tokens.
See it in Fieldmotion
CRM1
Open a CRM1 User → Main → CRM Access and toggle a module. Filter User_setCrmAccess; it sends the full mask. Admin changes may trigger an additional request here.
CRM2
No direct production caller was found in CRM2. Its User layouts use the generic getRequestedDetails/updateData flow instead; do not assume that flow has the same validation or permissions as this legacy route.
Related endpoints
User_setPermissions— Configure general/admin permissions separately.User_setAppPermissions— Configure the app mask independently.