Assets
Create mapped asset data
/a/Asset_createData
Create one asset through the named field-map contract used by configurable CRM2 layouts.
When to use this endpoint
Use Asset_createData with CRM2 layout field names such as typeID and owner. For CRM1-style fields such as type_id, use Asset_new.
This route also converts the contacts and service-frequency widgets before insert and fires asset creation notifications afterward.
Authentication and permissions
The request must authenticate with signed API-key fields or a logged-in CRM session. The handler performs no additional page or role-permission check.
The lookup and any write use the authenticated tenant; an ID from another tenant cannot be addressed through this call.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
name | String | Yes | Required asset name. The uniqueness precheck uses the trimmed value, but the mapped insert stores the supplied value. |
typeID | Integer string | Yes | Mapped asset-type ID. It is required but existence is not checked by this endpoint. |
code / bookID | Strings | No | Serial number and book ID. Tenant uniqueness settings apply to active rows. Legacy book_id is considered by the uniqueness precheck but is not a mapped insert field; use bookID to store the value. |
active / archived | Integer strings | No | Status flags converted to integers. Neither value triggers archive/deletion-log side effects during creation. |
value | Decimal string | No | Mapped numeric asset value. |
location | Object | No | Current whereabouts as {"id": targetId, "type": 0|1|2|3}. It is split into locationID/locationType; target existence and circularity are not validated. |
locationID / locationType | Integer strings | No | Direct mapped alternatives to location. |
owner / ownerID | Object or integer string | No | owner is a picker object with id; ownerID is the underlying customer ID. The customer is not validated. |
departments | String | No | Stored in the asset departments column; this is distinct from CRM1’s singular department_id. |
warranty | Date string | No | Exact valid YYYY-MM-DD or blank. Unlike Asset_new, spreadsheet serials are not converted. |
make / model / customQR | Strings | No | Mapped identity fields. |
contacts / widgetTableContact | JSON/array | No | The widget form is converted from CRM2 contact keys to storage keys and replaces contacts when conversion returns data. |
widgetAssetServiceFrequency | Object | No | Copied to metaServiceFrequency when non-empty. |
registrationNumber / url | Strings | No | Stored under metadata as vehicle_reg and url. |
homeLocation | Object | No | Picker object {"id": value, "type": value}, split into metadata-backed homeLocationID/homeLocationType. No target resolution or validation occurs in this mapped route. |
metaServiceFrequency / metaLastVisited / metaLastServiced / metaNextDate / metaNextServiced / metaIsFlagged / metaCreditTerms / metaSkills | Mapped metadata values | No | Stored in the corresponding meta |
customValues / customMainValues | JSON-compatible values | No | Stored as complete meta.custom and meta.custom_main values. This route does not translate custom display labels to canonical field IDs. |
meta / files / jobDetails / locID / editedUuid / lastEdited / cdate / appID | Mapped scalar or JSON values | No | Low-level mapped fields accepted by the generic helper. Omitted cdate defaults to now and omitted lastEdited is set automatically. Prefer higher-level fields unless reproducing CRM2 layout behavior. |
Example request
$created = FM_api('Asset_createData', [
'name' => 'Compressor 4',
'typeID' => '47',
'code' => 'CMP-004',
'bookID' => 'BOOK-2048',
'owner' => ['id' => '1042'],
'location' => ['type' => '1', 'id' => '1042'],
'widgetAssetServiceFrequency' => ['frequency' => 2, 'every' => 6],
]);
Example response
{
"ok": 1,
"id": 4821
}
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: name"} | name is absent or serializes as an empty required quoted value. |
{"error":"missing or invalid parameter: typeID"} | typeID is absent. |
{"error":"invalid date parameter: warranty"} | A supplied warranty is neither blank nor a real YYYY-MM-DD date. |
{"error":"An asset of that name already exists"} | asset-unique-name is enabled and a non-deleted trimmed-name match exists. Equivalent errors apply to asset-unique-code and asset-unique-book_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
- Unknown request keys are ignored. The map’s layout
readonlyandhiddenflags do not prevent API writes. - Name, code, and book-ID uniqueness is controlled by
asset-unique-name,asset-unique-code, andasset-unique-book_id. Soft-deleted rows do not block reuse; archived rows do. - The endpoint does not validate referenced asset types, owners, whereabouts targets, departments, or files. It also does not apply the circular-whereabouts guard.
- This is a single insert with no filtering or pagination.
Side effects
- Inserts the asset, sets
last_edited, invalidates the asset cache, and writes generic audit entries for mapped fields. - After a successful insert, sends the asset
create2andtime2notification-service events. Tenant notification rules can perform further external actions; insert, audits, and notifications are not one transaction.
See it in Fieldmotion
CRM1
No direct production CRM1 caller was found; CRM1 uses Asset_new.
CRM2
The shared Asset layout map registers Asset_createData as its create route. Create an asset through a configurable CRM2 Assets layout and inspect the save request.
Related endpoints
Asset_getLayoutDetailsis the matching configurable-layout read.Asset_updateDatais the matching mapped update.Asset_newis the stricter CRM1 creation route and creates initial movement history.