When to use this endpoint

Use for a deliberately selected metadata property after reading the current job; this is a low-level setter rather than a typed business-workflow endpoint.

Use dedicated job actions for completion, assignment or invoice workflows: editing their metadata here does not invoke those workflows.

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.
keyStringYesTrimmed truthy top-level property name. Blank and string 0 are rejected; no metadata-key allowlist.
valStringYesTrimmed truthy input. Blank and string 0 are rejected. With json unset it is stored as a string; cannot remove a property or save an empty string.
jsonStringNoDefaults to 0. Loosely equal to 1 enables associative JSON decoding of val; malformed JSON is saved as null without an error.

Example request

$result = FM_api('Job_setMetaVal', [
	'id'=>'1042', 'key'=>'integration_details',
	'val'=>json_encode(['external_reference'=>'EXT-1042']), 'json'=>'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: id"}Nonpositive ID.
{"error":"missing or invalid parameter: key"}Trimmed key is falsey.
{"error":"missing or invalid parameter: val"}Trimmed val is falsey.
{"error":"job does not exist"}No job row is read.
{"ok":1,"warning":"no change needed"}Existing property loosely equals the raw trimmed input before optional JSON decoding; no write occurs.
{"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

  • Lookup and UPDATE require an active job. The handler checks neither assigned-user scope nor permitted metadata names.
  • Compares before decoding JSON; semantically equivalent JSON is not a reliable no-change contract. Only the selected top-level key is replaced, not merged recursively.
  • Existing scalar/corrupt metadata is normalized to an empty collection before the selected key is saved. There is no pagination, maximum value length or concurrency token.

Side effects

  • Unchecked metadata/timestamp/edit-marker UPDATE and meetings-cache invalidation; no direct history entry.
  • Does not recalculate costs/prices, queue notifications, apply completion canonicalization, update linked invoices or mirror outsourced state.

See it in Fieldmotion

CRM1

No direct canonical or legacy caller was found in CRM1’s source. This endpoint is available to integrations and internal server calls; do not infer a dedicated screen.

CRM2

No direct canonical or legacy caller was found in CRM2’s source. Its layout-driven job editing uses a separate contract.

Related endpoints