When to use this endpoint

Use with User_getMeta for ordinary UI preferences. JSON text submitted as val remains a string; this setter does not parse it into a nested object.

Trusted login-origin/token keys are reserved. This endpoint must not be used to mint login credentials.

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.

The handler requires an authenticated tenant and adds no administrator, Users page or self-only permission check. This describes this legacy route; permissions enforced by other User update routes do not automatically apply here.

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
nameStringYesTrimmed, nonempty top-level key. The initial truthiness check also rejects 0. is_tmp, login-md5, login-md5-expires and login-source are reserved after trimming.
idInteger stringNoOmitted/null defaults to current user. Unlike the getter, explicit blank or zero becomes 0 and produces user does not exist.
valScalar stringNoOmitted/null defaults to an empty string. Stored directly without decoding JSON or deleting the key.

Example request

$result = FM_api('User_setMeta', [
	'name'=>'dashboard',
	'val'=>'[]',
]);

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: name"}Omitted/null/falsy or whitespace-only key.
{"error": "reserved user metadata key"}Key matches a reserved login key.
{"error": "user does not exist"}No tenant user for converted ID.
{"error": "only client admins or users with Users edit permission can edit other users"}Caller targets another user without explicit permission.

Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.

Behaviour and edge cases

  • Self preference changes require login. Editing another user requires client admin or the explicit Users edit permission; a permissive missing-role fallback is disabled for this check.
  • Loads the tenant row by ID without active/deleted/parent filtering. The global lookup/update additionally requires the authenticated parent. Malformed stored metadata is reset to an empty map before this key is merged.
  • Tenant/global metadata are merged independently so unrelated keys unique to either store survive. The handler does not update current session userdata.meta.
  • Reserved key rejection occurs before the target read. The trusted is_tmp identity flag cannot be changed through this preference API; authorized temporary-user management uses the protected mapped isTmp field. With hierarchy enabled the dispatcher also requires admin for names beginning hr_profile; ordinary preferences still follow the self/editor check.
  • 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.

Side effects

  • Writes both metadata stores with edit markers, invalidates employees cache and logs meta updated. No login token, email or background sync is created by the operation itself.

See it in Fieldmotion

CRM1

CRM1 saves Dashboard layout through User_setMeta name=dashboard and JSON-text val. User Main preferences and the app stylesheet dialog also use this route.

CRM2

The fmTools app stylesheet dialog uses User_setMeta with id, name=app_css_url and val. Filter the request and compare with the preceding User_getMeta response.

Related endpoints