When to use this endpoint

Use for the main-form autosave workflow after obtaining the attached form’s field names. Send only changed answers; unspecified answers remain.

This is not a general job-column setter and does not edit table cells. It accepts unknown names rather than validating them against the form.

Authentication and permissions

Authenticate with signed API-key fields or a logged-in CRM session. The handler performs no additional page or role-permission check.

Job and form IDs refer to the authenticated account. Cross-account writes occur only through the stored outsourcing relationship on the routes that explicitly mirror changes.

The dispatcher also applies account/user and IP restrictions. A CRM session carrying a CSRF token must supply it through X-FMCSRF or _csrf; missing/incorrect tokens can be rejected before this handler runs.

Parameters

ParameterTypeRequiredDescription
idInteger stringYesPositive physical job ID.
fieldsJSON object string or arrayYesTruthy name-to-value map. JSON-encode nested values before signing. Blank input is rejected, but encoded []/{} passes the initial check; decoded type/field values are not validated. Empty-string values clear individual answers.

Example request

$result = FM_api('Job_setFields', [
	'id'=>'1042', 'fields'=>json_encode(['Inspection result'=>'Passed']),
]);

Example response

{"ok":1,"0":[]}

The numeric property "0" contains the attached form’s decoded field definitions; this example uses a form with an empty definition array. It may instead contain definitions or null. It is not an answer count.

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":"missing or invalid parameter: id"}Job ID is nonpositive.
{"error":"fields paramater cannot be empty"}fields is missing/PHP-falsy; the misspelling is the wire response.
{"error":"job does not exist"}No active job is read.
{"error":"Unable to save job"}The primary database save failed. Successful-save history and subsequent follow-ups are not run.
{"ok":1,"0":[],"warning":"Job saved; follow-up incomplete. Inspect saved state before retrying.","warnings":["Job_updateCosts: Unable to save job"],"saved":1}The primary save succeeded, but a recalculation, asset rebuild, notification or outsourced mirror failed. warnings identifies the failed follow-up; any normal response fields remain present. A benign no-change result from a follow-up is not a failure. Read saved state before retrying.

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

Behaviour and edge cases

  • Merges every supplied name into decoded form_values, without required-field, form-name or field-type validation. Existing unspecified answers remain.
  • Known changed fields use loose old/new comparison and the form field’s meta.id for field history. Unknown names are still saved but do not get that per-field entry.
  • Changed known assets fields trigger Job_updateAssetJobs. That helper rebuilds derived asset links/movements from the job, main-form tracked assets and table assets; asset_not_tracked suppresses main-form tracking.
  • Malformed decoded fields or legacy answer data can cause warnings/runtime failures. No request row limit, pagination or optimistic concurrency check is provided.

Side effects

  • The checked primary UPDATE saves form_values, last_edited and edited_uuid and invalidates the meetings cache. Known-field history is recorded only after that save succeeds.
  • Conditionally rebuilds asset associations and always calls Job_updateCosts; follow-up failures produce saved-state warnings. No general outsourced-answer mirror or notification-mail call is made here.

See it in Fieldmotion

CRM1

Edit an ordinary answer in the job Form with editing enabled. pageJobForm.js collects changed names and sends Job_setFields after a 500 ms debounce, then recalculates the UI.

CRM2

Edit answers in the job Form and save/confirm. pageJobForm.js sends a JSON name-to-value map to Job_setFields, including its confirmation and calculation-save paths.

Related endpoints

  • Job_setField saves one main-form answer, including clearing an image reference.
  • Job_setTableCells patches selected row/field positions while retaining unspecified cells.
  • Job_updateCosts refreshes cost/resource snapshots and invokes the price follow-up.