When to use this endpoint

Use ScheduleOfRates_get when a legacy CRM1 workflow needs the raw row plus derived stock/labour costs. For batch lookup, use SchedulesOfRates_getById.

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
idInteger stringYesPositive tenant-local rate ID.

Example request

$rate = FM_api('ScheduleOfRates_get', [
	'id' => '430001',
]);

Example response

{
  "id": "430001",
  "name": "Annual service",
  "code": "AS-01",
  "stock_used": "[[74,1]]",
  "cost": "150",
  "last_edited": "2026-09-27 14:30:00",
  "description": "Annual preventative service",
  "meta": "{\"customerCosts\":{\"1042\":145}}",
  "asset_types": "[]",
  "labour_used": "[{\"user_id\":18,\"hours\":2,\"cost\":50}]",
  "price_bands": null,
  "archived": "0",
  "customer_costs": {"1042":145},
  "tax_rate": 0,
  "stock_cost": 12.5,
  "labour_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.
{"error":"missing or invalid parameter: id"}The ID is absent or not positive.
{"error":"schedule of rates does not exist"}No row has that ID.

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

Behaviour and edge cases

  • All stored columns are returned. Database scalars normally remain strings; JSON columns/text are not decoded except the derived customer_costs value.
  • stock_cost sums each stored quantity against the stock row’s current average_cost. Missing stock and nonpositive average costs contribute zero; deleted stock is not explicitly excluded.
  • labour_cost sums the stored cost from newer labour objects. Legacy [user_id,hours] rows with positive hours have no stored cost and therefore contribute zero because the fallback condition is inverted.
  • tax_rate reads only legacy meta.tax. Rates written by ScheduleOfRates_setTax use meta.tax_rate, so this derived field commonly remains 0 even though raw metadata contains tax.
  • Archived rows are returned. There is no pagination.
  • 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

The Quote Costs widget calls this route when expanding a selected rate.

CRM2

No direct CRM2 call was found; CRM2 uses mapped details or the batch endpoint. The mobile app also has no direct call to this CRM API.

Related endpoints