When to use this endpoint

Use for the CRM1 Tables image editor after obtaining table ID and zero-based row/field positions.

Job_setSubFieldImage is the different multipart contract used by CRM2’s job Form tables.

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 stringConditionalPositive physical active-job ID. Preferred name; defaults to the legacy alias only when absent/null.
appointment_idInteger stringConditionalLegacy fallback when job_id is absent/null; defaults to 0 if neither is supplied. A present job_id=0 does not fall back.
table_idInteger stringNoDestination table ID, integer-converted; defaults to 0 and is not checked against form definitions.
xInteger stringNoZero-based row position; default 0, no bounds validation.
yInteger stringNoZero-based field position; default 0, no bounds validation.
jpegBase64 stringConditionalRaw base64 image bytes or the exact data:image/jpeg;base64, prefix followed by base64. Decoding is non-strict. If present it overrides Filedata, even when blank.
FiledataMultipart fileConditionalAlternative upload part; the handler reads its temporary-file bytes. Supply one nonempty image source.

Example request

$result = FM_api('Job_setTableCellImage', [
	'job_id'=>'1042', 'table_id'=>'302', 'x'=>'0', 'y'=>'1',
	'jpeg'=>base64_encode($imageBytes),
]);

Example response

{"ok":1,"val":"{\"src\":\"appointment-1042-1791714600.1234.jpg\",\"cid\":\"42\"}"}

val is an encoded JSON string with src and the authenticated account’s cid; cid is the session value, commonly a string. The generated src uses the exact legacy appointment- filename prefix.

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":"no jpeg parameter supplied"}No nonempty bytes; checked before login. Coordinates are not explicitly validated.
{"error":"Unable to save job"}The primary database save failed. Successful-save history and subsequent follow-ups are not run. Image storage may already have created a file.
{"error":"job does not exist"}The job does not exist or is soft-deleted; no answer or resource write is performed.
{"error":"Unable to store job image"}Image storage reported failure or did not return a positive file-metadata ID; no answer reference is saved.
{"ok":1,"val":"{\"src\":\"appointment-1042-1791714600.1234.jpg\",\"cid\":\"42\"}","warning":"Job saved; follow-up incomplete. Inspect saved state before retrying.","warnings":["Unable to mirror outsourced image"],"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

  • Image bytes are not validated as JPEG. A .jpg filename does not prove the content type; a base64 value takes precedence over an uploaded file.
  • Each upload creates a new image reference; replacing a cell/answer does not delete its previous image file. Storage errors or a missing file-metadata ID return Unable to store job image before the answer is saved.
  • Recognized images larger than 1024 pixels in either dimension are aspect-fitted within 1024×1024 and re-encoded as JPEG quality 85 when GD succeeds. Smaller, unrecognized or unsuccessfully decoded images retain their original bytes.
  • Requires an active job before storage is attempted; lookup and UPDATE both exclude deleted jobs. Missing or nonpositive job IDs return job does not exist without creating a file.
  • Creates missing tables, row gaps and preceding blank cells, then stores the encoded src/cid reference. No field-type or attached-form validation occurs.

Side effects

  • Creates checked type-8 image storage/metadata, then performs a checked active-job table-answer/timestamp/edit-marker UPDATE, meetings-cache invalidation and generic job history.
  • Mirrors the stored image bytes and reference to an active outsourced counterpart, using its account ID in the mirrored cell. A missing/deleted counterpart receives no copied file; a failed mirror returns a saved-state warning.
  • No cost or asset-link recalculation, old-image cleanup or transaction is used.

See it in Fieldmotion

CRM1

Upload an image in a job’s Tables page. pageJobTables.js converts it to a JPEG data URI and sends Job_setTableCellImage with appointment_id, table_id, x/y and an extra name that this handler does not read.

CRM2

No direct caller was found in CRM2. Its job Form subform upload uses Job_setSubFieldImage with formID and multipart Filedata instead.

Related endpoints