When to use this endpoint

Use for small table answer edits after reading the current table and its field order. Unspecified cells and tables remain.

Use Job_setTables only when intentionally replacing the entire saved table collection.

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
job_idInteger stringYesPositive physical job ID.
changesJSON object stringYesNonempty table-ID map of position-to-value maps, for example {"302":{"0_1":"Passed"}}. Positions are x_y: zero-based row then field index. Native arrays are not accepted by json_decode; inner shape/coordinate bounds are not validated.

Example request

$result = FM_api('Job_setTableCells', [
	'job_id'=>'1042', 'changes'=>json_encode(['302'=>['0_1'=>'Passed']]),
]);

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":"missing or invalid parameter: job_id"}Job ID is nonpositive.
{"error":"missing or empty parameter: changes"}Decoded changes is not an array or is empty.
{"error":"no such job exists"}No job row is read.
{"error":"Unable to save job"}The primary database save failed. Successful-save history and subsequent follow-ups are not run.
{"ok":1,"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

  • The job lookup and UPDATE both require an active job. No table-form existence, field type, required-answer or assignee scope is checked.
  • Splits each position string on underscore and integer-converts its first two components. Missing rows become arrays and earlier field gaps become empty strings; values are stored as supplied. Supply valid nonnegative, bounded indexes; malformed positions are not a supported error contract.
  • Whole stored table JSON is rewritten after merging. Concurrent edits can overwrite each other; there is no version token, paging or batch-size limit.

Side effects

  • Unchecked write of subform_values, last_edited and edited_uuid with meetings-cache invalidation and generic job history.
  • Calls Job_updateAssetJobs to rebuild derived asset associations and Job_updateCosts to enrich/recalculate resources and prices; follow-up errors produce saved-state warnings. No general outsourced-table mirror or stock-level reconciliation is called.

See it in Fieldmotion

CRM1

Edit a cell on a job’s Tables page. pageJobTables.js batches addressed cells into changes and sends Job_setTableCells. The rate picker also uses this contract for an encoded rate answer.

CRM2

Create a linked child job from a subform field in the job Form. pageJobForm.js sends Job_setTableCells with table ID and rowIndex_fieldIndex mapped to the child ID.

Related endpoints

  • Job_setTables replaces the full saved table collection and refreshes dependencies.
  • Job_tableRowAppend appends rows already in destination field order.
  • Job_updateCosts refreshes cost/resource snapshots and invokes the price follow-up.