Programme Contracts
Save Contract operational settings
/a/ContractProgramme_saveConfig
Configure inherited Forms, checklist selection, QI and Site measurement fields without editing source master data.
When to use this endpoint
Read ContractProgramme_contract first and send its configuration revision and only the raw choices being edited. Use config.form_overrides when editing inherited Forms; effective IDs would freeze inheritance.
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
| Parameter | Type | Required | Description |
|---|---|---|---|
contract_id | Positive integer or digit string | Yes | Local, non-deleted Contract with an accessible Programme configuration. |
revision | Integer-compatible | No | When supplied must match current config revision; omit only with deliberate lost-update risk. |
sector | String | No | Exact configured name or blank, max 64 characters; an unchanged retired value remains accepted. |
service_form_id, qi_form_id | Integer-compatible | No | Zero inherits module defaults. Nonzero choices must resolve to an unarchived Job Form (type=0). Omitted fields retain the current override. |
qi_field_id | String | No | Max 64 characters; existing choice/contract-grade field identity. Blank inherits only when effective QI Form matches the module QI Form. |
grading_set_id | Integer-compatible | No | Zero clears; nonzero must be an active non-deleted set. QI field/Form/set changes require contractProgrammeQI. |
area_field_id, duration_field_id | Strings | No | Existing Site custom field names from bootstrap.site_fields, or blank; max 64 characters. |
default_duration | Positive integer or digit string | No | 1–1440 minutes; omitted retains current configuration. |
portal_qi, portal_progress | 0/1 or boolean | No | Contract-level Portal view switches; changing either requires contractProgrammePortal. |
checklist_template_id | Integer-compatible | No | Named template ID; 0 explicitly disables checklists. Omitted preserves selection or legacy fallback. |
Example request
$result = FM_api('ContractProgramme_saveConfig', [
'data' => json_encode([
'contract_id' => 210,
'revision' => 1,
'service_form_id' => 301,
'default_duration' => 60,
]),
]);
Example response
{
"ok": 1
}
Errors and unusual responses
| Response | Condition |
|---|---|
{"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":"Contract settings changed. Reload before saving."} | Supplied config revision is stale. |
{"error":"Choose an existing QI choice field"} | Effective QI field does not match the Form. |
{"error":"Choose an existing Site custom field"} | Area/duration field is not in the Site catalogue. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- Only a client administrator may initialize a missing configuration for an existing non-deleted Contract. Existing configurations require Contract scope. The save increments revision even if values are unchanged.
- manager_id and area_id are not writable through this operation. It changes operational settings only.
- The resolved Form combination is validated even for unrelated changes. Zero Form overrides inherit dynamically; a blank QI field never borrows from another QI Form.
- Selecting a checklist refreshes only incomplete Jobs with no saved checklist answers. Answered/completed snapshots are retained.
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.
- Audits contract_settings_saved; checklist changes update Contract metadata and eligible Job snapshots/sync timestamps. Published inspection grade snapshots are preserved.
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 a Programme Contract → Contract Settings, edit the choices and Save; filter for ContractProgramme_saveConfig. Checklist Apply Template and QI Apply Set also use this route.
Related endpoints
ContractProgramme_saveDefaults— Maintain inherited Forms.ContractProgramme_saveChecklistTemplate— Maintain named checklist questions.ContractProgramme_saveGrades— Maintain a versioned QI set.