When to use this endpoint

Use Contract_addJob as part of a job save that assigns a known contract. The normal Job_new, Job_save, and mapped job-update flows call it internally.

It is not a complete job update: callers that own the job record must also keep the job’s contract_id synchronized.

Authentication and permissions

The request must authenticate with signed API-key fields or a logged-in CRM session. The handler performs no additional page or role-permission check.

The lookup and any write use the authenticated tenant; an ID from another tenant cannot be addressed through this call.

Parameters

ParameterTypeRequiredDescription
idInteger stringYesPositive target contract ID. The existence check includes soft-deleted contracts.
aidInteger stringYesPositive job ID under the established legacy parameter name. Job existence is not checked.

Example request

$result = FM_api('Contract_addJob', [
	'id' => '720',
	'aid' => '2039001',
]);

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"}The contract ID is absent, zero, negative, or nonnumeric.
{"error":"missing or invalid parameter: aid"}The job ID is absent, zero, negative, or nonnumeric.
{"error":"Contract does not exist"}No contract row has the converted ID.
{"ok":1,"warning":"job already linked to contract"}The type-6 link already points from this job to this contract; no write or audit entry is made.

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

Behaviour and edge cases

  • An existing type-6 link from the job to another contract is deleted before the target link is inserted.
  • The target contract may be soft-deleted, and a nonexistent positive job ID creates an orphan link.
  • The operation is idempotent only when the exact target link already exists; there is no transaction around delete, insert, audit, and cache invalidation.

Side effects

  • Writes the legacy link, records a contract audit event, and sets meta.customersDirty=1 on the target contract unless already set.
  • The former contract is not marked dirty when its link is removed.

See it in Fieldmotion

CRM1

Assign or change a Contract while creating or editing a job. The job save route calls Contract_addJob internally; it is not normally visible as a separate browser request.

CRM2

Assign a Contract in the CRM2 job editor and inspect the surrounding job save request. CRM2 does not call Contract_addJob directly from client JavaScript.

Related endpoints