When to use this endpoint

Use after reading the current mask and modifying the intended bits. val replaces the whole mask; this is not an add/remove-bit operation.

App permissions, general permissions and CRM access are separate masks; changing one does not update the others.

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. A non-admin receives {"error":"only admins can edit user app permissions"}.

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

ParameterTypeRequiredDescription
idInteger stringYesExisting 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.
valInteger stringYesComplete nonnegative integer mask, at most 2147483647. 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_setAppPermissions', [
	'id'=>'1042',
	'val'=>'3',
]);

Example response

{
  "ok": 1
}

Errors and unusual responses

ResponseCondition
{"error":"not logged in"}No authenticated tenant context is available. Invalid signed credentials can be rejected by the dispatcher before the handler runs.
{"error": "missing or invalid parameter: val"}val is omitted or null; this check runs before the administrator check.
{"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.
{"error":"only admins can edit user app permissions"}Caller is not a client administrator.

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.
  • The mask contains both granting and restricting bits. A set bit does not universally mean allow; preserve unrelated bits from the existing value. No refresh or push to a running mobile client is sent by this handler.
  • 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.

See it in Fieldmotion

CRM1

Open Users → Main → App permissions in CRM1 and toggle a setting. User_setAppPermissions receives the selected user and the complete updated mask.

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