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

ParameterTypeRequiredDescription
startInteger stringYesZero-based page offset. Presence is required; the value is converted to an integer.
cidInteger stringNoAsset ID; defaults to 0. The handler does not validate the asset row.
lengthInteger stringNoPage size; defaults to 1. An explicit zero remains zero.
drawInteger stringNoDataTables token returned as an integer; defaults to 0.
search[value]StringNoTrimmed contract search. A numeric value matches exact contract ID or a name substring; other values match name only.
activeInteger stringNoExact numeric active/completed flag.
nameStringNoAdditional contract-name substring filter. A present blank value is harmless.
notesStringNoAdditional notes substring filter.
order[0][column]Integer stringNo0 ID, 1 name, 9 created date, 10 expiry date, or 11 active flag; other values fall back to name.
order[0][dir]StringNoExact desc selects descending; every other value selects ascending.
dateFrom / dateToStringNoAccepted 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

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: 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.customers cache. 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_id matches. 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