When to use this endpoint

Use ScheduleOfRate_getRequestedDetails for CRM2 selectors and job/financial widgets that need named fields. Use ScheduleOfRates_getDataTable for table counts and paging.

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
fieldsNative arrayNoMapped names to return. Omission selects all keys; unknown names are ignored; id is always added. Valid stored names are name, code, stockUsed, cost, lastEdited, description, meta, metaNominal, metaNominalID, metaNominalCode, metaTaxTypeID, assetTypes, labourUsed, priceBands, archived, and metaCustomerCosts; taxType returns a composite picker object. JSON array text is not decoded.
id / idsInteger string or native arrayNoOptional ID restriction; id takes precedence. Members are integer-converted. A present empty array adds no filter and can return every row.
Mapped field filtersScalar or native arrayNoExact filters using map names. Text values are trimmed and case-folded; numeric values use integer equality (including cost, which is incorrectly treated as an integer by this generic filter path).
orderMapped name or native arrayNoMapped sort key(s), optionally objects such as {"id":"name","dir":"desc"}. Exact desc reverses a key.
advanceSearchNative arrayNoShared CRM2 advanced-search conditions over mapped fields.

Example request

$rates = FM_api('ScheduleOfRate_getRequestedDetails', [
	'ids' => ['430001', '430002'],
	'fields' => ['id', 'name', 'code', 'cost', 'stockUsed', 'labourUsed'],
	'order' => [['id' => 'name', 'dir' => 'asc']],
]);

Example response

[
  {
    "id": "430001",
    "name": "Annual service",
    "code": "AS-01",
    "cost": "150",
    "stockUsed": "[[74,1]]",
    "labourUsed": "[{\"user_id\":18,\"hours\":2,\"cost\":50}]"
  }
]

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.
[]No row matches. Missing IDs are silently omitted.
Runtime warning or type errorA list-shaped parameter is supplied in an unsupported scalar form.

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 table has an archived flag but no deleted flag; archived rows are included unless filtered.
  • JSON stored in stockUsed, labourUsed, assetTypes, priceBands, or raw meta remains encoded. Nested metadata keys and taxType are expanded from meta.
  • No default ordering is applied. There is no pagination or count wrapper.
  • These endpoints store the base price in cost; they do not calculate a customer’s final price. Job/quote consumers can apply meta.customerCosts, the tenant setting sor-child-gets-parent-price, and the customer’s price band later.

See it in Fieldmotion

CRM1

No direct CRM1 browser caller was found; CRM1 uses the legacy list/detail routes.

CRM2

The Schedule of Rates page uses this route for archive checks and selection, while job tables, financial modules, history, and reports request selected rate fields through it.

Related endpoints