Schedule of Rates
Retrieve mapped Schedule of Rates details
/a/ScheduleOfRate_getRequestedDetails
Retrieve selected mapped Schedule of Rates fields by ID or exact field filters without pagination.
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
| Parameter | Type | Required | Description |
|---|---|---|---|
fields | Native array | No | Mapped 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 / ids | Integer string or native array | No | Optional ID restriction; id takes precedence. Members are integer-converted. A present empty array adds no filter and can return every row. |
Mapped field filters | Scalar or native array | No | Exact 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). |
order | Mapped name or native array | No | Mapped sort key(s), optionally objects such as {"id":"name","dir":"desc"}. Exact desc reverses a key. |
advanceSearch | Native array | No | Shared 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
| Response | Condition |
|---|---|
{"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 error | A 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
archivedflag but no deleted flag; archived rows are included unless filtered. - JSON stored in
stockUsed,labourUsed,assetTypes,priceBands, or rawmetaremains encoded. Nested metadata keys andtaxTypeare expanded frommeta. - 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 applymeta.customerCosts, the tenant settingsor-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
ScheduleOfRates_getDataTableadds shared table filtering and counts.SchedulesOfRates_getByIdis the older batch detail contract with derived costs.