When to use this endpoint

Use Opportunities_getExportData only through the CRM export widget, which manages the _ids sentinel/JSON batch contract and fN columns.

Authentication and permissions

The request must authenticate with signed API-key fields or a logged-in CRM session. The handler performs no additional page or role-permission check.

The lookup and any write use the authenticated tenant; an ID from another tenant cannot be addressed through this call.

Parameters

ParameterTypeRequiredDescription
_idsStringYesExact/loosely equal 1 starts ID discovery. Otherwise it must be a non-empty JSON array of IDs for row resolution.
from / toLocal date stringsPhase 1 only, optionalInclusive tenant-local calendar bounds on cdate, converted to epochs at 00:00:00/23:59:59.
searchStringPhase 1 only, optionalLegacy broad search. Any nonblank value currently generates malformed SQL; do not use until the implementation is corrected.
opportunityID / quoteID / value / notesScalarsPhase 1 only, optionalExact ID/quote/value filters or lowercase notes substring. Notes is interpolated without escaping. The quote filter is redundantly added twice.
isStarred / formIDList / customersList / usersList / status / sourceNative integer arraysPhase 1 only, optionalValidated integer IN filters. They are applied only for non-empty native arrays.
referenceDateField / dateFromFilter / dateToFilter / isDateUnixField / relative days / flagPhase 1 only, optionalWhen both day offsets and a nonblank field exist, filter cdate, last_edited, or legacy won_date. Set isDateUnix for epoch fields.
fieldsJSON array stringPhase 2Non-empty requested field list. Allowed stored names: cdate, customer_id, id, last_edited, marketing_source, notes, parent, quote_id, status, user_id, value, callback, callback_notes. Form values use <form-id>:<stored-field-key>.

Example request

// Phase 1
$ids = FM_api('Opportunities_getExportData', [
	'_ids' => '1',
	'from' => '2026-09-01',
	'to' => '2026-09-30',
]);

// Phase 2
$rows = FM_api('Opportunities_getExportData', [
	'_ids' => json_encode($ids['ids']),
	'fields' => json_encode(['id', 'status', '12:field-1', 'parent']),
]);

Example response

[
  {
    "opportunity_id": "481",
    "form_id": "12",
    "form_values": "{\"field-1\":\"Yes\"}",
    "subform_values": null,
    "f0": "481",
    "f1": "Draft",
    "f2": "Yes",
    "f3": "900",
    "customer_id": "1042"
  }
]

Phase 1 instead returns {"ids":[481,482]}. Phase 2 always includes the four helper columns shown; each requested field is returned as f0, f1, and so on. Requesting parent can also expose the helper customer_id.

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 is omitted.
{"error":"invalid <filter>"}A phase-1 integer-list filter contains a non-integer value.
{"error":"invalid referenceDateField"}The requested relative-date field is not in the three-name allowlist.
{"error":"_ids should be a JSON array of numbers"}Phase-2 _ids is malformed, empty, or not an array. Despite the wording, members are merely integer-converted.
{"error":"fields should be an array of requested field names"}fields is missing, malformed, empty, or not a JSON array.
{"error":"unknown field name: ..."}A non-form field is outside the allowlist.
Database/runtime errorNonblank search, unsafe notes, an unavailable won_date column, or malformed IDs produce invalid SQL.

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

Behaviour and edge cases

  • Phase-1 IDs are sorted ascending. Phase-2 rows have no explicit order, so callers must match by opportunity_id.
  • Status is translated to its name only for the first requested status occurrence. Other IDs remain numeric; lead source/user/customer are not name-expanded by this route—the export widget handles their field types.
  • parent looks up the opportunity customer’s parent_id. A form-field request is populated only when its form ID equals the row’s form_id and its key exists in form_values.
  • The won_date filter option is present in code but no corresponding opportunity column appears in the canonical tenant schema/migrations reviewed for this batch.

See it in Fieldmotion

CRM1

The Opportunities Export button uses phase 1 with its date range and table search, then phase 2 for selected base/form columns.

CRM2

CRM2 first obtains filtered IDs from Opportunities_getDataTable, then its export widget uses phase 2 with those IDs.

Related endpoints