When to use this endpoint

Use this only for the legacy DataTables invoice grid. Its rows are positional arrays tailored to CRM1 rather than stable named objects.

Authentication and permissions

The request must use a logged-in CRM session or valid signed API credentials and is scoped to that tenant.

Users whose legacy crm_access mask contains bit 64 receive {"error":"no permission to access api"}. No record-owner check is made.

Parameters

ParameterTypeRequiredDescription
startNonnegative integerYesZero-based SQL offset.
lengthIntegerYesPage length passed to SQL.
drawIntegerNoDataTables draw token echoed in the response.
order[0][column] / order[0][dir]Integer / asc|descNoLegacy column index and direction. Unsupported indexes fall back to invoice number.
search[value]StringNoSubstring across ID, number, customer/asset name, and formatted total/net/owing values.
dateFrom / dateToDate stringsNoInclusive invoice-date range; dateTo is read whenever dateFrom is present.
invoice_id, form_id, statusInteger-compatibleNoExact filters.
invoice_no, customer, nominal, order_noStringNoInvoice-number, customer/asset, nominal-code, and order-number filters. A numeric N-M invoice number becomes an inclusive lexical range.
due_dateNumeric day offsetNoMatches the calendar day at today minus this many days.
overdue0 or 1NoWhen 1, keeps status-1 invoices due before yesterday.
recurringall, 0, or 1NoAll, nonrecurring, or recurring invoices.

Example request

$table = FM_api('Invoices_getDT', [
	'draw' => 3, 'start' => 0, 'length' => 25,
	'order' => [['column' => 8, 'dir' => 'desc']],
]);

Example response

{
  "draw": 3,
  "recordsTotal": "148",
  "recordsFiltered": "25",
  "totals": {"total": "3000.00", "paid": "1200.00", "ids": "25"},
  "data": [[981, ["INV-981", null], 0, 7, "", [1, 0], "2026-10-02", [0, 55, 0, 0, 0, {}], "120.00", 120, 1790899200, 1]]
}

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 or negative.
{"error":"no permission to access api"}The legacy access bit is set.

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 invoice; recordsFiltered and totals reflect filters before pagination.
  • Rows contain invoice ID; number and metadata number; quote/form placeholders; direct and ancillary job-link counts; date; normalized customer/asset tuple with customer snapshot; gross, owing, due date, status, email/recurrence/nominal/tax/order/user/net/paid-date values; and QuickBooks/Xero IDs.
  • Invoices whose historical job target vanished are hidden only while unpaid, unpublished, and draft/unset.
  • Customer filtering is expanded by invoice-customer-filter-include-sites and invoice-customer-filter-includes-owned-and-located-assets. Credit allocations reduce owing when accounting_credit_notes=1. Missing customer snapshots may be refreshed and persisted while reading.

Side effects

  • May refresh and store an invoice’s customer-details snapshot.

See it in Fieldmotion

CRM1

The main invoice page calls this route.

CRM2

CRM2 uses Invoices_getDataTable instead.

Related endpoints