When to use this endpoint

For older checklist definitions, read ContractProgramme_contract.tasks/task_revision or getDataTable(resource=tasks, sector=...) first. Named checklist selection takes precedence; this does not edit named template questions.

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.

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
contract_idInteger-compatibleNoNonzero selects an accessible Contract. Zero/omitted selects a Sector template and requires client administrator access.
sectorStringFor Sector templatesNonblank max 64 characters; when the Sector catalogue has been saved, must be an active configured name. Ignored for Contract lists.
tasksArray or JSON listYesExplicit complete ordered list, max 200. Missing, null, scalar, malformed JSON and JSON objects are rejected. Only [] or its JSON encoding clears intentionally. Each entry: nonblank subject max 128 characters; details string max 16000 (default blank); active 0/1 (default 1); task_type_id existing or 0 (default).
revisionSHA-256 stringNoWhen supplied, must match current task_revision. Omitting allows replacement without optimistic concurrency protection.

Example request

$result = FM_api('ContractProgramme_saveTasks', [
	'data' => json_encode([
		'contract_id' => 210,
		'tasks' => [
			[
				'subject' => 'Check access',
				'details' => 'Check the gate',
				'active' => 1,
			],
		],
	]),
]);

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":"Supply tasks as an explicit array or JSON list"}tasks is missing, null, a scalar, malformed JSON or a non-list object/array. The existing list is retained.
{"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":"Tasks changed. Reload before saving."}Supplied revision hash is stale.
{"error":"At most 200 ordered Tasks per template"}Decoded input is not a list or is too long.

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

Behaviour and edge cases

  • Existing definition rows are soft-deleted/audited and replaced with new IDs in array order; submitted row IDs are not retained.
  • Saving a Contract list marks tasks_customised=1 and increments config revision. An explicit empty list suppresses Sector fallback.
  • Publication snapshots active definitions as checklist questions; it creates no standalone Tasks. Existing published snapshots are not rewritten by this endpoint.
  • Warning: This is a full replacement. Send an explicit empty list only when you intend to clear every active definition. Invalid or omitted input returns an error without changing the saved list, audit or sync state.
  • Unlike ContractProgramme_saveChecklistTemplate, this legacy definition write does not refresh attached unanswered Job snapshots. New publication uses the current active definitions; existing evidence keeps its attached list.

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.
  • Records template-row deletions and task_template_saved. Does not refresh already attached Job checklist snapshots.

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

The older Sector checklist editor loads getDataTable(resource=tasks) and calls ContractProgramme_saveTasks. The named Checklist Template editor uses ContractProgramme_saveChecklistTemplate instead. Filter Network for the exact endpoint.

Related endpoints