When to use this endpoint

Use AssetMaintenance_create for the legacy CRM1 maintenance dialog after selecting an asset, job form, first date, frequency, and optional default user.

The current CRM2 Maintenance page models the workflow directly as an asset-scoped job recurrence and does not call this legacy wrapper.

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
asset_idInteger stringYesPositive asset ID. Positivity is checked early; tenant asset existence is checked later by job creation, after maintenance and recurrence rows have already been inserted.
next_dateDatetime stringYesFirst schedule/due datetime in YYYY-MM-DD HH:MM or YYYY-MM-DD HH:MM:SS shape. Only the character pattern is checked, not calendar validity.
meeting_time_eUnix timestamp stringNoFirst job start time. If blank/omitted, next_date is converted from the tenant timezone. When supplied, it can disagree with next_date; the latter still becomes the due date and maintenance next date.
recur_amtNumber stringYesFrequency amount, converted to float. The API accepts zero and negative values even though CRM1 requires a positive amount.
recur_periodInteger stringYesFrequency unit stored on the recurrence. CRM1 uses 3 days, 4 weeks, 5 months, or 6 years; the API does not restrict the integer.
form_idInteger stringYesPositive form ID for the first job. This wrapper checks positivity but does not verify a form row exists.
nameStringNoMaintenance description. Blank is accepted; maximum 236 characters. The recurrence is subsequently named Asset Maintenance: <name>.
jobrefStringNoFirst job reference. Blank delegates generation to the account’s normal job-reference settings.
default_userInteger stringNoDefault tenant-user ID, or 0. The reference is not validated; it is assigned to the first job and stored for later maintenance display.
expiry_dateDate stringNoPassed to recurrence creation. Blank/0000-00-00 means no expiry; other values are stored without date validation and may schedule the account’s recurrence-expiry notification.

Example request

$result = FM_api('AssetMaintenance_create', [
	'asset_id' => '418',
	'next_date' => '2026-10-15 09:00',
	'recur_amt' => '3',
	'recur_period' => '5',
	'form_id' => '12',
	'name' => 'Filter service',
	'jobref' => 'MAINT-418-1',
	'default_user' => '27',
]);

Example response

{
  "ok": 1,
  "rec": {
    "id": "879027",
    "name": "Filter service",
    "ids": "",
    "active": "0",
    "every": null,
    "on_arr": null,
    "customer_id": "0",
    "customer_type": "0",
    "edited_uuid": "JobRecurrence_create"
  },
  "id": 61003
}

id is the new maintenance ID. rec is the complete recurrence row as read immediately after the generic recurrence insert; the example shows its key fields.

The returned rec snapshot is stale by design: the wrapper activates and retargets the stored recurrence afterward, but does not reread it before responding.

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: asset_id"}asset_id is absent or not positive.
{"error":"invalid or missing parameter: next_date"}next_date does not match the accepted datetime pattern.
{"error":"missing parameter: recur_amt"}The frequency amount key is absent.
{"error":"missing parameter: recur_period"}The frequency-unit key is absent.
{"error":"missing or invalid parameter: form_id"}form_id is absent or not positive.
{"error":"name parameter too long. ..."}The description exceeds 236 characters.
{"error":"failed to create new job"}The final job helper returns no ID, including for a nonexistent asset or invalid first-job input.

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

Behaviour and edge cases

  • The Asset feature flag used by CRM1/CRM2 navigation is not enforced by the endpoint.
  • The stored recurrence is activated, asset-scoped, and given the requested amount/unit after its initial generic creation. The first job is linked back through recurrence metadata.
  • The recurrence-days tenant setting controls how far ahead the scheduler prepares jobs. Normal job-reference and notification settings also apply to the first job.

Side effects

  • Creates a maintenance row, tenant recurrence row, global scheduler row, and first job; updates their links; invalidates relevant job/maintenance caches; and performs normal job-create logging, events, asset-job updates, and notification-service calls.
  • An expiry date can add a scheduled expiry-notification task. No dedicated maintenance audit entry is written.

See it in Fieldmotion

CRM1

Open Assets → Maintenance, click Create, complete the dialog, and inspect AssetMaintenance_create. CRM1 derives meeting_time_e in the browser and obtains a suggested job reference first.

CRM2

The Maintenance page is feature-gated by Assets, but current CRM2 creates an asset-scoped job recurrence through its generic recurrence/job editor rather than calling this endpoint.

Related endpoints