When to use this endpoint

Use Assets_getDT only when reproducing the legacy CRM1 Assets table contract. New named-field clients should use Assets_getDataTable.

Authentication and permissions

The request must authenticate with signed API-key fields or a logged-in CRM session. The handler requires login or an established tenant database context and performs no additional Asset-page or role-permission check unless the page says otherwise.

Every query and write uses the authenticated tenant’s tables. CRM1 and CRM2 may hide actions through client-side permissions that these collection routes do not repeat.

Parameters

ParameterTypeRequiredDescription
lengthInteger-compatibleYesPage size. No minimum or maximum is enforced.
archivedInteger-compatibleYes0 live, 1 archived, and values 2 or greater omit the archive filter.
start / drawInteger-compatibleNoOffset (default 0) and echoed DataTables counter.
filter / daysFrom / daysToIntegersNoPreset filters: 1 warranty date, 2 next direct job, 3 last maintenance, 4 last completed visit, 5 owner not set, 6 whereabouts not set. Presets 1–4 require both relative day offsets.
search[value] / search[fields]String / JSON array stringNoSearch selected keys from book_id, asset_name, type, asset_value, meta, make, model, serial_number, warranty, and owner; all selects every key. Invalid field JSON returns a bare empty array.
book_id / serial_number / nameStringNoCase-insensitive substring filters.
type_id / assetid / owner_idInteger-compatibleNoExact ID filters.
warrantyInteger-compatibleNo1 after today; 2 today or earlier.
location_id / location_typeIntegersNoExact whereabouts pair; applied only when location ID is positive and the type key exists.
order[0][column] / order[0][dir]Integer / stringNoLegacy column order. Columns 8, 9, and 10 are derived and force all filtered rows to be loaded, sorted in PHP, then sliced.

Example request

$page = FM_api('Assets_getDT', [
	'archived' => '0',
	'draw' => '1',
	'start' => '0',
	'length' => '20',
]);

Example response

{
  "draw": 1,
  "recordsTotal": "240",
  "recordsFiltered": "180",
  "data": [
    [["4821", "BK-004"], "CMP-004", "Compressor 4", "2500.00", "[\"17\",\"Compressor\"]", ["1", "1042"], "1042", ["2026-09-20", "Annual service"], "2027-01-01", 3, [], "7712", "2026-09-20 09:00:00", ""]
  ]
}

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: length"}length is absent.
{"error":"missing or invalid parameter: archived"}archived is absent.
{"error":"missing or invalid parameter: daysFrom"}A day-range preset lacks its lower offset.

Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.

Behaviour and edge cases

  • recordsTotal counts every non-deleted asset regardless of the requested archive state; recordsFiltered applies the filters.
  • Each positional row contains identity, code/name/value, a JSON-encoded type tuple, whereabouts tuple, owner, maintenance tuple, warranty, department, incomplete direct jobs, last-visited job ID/time, and a trailing blank value.
  • Derived sorting can be expensive because it removes SQL pagination and performs per-asset maintenance and last-visit lookups.

See it in Fieldmotion

CRM1

Open Assets, page, search, sort, or apply warranty/maintenance/owner/whereabouts filters. The screen reads this positional contract.

CRM2

No production CRM2 caller was found; CRM2 uses Assets_getDataTable.

Related endpoints