Schedule of Rates
Retrieve Schedule of Rates rows by ID
/a/SchedulesOfRates_getById
Retrieve selected stored fields for several Schedule of Rates IDs and append legacy derived totals.
When to use this endpoint
Use SchedulesOfRates_getById for batch detail lookup in CRM1/CRM2 models and bill-of-materials expansion. Note the legacy extra s in the function namespace.
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 |
|---|---|---|---|
ids | Native array or JSON array string | Yes | IDs are integer-converted and deduplicated in first-seen order before the SQL query. Zero is retained. Invalid JSON/non-array values can produce a runtime error before the explicit empty-list check. |
fields | JSON array string | No | Allowed stored columns: id, name, code, stock_used, cost, last_edited, description, meta, asset_types, labour_used, and price_bands. Unknown names and duplicates are ignored. A native array is not accepted here. Omission selects all. |
Example request
$rates = FM_api('SchedulesOfRates_getById', [
'ids' => json_encode([430001, 430002]),
'fields' => json_encode(['id', 'name', 'cost', 'stock_used', 'labour_used', 'meta']),
]);
Example response
[
{
"id": "430001",
"name": "Annual service",
"cost": "150",
"stock_used": "[[74,1]]",
"labour_used": "[{\"user_id\":18,\"hours\":2,\"cost\":50}]",
"meta": "{}",
"tax_rate": 0,
"stock_cost": 12.5,
"labour_cost": 50,
"labour_hours": 2
}
]
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. |
{"error":"missing or invalid parameter: ids"} | ids is absent. |
{"error":"no ids in list"} | The decoded ID array is empty. |
{"error":"no fields selected"} | A supplied field list contains no allowed names. |
Runtime type error | ids does not resolve to an array, or fields is a native array/non-JSON scalar. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- Missing IDs are silently omitted and result order is not guaranteed to match input order. Archived rows are included.
- Derived
tax_rate,stock_cost,labour_cost, andlabour_hoursare appended even when their source columns were not requested; absent sources therefore yield zeros. stock_costuses current stock average costs.labour_costuses stored object costs; legacy positive-hour pairs contribute zero because the hourly-rate fallback condition is inverted. The labour helper is called twice per row.tax_ratereads legacymeta.tax, not modernmeta.tax_rate.customer_costsis appended only when selectedmetacontainscustomerCosts.- Stored JSON/text fields remain encoded.
See it in Fieldmotion
CRM1
The Job Bill of Materials widget and shared Schedule of Rates model batch selected IDs through this route.
CRM2
The Job Bill of Materials widget and shared ScheduleOfRates model use this route. The mobile app has no direct call to it.
Related endpoints
ScheduleOfRates_getreturns one full row with similar derived values.ScheduleOfRate_getRequestedDetailsis the newer mapped batch reader without derived totals.