When to use this endpoint

Use this for the legacy recurrence editor. Creation copies the invoice’s customer target; editing preserves the recurrence’s existing customer target.

Authentication and permissions

The request must authenticate with signed API-key fields or a logged-in CRM session and is scoped to the authenticated tenant.

The handler performs no additional invoice page, record-owner, or department permission check unless stated below.

Parameters

ParameterTypeRequiredDescription
idPositive integerFor editingExisting recurrence ID. Takes precedence over invoice_id.
invoice_idPositive integerFor creationExisting invoice to attach and use as the recurrence source.
nameString, 1–255 bytes after trimmingYesRecurrence name. The stored value itself is not trimmed.
everyInteger 0–6YesSchedule kind: weekday, month days, year days, or day/week/month/year interval respectively.
onJSON valueYesFor kinds 0–2, normally a JSON array of numeric offsets; for 3–6, a positive numeric JSON scalar. A decoded string is split on commas.
expiryYYYY-MM-DDNoExpiry date stored as noon Unix time. Blank or 0000-00-00 stores zero.
activeInteger-compatibleNoActive flag; defaults to zero.
notesStringNoReplaces notes when present. Omission preserves notes on edit and leaves them unset on creation.
copy_itemsInteger-compatibleNoStored in recurrence metadata; defaults to zero.
job_recurrence_idInteger-compatibleNoLinks the invoice recurrence to a job recurrence; defaults to zero.

Example request

$result = FM_api('InvoiceRecurring_save', [
	'invoice_id' => '981',
	'name' => 'Monthly service invoice',
	'every' => '1',
	'on' => '[0]',
	'active' => '1',
]);

Example response

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

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: name"}Name is absent, blank after trimming, or longer than 255 bytes.
{"error":"missing or invalid parameter: every"}Schedule kind is absent or outside 0–6.
{"error":"missing or invalid parameter: on"}Schedule data is absent, blank, or contains a nonnumeric array item.
{"error":"invalid parameter: edate"}The nonblank expiry value is not in the required shape.
{"error":"invoice recurrence does not exist","errcode":1}Edit ID does not exist.
{"error":"invoice does not exist"}Creation invoice does not exist.
{"error":"no way to identify which recurrence to edit"}Neither a positive recurrence ID nor invoice ID is supplied.

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

Behaviour and edge cases

  • If the source invoice already has a recurrence, the endpoint returns {"ok":1,"warning":"recurrence not created - already existed","id":…} without applying the submitted recurrence fields.
  • Edits reset num_invoices to 1 and ndate to zero before recalculating it. Existing metadata keys other than the two controlled keys are preserved.
  • All array entries in on must be numeric, but range and combination validation is deferred to recalculation.

Side effects

  • Creates or updates the recurrence, attaches a newly created recurrence to the source invoice, synchronizes the reciprocal job-recurrence metadata link, and recalculates the next run.
  • Advances recurrence and invoice last_edited timestamps as applicable.

See it in Fieldmotion

CRM1

The invoice recurrence widget creates and edits definitions with this route.

CRM2

The recurrence editor currently loads/deletes records directly, while creation/editing is also available through the invoice module.

Related endpoints