Assets
List asset contracts and costs
/a/Asset_contractsGetDT
Return contract, job, cost, invoice-value, and file summaries associated with an asset.
When to use this endpoint
Use Asset_contractsGetDT only for the legacy CRM1 asset Contracts table, whose UI understands this 23-position row.
For a simple CRM2 contract picker, Asset_getAllContracts returns just IDs and names.
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 |
|---|---|---|---|
start | Integer string | Yes | Zero-based page offset. Presence is required; the value is converted to an integer. |
cid | Integer string | No | Asset ID; defaults to 0. The handler does not validate the asset row. |
length | Integer string | No | Page size; defaults to 1. An explicit zero remains zero. |
draw | Integer string | No | DataTables token returned as an integer; defaults to 0. |
search[value] | String | No | Trimmed contract search. A numeric value matches exact contract ID or a name substring; other values match name only. |
active | Integer string | No | Exact numeric active/completed flag. |
name | String | No | Additional contract-name substring filter. A present blank value is harmless. |
notes | String | No | Additional notes substring filter. |
order[0][column] | Integer string | No | 0 ID, 1 name, 9 created date, 10 expiry date, or 11 active flag; other values fall back to name. |
order[0][dir] | String | No | Exact desc selects descending; every other value selects ascending. |
dateFrom / dateTo | String | No | Accepted from the CRM1 screen but ignored by this implementation. |
Example request
$page = FM_api('Asset_contractsGetDT', [
'cid' => '4821',
'draw' => '2',
'start' => '0',
'length' => '10',
'active' => '1',
'search' => ['value' => 'maintenance'],
]);
Example response
{
"draw": 2,
"recordsTotal": "48",
"recordsFiltered": "1",
"data": [
[901, "Annual maintenance", "C-901", 2, [[7719, "2026-09-24 09:00:00", "JOB-7719", 4]], "5000.00", "125.00", "18.00", ["40.00", 12.5, "5.00"], "Notes", [[37, "2.5"]], [[8, "24"]], [], "900.00", "1080.00", "180.00", "", "1", "2026-01-01 10:00:00", "2026-01-01", "2026-12-31", null, 2]
]
}
Rows are [id, name, number, typeId, jobs, budget, labourCost, mileageCost, [stockCost, currentSorCost, miscCost], notes, labour, vehicles, stockUsed, net, gross, tax, reserved, active, createdAt, started, expires, completed, fileCount].
Each job tuple is [jobId, localJobTime, jobRef, jobTypeId]; labour entries are [userId, hours]; vehicle entries are [vehicleId, distance].
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: start"} | start is absent. |
{"draw":0,"recordsTotal":"…","recordsFiltered":"0","data":[]} | No contract matches the legacy asset-link cache. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- Contract association is detected with a substring match against the legacy
contracts.customerscache. The endpoint does not use the current asset-to-contract link table and does not exclude deleted contracts. - Jobs in the row are non-deleted direct asset jobs whose
contract_idmatches. They are ordered by job time ascending. The supplied date parameters do not narrow them. - The aggregate job-cost query uses a separate legacy contract-link relation. Consequently the displayed job list and aggregate costs can cover different jobs.
- SOR cost is estimated from current stock average costs and current SOR labour definitions. Stock cost in an SOR is not multiplied by the job’s SOR quantity, while the labour helper does apply the stored SOR labour totals before the row quantity is added only for that labour path.
- File count includes non-deleted files whose type is Contract. The endpoint is read-only.
See it in Fieldmotion
CRM1
Open an asset’s Contracts tab and filter Network requests for Asset_contractsGetDT.
CRM2
No direct CRM2 table caller was found. CRM2 uses Asset_getAllContracts for an asset-module filter and separate contract APIs for details.
Related endpoints
Asset_getAllContractsreturns the lightweight CRM2 picker list.Asset_financialsGetDTreturns job-level financial rows without grouping them by contract.