When to use this endpoint

Use for a usage-list adjustment with id/source/amt rows. Choose Job_setStock for the legacy Resources replacement flow that also adjusts stock levels.

For order replacement, include every replacement row for each requested order source; an empty request does not identify which source to clear.

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 stringYesRequired by presence, integer-converted without positivity validation. The referenced job must be active.
stockUsedJSON array string or arrayYesUsage row list. Normal add/delete rows require id, source and amt; quantities are not validated as positive/numeric. Matching uses loose id/source comparison. Malformed nonarray input is wrapped and rejected in add/delete, but replaceOrder has weaker validation.
optionStringYesUse add, delete or replaceOrder. There is no allowlist check: unknown values can still filter and rewrite old rows without applying the requested delta.
stockUsed[].linkIDString inside stockUsed JSONNoFor replaceOrder, absent linkID is generated as r followed by current Unix seconds plus row position; it is not a uniqueness guarantee.

Example request

$result = FM_api('Job_setStockUsed', [
	'id'=>'1042',
	'stockUsed'=>json_encode([['id'=>205,'source'=>'0_0','amt'=>2]]),
	'option'=>'add',
]);

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"}id is absent/null.
{"error":"missing or invalid parameter: stockUsed"}stockUsed is absent/null, or add/delete rows lack required members/array shape.
{"error":"missing or invalid parameter: option"}option is absent/null.
{"error":"job does not exist"}No 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,"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

  • add increases the first matching old row’s amount, or appends a new row. A new unmatched row’s cost/price are overwritten from the stock catalog (missing stock defaults to zero); caller values are not preserved in that branch.
  • delete subtracts amount from the first match and ignores unmatched requests. Both delta branches discard all old rows whose resulting amt is nonpositive. Replays apply the delta again.
  • replaceOrder first identifies exact source tokens whose numeric prefix is 15 (requisition) or 16 (purchase), removes old rows with those exact sources, then appends every requested row. Other new source types append rather than replace. [] leaves existing order rows in place.
  • replaceOrder does not enforce the add/delete row-shape checks or remove nonpositive rows. Missing cost/price fields are subsequently enriched using generic catalog prices without the job customer’s price band.
  • Reads and updates only active jobs. No amount bounds, stock-active check, pagination, transaction or optimistic concurrency token is used. Unknown option strings are not a safe documented no-op.

Side effects

  • Unchecked ID-only stock_used/timestamp/edit-marker UPDATE with meetings-cache invalidation. No direct history entry.
  • Calls Job_updateCosts and Job_updatePrices; failures produce saved-state warnings. Deleted jobs are rejected before any usage changes.
  • Does not deduct or return warehouse/container stock, record stock movements, queue threshold mail or mirror outsourced usage.

See it in Fieldmotion

CRM1

No direct canonical or legacy caller was found in CRM1’s source. Its Resources stock widget uses Job_setStock with the complete desired list instead.

CRM2

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

Related endpoints

  • Job_getStock reads the job’s direct and field-specific stock usage before a resource edit.
  • Job_setStock replaces direct stock usage and adjusts legacy warehouse/container quantities.
  • Job_updateCosts refreshes cost/resource snapshots and invokes the price follow-up.