When to use this endpoint

Choose an existing live Visit/day in Job Progress. Select its scoped Contract/Site, kind and duration. Use one stable request_key for exact retries.

Send operation fields inside one JSON-encoded data object. When data is present it replaces top-level operation fields; otherwise the handler accepts the top-level request. String data is limited to 2 MB. Reserved transport/internal keys are removed. Malformed or non-array JSON becomes an empty input, so validate JSON before sending.

Authentication and permissions

Authenticate with a signed API key or logged-in CRM session; session requests follow dispatcher CSRF checks. API-key requests use the key owner’s identity and permissions.

Requires the Contracts entitlement (features & 64), features2.contractProgrammes and Contracts View. Also requires features2.contractProgrammePublishing. Requires Contracts Edit.

All storage belongs to the authenticated tenant. Contract operations follow the actor’s recursive HR manager/team scope, or the configured TeamAccess Contract/Department policy. Client administrators have broad Contract scope; private Programme and route ownership still applies. Active assignees must be within the permitted team.

Non-administrators also need Jobs Add; TeamAccess field roles cannot add through this workflow.

For newly created work, the configured CRM Job customer/Contract eligibility restriction is checked independently. Publication revalidates it before changing prior work; adopted reactive Jobs use their existing identity.

The tenant must have the Programme storage upgrade (foundation 803; independent route ownership 804 before planning). Requests never create or repair tables. A missing/incompatible storage failure can return an initialization/storage error or Contracts operation failed. Check the saved state before retrying.

Parameters

ParameterTypeRequiredDescription
visit_idPositive integer or digit stringYesExisting live, non-deleted Visit. Actor owns its run or can see published work in that Visit.
contract_idPositive integer or digit stringYesActive, non-deleted Contract (active=1) with an accessible Programme configuration. Inactive/Completed Contracts reject new Service and QI work.
site_idPositive integer or digit stringYesActive non-deleted child Customer linked to the Contract.
day_numberPositive integer or digit stringYesExisting numbered day in the Visit’s saved route revision.
dateYYYY-MM-DDYesExplicit tenant-local calendar date; accepted independently of the Visit start/end range.
user_idPositive integer or digit stringNoDefaults to Visit user; both Visit user and target must be active/in permitted team.
kindS or QNoDefaults to S (Service). Q requires contractProgrammeQI and a configured active grading set, QI Form and choice field.
duration_minutesPositive integer or digit stringNoDefaults to Contract default_duration; 1–1440 minutes.
request_keyStringYesNonblank trimmed replay key, max 64 characters. Same actor and exact request return saved result; changed data with same key fails.

Example request

$result = FM_api('ContractProgramme_addJob', [
	'data' => json_encode([
		'visit_id' => 710,
		'contract_id' => 210,
		'site_id' => 1043,
		'day_number' => 1,
		'date' => '2026-11-10',
		'kind' => 'S',
		'request_key' => 'extra-north-2026-11-10-1',
	]),
]);

Example response

{
  "ok": 1,
  "id": 812
}

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":"Inactive or completed Contracts cannot receive new work"}The selected Contract is not active. No new Job, audit or replay acknowledgement is saved.
{"error":"No start time remains on the selected date"}Existing work runs through the remaining date; choose another date or adjust the live schedule.
{"error":"Programme Contracts is not enabled"}Workspace flag or Contracts entitlement is disabled.
{"error":"Permission denied"}Contracts View or the required action permission is unavailable.
{"error":"This Contracts capability is not enabled"}The operation’s additional feature flag is disabled.
{"error":"Choose a live Visit"}Visit is missing, deleted or not live.
{"error":"Choose an existing Visit day"}day_number not in saved route revision.
{"error":"Request key has already been used for different data"}Replay key reused with another payload or actor.

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

Behaviour and edge cases

  • Creates a new Job and ad_hoc provenance; it does not adopt an existing reactive Job or change the master route. Position is one greater than the maximum in this Visit/day.
  • The Job starts no earlier than account work-day-start (fallback 09:00), after the latest scheduled end of existing work for the selected local user/date. Ordinary Jobs and earlier ad hoc Jobs count, including work crossing from the previous date; cancelled, deleted and archived work do not. Duration comes from hours. Capacity remains advisory. If no start remains before local midnight, the call fails rather than silently scheduling on another date.
  • The Contract must be active. The explicit live date may differ from the Visit’s original date range, supporting rescheduled work; it does not change the reusable route or the saved Visit boundary.
  • QI snapshots the current grading set revision/labels/categories and choice-field identity. Later set edits do not rewrite it. New Job checklist snapshots and normal reference/report numbering follow the shared materializer.
  • An exact completed replay returns its original id and schedule without allocating another time, even if the Contract was later deactivated. Current authentication/feature/role gates still apply. No ordinary Job_new event/email workflow is invoked.
  • The new Job’s due_date uses its scheduled date and its initial date_completed is an estimated end. is_complete remains 0; these timestamps do not indicate finished work.

Side effects

  • The service serializes writes on the tenant owner in a transaction. Validation, persistence, audit or TeamAccess outstanding-Job access failures roll back that transaction. Successful changed writes refresh linked Contract/Customer sync timestamps and shared mobile update markers, then invalidate CRM caches after success. These operations do not create schema or enable account features.
  • Commits new Job, Contract link, Site open-Job counter, provenance, Job/ad_hoc_job_added audits, snapshots and replay acknowledgement atomically. Does not create standalone Tasks.

See it in Fieldmotion

CRM1

No direct caller was found in CRM1 source. This workflow is implemented by the opted-in CRM2 Programme Contracts workspace.

CRM2

In Job Progress open Add Job on a live day. Filter for ContractProgramme_addJob. CRM2 supplies that day’s Visit, user, day_number and scheduled_date, a selected Contract/Site and one generated key.

Related endpoints