Assets
Set an asset custom value
/a/Asset_setCustom
Set one custom metadata value on an asset and optionally append its legacy change history.
When to use this endpoint
Use Asset_setCustom for the inline custom fields on CRM1 asset screens and for compatible CRM2 shared custom-field widgets.
The endpoint merges one key into meta.custom. Use Asset_updateData only when replacing a complete customValues map is intended.
Authentication and permissions
The handler requires an authenticated tenant context, established by signed API-key fields or a CRM session. It checks the tenant prefix after validating parameters and performs no page, role, or asset permission check.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | Integer string | Yes | Positive asset ID. Existence and deleted state are not validated before the update attempt. |
name | String | Yes | Custom field key. A canonical layout ID remains unchanged; an unambiguous custom-layout display name is converted to its ID. Duplicate display names are deliberately not translated. |
val | Mixed | Yes | New value. Omission and null are rejected; blank, zero, strings, and arrays are accepted. It is JSON-encoded as part of the asset metadata. |
Example request
$result = FM_api('Asset_setCustom', [
'id' => '4821',
'name' => 'inspection_class',
'val' => 'A',
]);
Example response
{
"ok": 1,
"asset": {
"type_id": "47",
"meta": "{...}",
"location_type": "1",
"location_id": "1042",
"owner_id": "1042"
},
"asset_type": {"id": "47", "name": "Compressor", "meta": "{...}"},
"field": 0
}
asset is the selected pre-update subset, asset_type is the complete current type row, and field is the matching legacy template definition or numeric 0. An unchanged value returns only {"ok":1,"warning":"already has that value"}.
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"} | id is absent, zero, or otherwise not positive. |
{"error":"missing or invalid parameter: val"} | val is absent or null. |
{"error":"missing or invalid parameter: name"} | name is absent. A present blank name is accepted but removed from metadata before storage. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- No-change comparison uses PHP loose equality. It returns before changing timestamps or logs.
- Legacy change history is written only when the matching field in the asset type’s old template has
record_changes. The related customer ID is current whereabouts when type is customer, otherwise current owner. - For a recorded array value, the legacy history insert coerces the array to the string
Array, even though the asset metadata stores the actual JSON value. - After assignment, an empty custom-field key is removed. The route has no filtering or pagination.
Side effects
- Updates
meta.custom,last_edited, andedited_uuid="Asset_setCustom"; invalidates the asset cache; and writes one asset audit entry. - May insert an
asset_changesrow before attempting the asset update. There is no transaction and no notification-service event.
See it in Fieldmotion
CRM1
Edit a custom field on an asset details popup, asset details page, Assets list, or customer Assets tab and filter Network requests for Asset_setCustom.
CRM2
CRM2 shared custom-field and job auto-populate flows call this endpoint directly for individual values.
Related endpoints
Asset_changesGetDTreads recorded legacy changes.Asset_updateDatareplaces the complete mapped custom-values object.