When to use this endpoint

Reload bootstrap.sector_settings or the Sectors collection first. Submit the full desired active catalogue with stable IDs and the current revision; omitted active entries are retired.

Send operation fields inside one JSON-encoded data object. When data is present it replaces top-level operation fields; otherwise the handler accepts the top-level request. String data is limited to 2 MB. Reserved transport/internal keys are removed. Malformed or non-array JSON becomes an empty input, so validate JSON before sending.

Authentication and permissions

Authenticate with a signed API key or logged-in CRM session; session requests follow dispatcher CSRF checks. API-key requests use the key owner’s identity and permissions.

Requires the Contracts entitlement (features & 64), features2.contractProgrammes and Contracts View. Requires Contracts Edit.

All storage belongs to the authenticated tenant. Contract operations follow the actor’s recursive HR manager/team scope, or the configured TeamAccess Contract/Department policy. Client administrators have broad Contract scope; private Programme and route ownership still applies. Active assignees must be within the permitted team.

Only a client administrator may perform this operation, in addition to the permissions above.

The tenant must have the Programme storage upgrade (foundation 803; independent route ownership 804 before planning). Requests never create or repair tables. A missing/incompatible storage failure can return an initialization/storage error or Contracts operation failed. Check the saved state before retrying.

Parameters

ParameterTypeRequiredDescription
revisionScalar revisionYesMust exactly match sector_settings.revision, initially 0.
entriesArrayYes, unless sectors suppliedAt most 200 ordered {id,name} objects. id=0 creates; existing active ID renames. Nonblank trimmed name max 64 characters. [] retires every active entry.
sectorsArray of stringsLegacy alternativeUsed only when entries is null/omitted. Matches exact active names to preserve IDs; renamed text is treated as a new entry.

Example request

$result = FM_api('ContractProgramme_saveSectors', [
	'data' => json_encode([
		'revision' => 0,
		'entries' => [
			[
				'id' => 0,
				'name' => 'Parks',
			],
		],
	]),
]);

Example response

{
  "ok": 1,
  "sector_settings": {
    "sectors": [
      "Parks"
    ],
    "entries": [
      {
        "id": 1,
        "name": "Parks",
        "deleted": 0
      }
    ],
    "revision": 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":"Programme Contracts is not enabled"}Workspace flag or Contracts entitlement is disabled.
{"error":"Permission denied"}Contracts View or the required action permission is unavailable.
{"error":"Sectors changed. Reopen Sectors before saving."}Revision missing or stale.
{"error":"This Sector name belongs to another active or retired Sector. Choose a new name to preserve existing Contract and checklist references."}A name is reserved by another retained ID.

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

Behaviour and edge cases

  • Names are unique ignoring case across both active and retained retired entries. Swapping names, reusing another retired name or taking a name retired in the same request is rejected. Own-name case changes are accepted.
  • Renames preserve stable IDs and update active Contract configuration, Task-template and named-template Sector labels. Job snapshots retain historical wording.
  • Retirement removes the new-choice option, retains deleted/ddate metadata and existing Contract/template evidence. An unchanged retired Contract value remains saveable; it cannot be assigned to a new Contract.

Side effects

  • The service serializes writes on the tenant owner in a transaction. Validation, persistence, audit or TeamAccess outstanding-Job access failures roll back that transaction. Successful changed writes refresh linked Contract/Customer sync timestamps and shared mobile update markers, then invalidate CRM caches after success. These operations do not create schema or enable account features.
  • Writes contract-programme-sectors, advances its revision and audits module_sectors_saved. Retirements append tenant deletion-log records. No Contract or Job is deleted.

See it in Fieldmotion

CRM1

No direct caller was found in CRM1 source. This workflow is implemented by the opted-in CRM2 Programme Contracts workspace.

CRM2

Open Module Settings → Sectors, create, edit or delete a Sector. Filter for ContractProgramme_saveSectors; each UI action sends the complete remaining catalogue and revision.

Related endpoints