Programme Contracts
Save a versioned grading set
/a/ContractProgramme_saveGrades
Create a grading-set revision without changing historical inspection results.
When to use this endpoint
Load the current set/revision before updating. Assign an active set to a Contract with ContractProgramme_saveConfig; new QI Jobs snapshot that version.
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. Also requires features2.contractProgrammeQI. 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 |
|---|---|---|---|
id | Integer-compatible | No | Zero/omitted creates; nonzero must be an existing non-deleted set. |
revision | Integer-compatible | For updates | Current revision from the read; stale versions are rejected. |
name | String | Yes | Nonblank trimmed name, max 128 characters; no name uniqueness check. |
active | 0/1 or boolean | No | Defaults to 1, including updates; inactive sets cannot be newly assigned or snapshotted. |
grades | Array or JSON list | Yes | 1–100 ordered objects. id (or code fallback) is nonblank max 32; label max 128; code max 32; colour is # plus 6 hexadecimal digits; category is above/to/below. Strings are trimmed. |
Example request
$result = FM_api('ContractProgramme_saveGrades', [
'data' => json_encode([
'name' => 'Inspection standard',
'grades' => [
[
'id' => 'pass',
'label' => 'To specification',
'code' => 'PASS',
'colour' => '#008800',
'category' => 'to',
],
],
]),
]);
Example response
{
"ok": 1,
"id": 910,
"revision": 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":"This Contracts capability is not enabled"} | The operation’s additional feature flag is disabled. |
{"error":"Grading set changed or is unavailable"} | Update ID missing/deleted or revision stale. |
{"error":"Each grade needs distinct labels, codes and identities"} | A token identifies multiple grades. |
{"error":"Choose a grade colour"} | Colour is not a six-digit hex colour. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- Grade identities must be unique. Tokens across every grade’s id/code/label must unambiguously identify one grade; comparisons are case-sensitive.
- Each save inserts a new immutable version, including unchanged submissions. Old versions and existing Job grade snapshots remain available.
- The existing QI Form choice field must be configured separately. Job completion validates one scalar grade against the saved snapshot; current Form choice edits do not reinterpret old inspections.
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 set header/current revision and immutable version; audits grading_set_saved. Assigned active Contracts advance sync timestamps; published Jobs remain unchanged.
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 Programme Contracts → Grading Sets → Create/Edit, add/reorder grades and Save. Filter for ContractProgramme_saveGrades; updates include the current revision.
Related endpoints
ContractProgramme_grades— Read latest grade choices.ContractProgramme_saveConfig— Assign the set and QI field.ContractProgramme_addJob— Create an inspection with a frozen snapshot.