When to use this endpoint

Use the two-phase export contract: _ids=1 returns matching IDs, then _ids as JSON text plus fields as JSON text returns data. The endpoint returns JSON, not a CSV download; browser exporters resolve identities and format cells.

Authentication and permissions

Authenticate with signed API-key fields or a logged-in CRM session. All records resolve in the authenticated tenant. This handler has no additional Job edit-bit, department-visibility or owner check.

Parameters

ParameterTypeRequiredDescription
_idsStringYesLiteral 1 selects ID discovery. Otherwise a nonempty JSON array of recurrence IDs; values are intval-coerced. A native array is not decoded by this handler.
fieldsJSON stringData phaseNonempty array of allowed export field names below. Native arrays not supported. id always returned and field positions determine fN aliases.
customer_id, customer_typeInteger-like scalarsDiscovery onlyNonzero customer_id plus customer_type (default0) exact target; otherwise nonzero customer_type can filter all assets. No parent/subsidiary expansion.
expiryFrom, expiryTo, non_expiringDate strings, literal true stringDiscovery onlyexpiryFrom activates inclusive expiry range; expiryTo defaults to server today with 23:59:59 appended. non_expiring="true" also includes NULL or expiry containing 0000, not the special 2999 sentinel.
name, notesStringsDiscovery onlyScalar lowercase substring filters; quoted input is searched as data using SQL-mode-independent text literals.
recurringIDInteger-like scalarDiscovery onlyNonblank exact recurrence ID.
users, formIDs, department_idNative integer arraysDiscovery onlyNonempty lists produce exact IN conditions. Strict integer-token sanitization rejects invalid members; department_id here is an array, unlike the CRM1 table scalar.
referenceDateField, dateFromFilter, dateToFilter, isDateUnixString, integer offsets, flagDiscovery onlyBoth day offsets plus a nonblank reference field required. Allowed fields cdate, edate, last_edited; inclusive server-date day bounds. isDateUnix wraps the chosen column in FROM_UNIXTIME, even though these recurrence columns store SQL dates. Leave it off for normal rows.
contractsFilterNative integer arrayDiscovery onlyNative sanitized integer list of contract IDs. Non-deleted linked jobs are matched against complete cached CSV IDs; no jobs forces no matches.
withExpiryDate, isCompleted, isActiveNative single-element arraysDiscovery onlyExpiry presence: [1] NOT NULL, [0] NULL. Completion: [1] expiry on/before today, otherwise after today; NULL excluded. Active: [1] active=1, otherwise active=0. Other array sizes skip each filter.
jobTypeNative integer arrayDiscovery onlyNonempty job-type IDs match stored job-type metadata.
invoiceIDInteger-like scalarDiscovery onlyNonblank linked invoice recurrence ID.

Example request

$ids = FM_api('JobRecurrences_getExportData', ['_ids'=>'1', 'isActive'=>['1']]);
// Decode ids, then fetch a bounded batch:
$rows = FM_api('JobRecurrences_getExportData', ['_ids'=>'[1042]', 'fields'=>'["name","frequency","completed","customer_id|customer_type"]']);

Example response

[{"id":"1042","f0":"Monthly checks","f1":"every 2 weeks","f2":"does not expire","f3_0":"101","f3_1":"0","edate":null,"on_arr":"2","every":"4"}]

Discovery response is {"ids":["1042",...]} with no count or paging. Data response is a bare array and can append dependency columns edate, on_arr and every when requested computed fields need them.

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: _ids"}Missing/falsy selector, checked before login.
{"error":"_ids should be a JSON array of numbers"}Data selector decodes to empty/non-array/falsy value.
{"error":"fields should be an array of requested field names"}Fields decode to empty/non-array/falsy value.
{"error":"unknown field name: bad"}Unrecognized export field; name varies.
{"error":"invalid users"}A sanitized native integer list contains invalid members; label varies.
{"error":"invalid referenceDateField: bad"}Date reference not allowlisted; echoed value varies.
{"error":"error in database query"}Discovery or data-phase query failed; generated SQL is not returned.

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

Behaviour and edge cases

  • Allowed export fields: id, customer_id|customer_type, user_id, name, edate, notes, recurrences, frequency, files, customer_type, completed, active, department_id.
  • Every field gets fN in request order. customer_id|customer_type produces fN_0 and fN_1. Fields containing a colon are skipped but keep their original index gap. id is also always a separate output key.
  • recurrences is the cached job-ID CSV, not a count. Notes/files remain stored strings, not formatted export cells.
  • frequency: NULL mode=weekly; 0=daily, 1=monthly, 2=yearly, 3–6=every N days/weeks/months/years using intval(on_arr). These are labels, not a full explanation of selected calendar days.
  • completed is expiry-derived: null/blank/zero date means "does not expire"; expiry <= server today means "complete"; later means "completes on DATE". Discovery isCompleted now uses the same inclusive today boundary.
  • Discovery filters are ignored in the data phase. Explicit selected IDs are read directly without active/deleted, department/account-manager visibility or parent-scope filters. No pagination, maximum batch size or defined order.
  • Contract discovery matches complete positive CSV IDs, including leading zeroes/whitespace, and excludes deleted linked jobs. No jobs for the selected contracts means no results, including legacy NULL caches.
  • Name/notes filters treat quoted text as data, not SQL. Scalar/list controls and requested field names are validated; database-query errors do not expose generated SQL.

Side effects

  • Closes the session write lock; otherwise read-only. Does not create files, send messages, repair caches, reconcile dates or change scheduler registration.

See it in Fieldmotion

CRM1

Jobs → Recurring Jobs or a customer’s Recurring Jobs → Export. pageJobsRecurring/pageCustomerJobsRecurring configure widgetExport with this function; widgetExport performs the ID/field requests and builds CSV.

CRM2

Recurring Jobs → Export. moduleRecurring first uses the mapped table to discover visible IDs, then widgetExportCRM2 calls this endpoint for export data. The endpoint itself does not repeat the table’s visibility controls.

Related endpoints