Schedule of Rates
Set Schedule of Rates customer prices
/a/ScheduleOfRates_setCustomerCosts
Replace or merge per-customer Schedule of Rates price overrides in metadata.
When to use this endpoint
Use ScheduleOfRates_setCustomerCosts for customer-specific prices from CRM1 or CRM2. The stored values affect later Job/quote price selection; they do not change the base cost.
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 |
|---|---|---|---|
id | Integer string | Yes | Positive rate ID. |
vals | Native object/array | No | Customer-ID-to-price mapping. Values are floating-point converted and keys are retained by PHP/JSON rules. Omission means an empty array. JSON text is not decoded. |
merge | Integer string | No | Exact integer 1 updates/adds supplied keys while retaining existing meta.customerCosts; otherwise the complete mapping is replaced. |
Example request
FM_api('ScheduleOfRates_setCustomerCosts', [
'id' => '430001',
'vals' => [
'1042' => 145,
'1088' => 140,
],
]);
Example response
{
"ok": 1
}
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: id"} | The ID is absent or not positive. |
{"error":"schedule of rates does not exist"} | The ID has no row. |
Runtime type error | vals is a scalar/JSON string, or merge targets legacy customerCosts data that is not an array. |
{"ok":1,"msg":"no change needed"} | The newly encoded complete metadata exactly matches the stored metadata string. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- Other metadata keys are preserved. Invalid/blank existing metadata is treated as an empty object.
- With tenant setting
sor-child-gets-parent-price=1, server Job price calculation checks a direct parent’s override before the child’s own override. With the setting off, it checks the direct customer override. Price-band/base-price fallback follows afterward. - CRM callers may generate child customer entries themselves; this endpoint only stores the submitted mapping.
Side effects
- On change, advances
last_editedand thescheduleOfRatescache marker. - Fires the tenant-configurable
SOR_editevent with the rate ID. Any configured listeners run synchronously and can add integration-specific side effects.
See it in Fieldmotion
CRM1
The rate Prices dialog and Customer Schedule of Rates page replace mappings through this route.
CRM2
Customer-specific price tools use this route, sometimes with merge=1. The main Schedule of Rates editor uses mapped update instead.
Related endpoints
ScheduleOfRates_setCostchanges the base price.ScheduleOfRate_updateDatacan update or remove the mapped metadata key.