When to use this endpoint

Use for CRM2’s quote line-item CSV export. These calculations are separate from Quote_calculateCost and can disagree with saved totals.

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
_idsString: 1 or JSON-encoded ID arrayYesLiteral 1 starts selection and returns integer IDs. Otherwise submit a nonempty encoded ID array to fetch rows; entries integer-convert. An empty list fails. No server checkpoint is stored.
fieldsJSON-encoded ordered array of field namesFetch phaseRequested positions become f0, f1, etc. Unknown names fail. Native fields arrays are not JSON-decoded by these exporters.
from / toDate stringsNo; selection onlyIndependent inclusive cdate bounds; to appends 23:59:59. No calendar validation.
quote_id / quote_numString patternsNo; selection onlyContains-style ID/reference LIKE matches, not exact quote_id equality. Wildcards retain SQL LIKE meaning.
form_id / contract_id / user_idInteger-compatible IDsNo; selection onlyTruthy exact filters after conversion.
customer / notes / searchString patternsNo; selection onlyCustomer/name, quote notes, and global ID/reference/customer search respectively; individual exporter differences are described below.
statusInteger-compatible value or 999No; selection onlyOmitted/blank or 999 means all statuses. Otherwise filters by integer status; no enum allowlist.

Example request

$rows = FM_api('Quotes_getLineItemsExportData', [
	'_ids'=>json_encode(['1042']),
	'fields'=>json_encode(['quote_num','quote_costs']),
]);

Example response

[{"quote_id":"1042","f0":"QT-1042","f1":"{\"description\":\"Call-out\",\"qty\":2,\"cost\":5,\"price\":10,\"summary\":\"Other\",\"amt\":2,\"gross\":10,\"cost_total\":10,\"price_total\":20,\"gross_total\":20}","lineitem":"{\"description\":\"Call-out\",\"qty\":2,\"cost\":5,\"price\":10,\"summary\":\"Other\",\"amt\":2,\"gross\":10,\"cost_total\":10,\"price_total\":20,\"gross_total\":20}"}]

lineitem and its selected fN are encoded JSON strings. Optional keys and key order come from stored rows; the sample shows a quantity-two, zero-VAT Other row.

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: _ids"}_ids omitted/null.
{"error":"_ids should be a JSON array of numbers"}Fetch selector is empty, invalid JSON or not an array.
{"error":"fields should be an array of requested field names"}Missing/empty/invalid encoded fields.
{"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

  • Shares the exact row exporter and response with Quotes_getLineItemExportData; the plural route remains the CRM2 caller’s name. Both phases exclude deleted/invisible quotes and require Export.
  • Uses the authoritative Quote row calculation, including selected Tax categories, fractional quantities/rates, row/header discount or markup, SoR combined cost, Labour priceph and Verbose net_price/amount. Export sums agree with calculated quote gross/profit.
  • Stock uses amt with qty fallback; Other preserves qty/amt fallback. Zero quantities are valid and do not divide by zero. Invalid/oversized rows return a structured error.
  • Returns one row per cost item with repeated header fN values and an encoded lineitem; selected quote_costs positions contain that same encoded string. Empty costs produces no lines. No record write or cache repair.
  • 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

No direct caller found. CRM1 uses the singular Quotes_getLineItemExportData.

CRM2

Quotes → Export Line Items selects matching IDs via Quotes_getDataTable, then invokes Quotes_getLineItemsExportData through widgetExportCRM2.

Related endpoints