When to use this endpoint

Use ScheduleOfRates_getExportData with the CRM export widgets. The first request can discover IDs; subsequent requests return field aliases expected by the CSV mapper.

Authentication and permissions

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

All reads and writes use the authenticated tenant. The CRM screens apply client-side Schedule of Rates permissions, but those controls are not repeated by this endpoint.

Parameters

ParameterTypeRequiredDescription
_idsStringYesExact 1 starts ID discovery. Otherwise it must be a nonempty JSON array of IDs for data retrieval.
name / code / description / searchStringDiscovery onlyCase-sensitive/insensitive substring behavior follows the tenant collation. search ORs name, code, and description; the named filters are AND-combined.
assetTypesNative arrayDiscovery onlyBuilds SQL asset_types IN (...) against the complete stored text. Because normal values are JSON arrays, individual asset-type IDs generally do not match.
archivedNative arrayDiscovery onlyAllowed exact archive flags for SQL IN.
sorIDInteger stringDiscovery onlyNonzero exact ID filter.
fieldsJSON arrayData retrieval onlyOrdered field names. Allowed: id, name, code, stock_used, cost, price (alias of cost), price_bands, last_edited, description, asset_types, labour_used, nominal, tax_rate, tax_type, and customerCosts.

Example request

$selection = FM_api('ScheduleOfRates_getExportData', [
	'_ids' => '1',
	'archived' => [0],
	'search' => 'annual',
]);

$rows = FM_api('ScheduleOfRates_getExportData', [
	'_ids' => json_encode($selection['ids']),
	'fields' => json_encode(['id', 'name', 'cost', 'nominal', 'customerCosts']),
]);

Example response

[
  {
    "f0": "430001",
    "f1": "Annual service",
    "f2": "150",
    "f3": "4000",
    "f4": ["Northwind Service Centre - 145"]
  }
]

Discovery instead returns {"ids":[430001,...]}, ordered by name. Data keys are positional f0, f1, and so on according to the requested field order; rows have no guaranteed order.

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"}_ids is absent or blank.
{"error":"_ids should be a JSON array of numbers"}The data-stage value is invalid JSON, empty, or not an array.
{"error":"fields should be an array of requested field names"}fields is absent, invalid JSON, empty, or not an array.
{"error":"unknown field name: FIELD"}A requested field is not allowlisted.

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

Behaviour and edge cases

  • ID discovery is unpaged and includes archived rows unless archived is supplied.
  • IDs are integer-converted and falsey values are removed. Missing IDs are silently omitted.
  • nominal prefers meta.nominal_code, then legacy meta.nominal. Tax fields read meta.tax_rate/meta.tax_type.
  • customerCosts becomes an array of customer name - rate lines. Missing customers produce a blank name. Customer lookup is cached only within this request.
  • If the same derived metadata field is requested more than once, only its last positional alias is flattened; earlier duplicates can expose the raw metadata string.

See it in Fieldmotion

CRM1

The Schedule of Rates Export action uses this endpoint for ID discovery and mapped CSV batches.

CRM2

The CRM2 export first obtains filtered IDs through ScheduleOfRates_getDataTable, then passes those IDs to this endpoint’s data stage.

Related endpoints