Jobs: recurrence workflows and lists
Edit one mapped recurrence field across selected rows
/a/JobRecurrence_updateField
Edit one mapped recurrence field across selected rows.
When to use this endpoint
Edit one mapped recurrence field across selected rows.
Authentication and permissions
Authenticate with signed API-key fields or a logged-in CRM session and tenant context. Job edit-restriction bit 128 applies, with the existing client-administrator exception. There is no additional recurrence-owner or department-visibility filter.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
field | Mapped setting name | Yes | Writable name from the allowlist below; server-owned fields are rejected. |
val | Type-dependent | Yes | Non-null replacement value, validated by the checked recurrence save. |
id / ids | Positive integer or native array | Yes | id takes precedence. Strict positive IDs; a JSON array string is not decoded. |
Example request
$result = FM_api('JobRecurrence_updateField', ['id'=>'1042', 'field'=>'name', 'val'=>'Monthly checks']);
Example response
{"ok":1,"oldData":[{"id":"1042","name":"Old name"}]}
A saved follow-up failure returns ok=1, saved=1 and warning/warnings, with followUpResults per recurrence when cleanup/reconciliation has details. Reload persisted state before retrying. Bulk errors identify the saved prefix; they are not all-or-nothing saves.
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":"No permission to edit"} | Job edit restriction applies. |
{"error":"missing or invalid parameter: field"} | Required selector absent or malformed. |
{"error":"missing or invalid parameter: val"} | Replacement absent/null. |
{"error":"missing or invalid parameter: id/ids"} | No row selector. |
{"error":"missing or invalid field"} | Unsupported/server-owned mapped key. |
{"error":"missing or invalid parameter: every"} | Strict integer/range validation failed; parameter varies. |
{"error":"missing or invalid parameter: val"} | Malformed mapped expiry, via the shared date validator. |
{"error":"job recurrence 1042 does not exist"} | No existing recurrence; numeric ID varies. |
{"error":"Unable to save job delivery changes"} | Checked local persistence/history failed. Earlier bulk rows may remain saved. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- Writable mapped keys: name, notes, active, every, onArr, eDate, copyUser, copyCustRef, copyJobRef, skipWeekends, userID, formID, departmentID, customerID, customerType, customer, user, schedule, custom, metaJobType. Use focused setters for the metadata copy-value/loop/form-values/due-offset options.
- Cache IDs, creation dates/creator, raw metadata, files, next dates, edit markers and generation horizon are server-owned and cannot be changed through these mapped writers. The id input selects the row; it cannot replace its primary key.
- Shares strict booleans, mode/selector and calendar validation with the checked settings save. every/onArr use the same ranges as JobRecurrence_set; when every alone is supplied, the stored selector is validated against that new mode. Name is at most 255 bytes. eDate blank clears expiry.
- Notes accept a native list or encoded list; plain text becomes a content entry. Schedule accepts a structured object or object JSON and validates override maps. Custom accepts decoded/encoded JSON arrays or objects. Generic raw JSON replacement is not supported.
- User assignment validates an active tenant assignee; forms must be valid non-archived Job forms; department/customer/asset/job-type targets must exist. Customer/department changes store explicit generation overrides, without retargeting existing children.
- Changed generation settings trigger checked from-now child cleanup. Expiry-only changes retain the inclusive tenant-local cutoff day; clearing expiry alone does not delete jobs. Notes/name/custom-only changes do not rebuild jobs.
- Settings/history commit locally before cleanup and worker/reminder reconciliation. Follow-up failures return committed-save warnings. No changes return ok without extra writes/history or scheduling work.
- Success retains oldData as a list of raw database-column snapshots for the selected field (meta for metaJobType); no matching row is an error.
Side effects
- Locks each existing recurrence and commits changed fields, edit timestamp/operation marker and checked history in a tenant transaction. Public Job edit restrictions apply to both writers.
- Runs generation cleanup and checked global scheduler/expiry-reminder reconciliation after a scheduling save. Inspect saved warnings before replaying.
- No mention/update notification wrapper is invoked by updateField.
See it in Fieldmotion
CRM1
No direct production CRM1 caller was found. The recurring-jobs screen uses focused controls and its legacy table.
CRM2
The shared CRM2 updateField/autosave helper builds this route dynamically for a recurrence prefix; no explicit direct literal caller was found. Recurring Jobs notes and bulk active controls specifically use updateData, not updateField.
Related endpoints
JobRecurrence_setperforms checked frequency/settings saves with lifecycle follow-ups.