When to use this endpoint

Use for empty placeholder-row cleanup. Despite the endpoint and parameter names, column indexes an entire stored row, not a form-definition column.

Read the current row order first; successful removal shifts the zero-based indexes of later rows.

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
appointment_idInteger stringYesPositive physical job ID. This exact legacy wire name is required; id/job_id are not aliases.
table_idInteger stringYesPositive table ID in the saved table answers.
columnInteger stringYesZero-based outer row index, converted with intval. Defaults to -1 and must be nonnegative.
forceInteger stringNoLegacy bypass: default 0; any nonzero integer skips the emptiness check. Avoid using this as a normal empty-row cleanup option.

Example request

$result = FM_api('Job_deleteEmptyTableColumn', [
	'appointment_id'=>'1042', 'table_id'=>'302', 'column'=>'1',
]);

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: appointment_id"}Job ID is nonpositive.
{"error":"missing or invalid parameter: column"}Converted index is negative.
{"error":"missing or invalid parameter: table_id"}Table ID is nonpositive.
{"error":"Job does not include data from table 302"}The active job’s saved collection has no requested table; missing/deleted jobs also reach this branch.
{"error":"That column does not exist in the appointment table data"}Requested stored row is not present and the index is beyond the table length.
{"error":"Cannot delete that column as it is not empty"}At least one cell is PHP-truthy and force is zero.
{"error":"Unable to save job"}The primary database save failed. Successful-save history and subsequent follow-ups are not run.

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 active jobs are read and updated. No table-form schema or field is deleted.
  • A row array is considered empty when every cell is PHP-falsy: numeric zero and the string "0" do not protect the row from removal. Non-array legacy row values are not inspected for nonempty cells.
  • Splices one outer row and reindexes the remaining rows. There is no paging, optimistic concurrency control or returned updated table.

Side effects

  • Writes canonical table JSON, last_edited and edited_uuid; invalidates the meetings cache and records job history. The database write is checked before history is recorded.
  • Does not rebuild asset links, recalculate costs, return consumed stock, delete image files or mirror outsourced table answers.

See it in Fieldmotion

CRM1

The Tables page’s empty-row cleanup in pageJobTables.js removes empty local rows and calls Job_deleteEmptyTableColumn using appointment_id, table_id and column. Watch Network while editing tables.

CRM2

No direct canonical or legacy caller was found in CRM2’s source. Its table form editing is a separate workflow; do not infer that this cleanup route runs there.

Related endpoints