When to use this endpoint

Use after loading the available work locations and collecting the user’s complete selection. Send [] to clear every linked area; this call replaces rather than appends.

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.

Requires login and an owned tenant user. Ordinary self-profile edits are allowed; editing another user requires client administrator or explicit Users Edit permission. Protected membership fields require that permission even for self. Configured TeamAccess record scope and relationship checks remain in force.

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 stringYesTarget user ID in the authenticated tenant. Parsed with intval; this is a single-record operation, with no pagination or sort controls.
location_idsJSON-encoded array or native arrayYesComplete positive location-ID list. Encoded/native [] clears memberships. IDs are validated, deduplicated and sorted; objects, negative/zero IDs and malformed entries are rejected.

Example request

$result = FM_api('User_setAreas', [
	'id'=>'1042',
	'location_ids'=>json_encode(['18', '23']),
]);

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": "parameter missing or invalid: id"}id converts below 1.
{"error": "parameter missing or invalid: locations"}location_ids is omitted or does not decode to an array/object; the error uses locations, not the wire name.
{"error": "user does not exist"}No target user belongs to the authenticated account.
{"error": "only client admins or users with Users edit permission can edit other users"}Caller targets another user without explicit edit authority.
{"error": "Unable to save user changes. Check the saved state before retrying."}A checked write/transaction failed; inspect saved state before retrying, especially for separate global identity storage.
{"error":"location does not exist"}At least one requested location is absent or deleted; existing selection is retained.

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

Behaviour and edge cases

  • Requires the shared User edit policy for the protected areas field, including self changes, and a target in the authenticated account.
  • Validates the full selection against existing non-deleted tenant locations before removing old type-7 links. Unknown/deleted locations return location does not exist.
  • Replacement, user edit marker and activity history share a checked tenant transaction. Failed insertion or audit rolls back the previous links; nested callers use savepoints.
  • This changes work-area relationships only, not the scalar work-location field. Empty selection intentionally removes all current work-area links.

Side effects

  • Replaces work-area links, stamps their Unix edit times and the user’s edit markers, records areas history and invalidates users/employees caches. No global user metadata is copied.

See it in Fieldmotion

CRM1

Open a CRM1 User → Main → Work areas selector. User_setAreas sends id and JSON.stringify of the entire location selection.

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