When to use this endpoint

Use for quote-level exports. fields controls response columns, while the first phase chooses IDs using its own filter vocabulary.

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.
marketingSource / metaEmailSentNative integer listsNo; selection onlyNonempty arrays add integer IN filters; malformed entries return an invalid-list error naming the field. A one-choice 0 email filter is exact zero and does not include missing metadata like the mapped table does.
metaTagsString patternNo; selection onlyCase-folded contains on meta.tags; interpolation is not safely bound in this legacy branch.
referenceDateField / dateFromFilter / dateToFilter / isDateUnixDate alias, relative day offsets and flagNo; selection onlyAllowed cdate/last_edited/won_date and inclusive relative day bounds. Quote date columns are not Unix timestamps; nonzero isDateUnix is rejected.

Example request

$selection = json_decode(FM_api('Quotes_getExportData', ['_ids'=>'1','status'=>'999']), true);
$rows = FM_api('Quotes_getExportData', [
	'_ids'=>json_encode($selection['ids']),
	'fields'=>json_encode(['id','quote_num','total_gross']),
]);

Example response

[{"quote_id":"1042","f0":"1042","f1":"QT-1042","f2":"120.00"}]

Selection example: {"ids":[1042,1088]}. Check selection errors and skip fetch when ids is empty; an encoded empty list is an error. The Getting Started FM_api helper returns raw JSON text, so decode the selection before reading its ids.

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":"invalid referenceDateField: \"example\""}Relative-date filter uses an unsupported field name.
{"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

  • Requires Quotes View and the Export permission; both selection and fetch enforce active quote/customer visibility. _ids and fields must be encoded nonempty lists in fetch mode; malformed structures fail before SQL.
  • Selection _ids=1 returns integer IDs using numeric-coerced quote reference ordering. Fetch still uses f0/f1/etc positions and quote_id, ignores selection filters and does not preserve caller ordering. Callers chunk requests; there is no server snapshot.
  • Date bounds and supported relative-date aliases are validated. Quote date fields reject isDateUnix rather than applying Unix conversion to stored date columns. Tags filters are safely escaped, actual tag newlines flatten to commas, and sale-chance date is unquoted before date formatting.
  • profit_margin uses profit divided by adjusted net (total_gross minus total_tax), consistent with discounts and markup; a zero denominator yields null. profit_pc remains profit/cost*100.
  • quote_costs remains encoded JSON with current Stock/SoR names. rows_names and rows_codes are supported derived aliases. Form answer selections keep FORM_ID:FIELD_KEY position mapping and omit absent answers.
  • The legacy appointment_id export field still selects the newest active linked Job. invoice_id is reached through that Job; these are not all-links exports. No write, recalculation or email.
  • 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 → Export uses Quotes_getExportData through widgetExport; inspect the initial ID request followed by encoded _ids/fields batches.

CRM2

Quotes → Export first asks Quotes_getDataTable for filtered IDs, then widgetExportCRM2 sends explicit ID batches to Quotes_getExportData. Its initial selection phase can therefore differ from the table filters.

Related endpoints