When to use this endpoint

Use when reproducing CRM1’s legacy table request. The positional rows and sort indexes differ; use Quotes_getDataTable for CRM2 objects.

Authentication and permissions

Authenticate with signed API-key fields or a CRM session. Requires Quotes View (pageQuotes_view); non-admin users blocked by legacy crm_access bit 32 are denied. Client administrators inherit page permissions.

Quote visibility follows the account’s department/account-manager customer filters for non-admin users, including signed keys. Export routes additionally require pageMain_exportTableData. Linked Jobs require Jobs View and their TeamAccess scope; invoice enrichment requires Invoices View and the legacy invoice access check.

Parameters

ParameterTypeRequiredDescription
startInteger-compatible offsetYesZero-based offset. No nonnegative bound is enforced.
lengthInteger-compatible page sizeNoDefaults to 0, returning no data rows while still calculating totals/counts. No cap or all-rows sentinel is implemented.
drawInteger-compatible tokenNoDefaults to 0 and is echoed as an integer.
orderNative or JSON-encoded arrayNoNative/encoded first {column,dir}, with validated asc/desc. Uses the visible CRM1 sort indexes documented below.
searchString or native {value:string}NoDefaults to blank; trims global search over notes, quote_num and active customer name. JSON object strings are treated as literal text, not decoded.
dateFrom / dateToDate textTogetherBoth must be present. Inclusive cdate lower bound and dateTo + 23:59:59 upper bound; pass YYYY-MM-DD. Content is not calendar-validated.
statusInteger-compatible statusNoValues integer-converting to at least -1 filter exactly; 999 means no filter. Other positive unknown statuses are not rejected.
user_id / form_id / quote_id / contract_id / customer_idInteger-compatible IDsNoNonzero exact filters; quote_id means primary ID here.
quote_num / notesString patternsNoTruthy values add contains-style SQL LIKE filters; wildcard characters keep LIKE semantics.
customer_nameStringNoName/parent-name helper matches customer names and their immediate children. Its query does not filter deleted customers.
job_idInteger-compatible IDNoNonzero restricts by quote relation type 2. No Job existence/scope filter.
tagsStringNoCase-folded substring search across the entire meta text, not just the tags path.

Example request

$table = FM_api('Quotes_getDT', [
	'start'=>'0','length'=>'20','draw'=>'1',
	'order'=>[['column'=>0,'dir'=>'desc']],
	'status'=>'999',
]);

Example response

{"draw":1,"recordsTotal":"0","totals":{"total_cost":null,"total_net":null,"total_tax":null,"ids":"0","total_gross":null,"total_profit":null},"recordsFiltered":"0","data":[]}

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 absent/null.
{"error":"invalid parameter: order"}Malformed first order item or unsupported direction.
{"error":"invalid parameter: search"}Non-string value in the search object.
{"error":"permission denied"}Required Quotes/Export permission is absent or legacy access restrictions apply.

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

Behaviour and edge cases

  • Returns the legacy 26-position rows and filtered totals/counts; database IDs/money/counts remain strings and derived Job IDs/counts are integers. Both total and filtered counts respect customer visibility.
  • start and length must be nonnegative; omitted length retains the legacy zero-row page. Sorting follows CRM1 visible columns: 0 creation date, 1 reference, 2 Form, 3 customer, 4 notes, 5 user, 6 cost, 7 net, 8 discount, 9 tax, 10 gross, 11 profit, 12 profit/cost percentage, 14 sale chance, 15 status, 18 contract and 19 marketing source. Other indexes fall back to creation date; ID is a tie-breaker.
  • Each data item has 26 positions: 0: [id,cdate]; 1: quote_num; 2: form_id; 3: customer_id; 4: notes; 5: user_id; 6: cost; 7: total_net; 8: discount_rate; 9: total_tax; 10: total_gross; 11: profit; 12: constant 0; 13: [empty text,email_sent,mail rows or false]; 14: sale_chance; 15: status; 16: Job ID integers; 17: [contract_id,contract name]; 18: requisition/purchase order objects; 19: file count integer; 20: invoice objects; 21: tags; 22: signature request objects; 23: sale_chance_date; 24: won_date or empty text; 25: marketing_source or 0. Ordinary IDs/money are database strings, while derived Job IDs/file counts are integers.
  • Preserves the positional response map described below; visible sort columns and payload indexes differ for later relation/action cells. Job IDs are computed from current distinct active permitted type-2 relations, independent of cached has_jobs.
  • Orders exclude deleted targets; invoice enrichment includes all active direct invoices and active linked Job invoices, is deduplicated into a list and requires invoice access. File counts exclude deleted files. Signature history still includes expired requests as history.
  • Existing date, text, status and relation filters retain their documented legacy shapes. No primary quote or derived-cache write is performed by this list read.
  • No direct caller for this endpoint was found in the mobile app or its m-service intermediary.

Side effects

  • Reads active permitted records without quote cost, history, email or derived Job-cache writes.

See it in Fieldmotion

CRM1

Quotes → change filters or paging. pageQuotes sends Quotes_getDT with DataTables start/length/order/search and separate filter values.

CRM2

No direct caller found. CRM2 uses Quotes_getDataTable, including the Kanban view.

Related endpoints