When to use this endpoint

Use the linked-jobs list’s unlink action for quotes, direct invoices or ancillary invoices. Use Job_taskUnlink for task associations instead.

Authentication and permissions

Signed API-key authentication or a logged-in CRM session is required. The handler uses the authenticated tenant and has no additional role/page check.

The dispatcher also applies user/account and IP restrictions. CRM sessions carrying a CSRF token must supply X-FMCSRF or _csrf; missing or incorrect tokens can be rejected before the handler runs.

Parameters

ParameterTypeRequiredDescription
from_idInteger stringYesPositive physical job ID; no job existence/active check.
to_idInteger stringYesPositive quote or invoice ID for this relation; no target existence requirement before removal.
type_numInteger stringYes2=quote, 3=direct invoice, 4=ancillary invoice. Integer conversion must fall within 2–4.

Example request

$result = FM_api('Job_unlink', [
	'from_id' => '1042',
	'to_id' => '501',
	'type_num' => '3',
]);

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: from_id"}Missing/nonpositive from_id; to_id has analogous guard.
{"error":"missing or invalid parameter: type_num"}Integer value outside 2–4.
{"error":"Unable to save job delivery changes"}A checked database write, audit or transaction failed; local transactional writes roll back. Cross-tenant files/commits are not distributed-atomic.

Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.

Behaviour and edge cases

  • Deletes exact matching from_id/to_id/type_num relation rows. Missing relations still return ok; job and target rows are not verified first.
  • For a removed type-3/type-4 relation, recomputes the target invoice’s distinct linked-job count in jobs_linked or legacy jobs_linked_ancilliary. Normalizes malformed invoice metadata before updating its count and edit markers.
  • Repeated unlink of an absent pair is a no-op: no count changes, history or deletion audits. Legacy invoice-pointer fields are not cleared.
  • Type 2 refreshes the target quote’s has_jobs from its remaining distinct linked-job relations and advances its edit time; it does not touch an invoice with the same numeric ID.
  • Copied quote costs, invoice rows, invoice/job sent markers and business objects are retained. No filtering, pagination, finance-role guard or active-object check applies.
  • Locks the job and target when present, then all matching links. Exact link deletion, every tenant deletion audit, history and cached target counts commit together; a persistence/audit failure rolls back.

Side effects

  • Physically removes association rows, audits each relation ID through the tenant deletion log, and writes job unlink history only when relations were removed.
  • Type-3/type-4 branches adjust invoice metadata counts without advancing invoice edit timestamps/markers. No cost reversal, mail or configured edit event is performed.

See it in Fieldmotion

CRM1

Open an invoice’s linked-jobs list and unlink a job. pageInvoices.js calls Job_unlink with type_num, from_id and to_id through its save helper.

CRM2

Open the invoice module’s linked jobs and choose Unlink. moduleInvoices.js posts the relation type and IDs then removes the displayed row; filter Job_unlink.

Related endpoints