When to use this endpoint

Use CRM2’s configurable header export. It now discovers IDs through PurchaseOrders_getDataTable and passes batches to this endpoint; the older _ids=1 discovery branch still exists.

Authentication and permissions

Authenticate with signed API-key fields or a logged-in CRM session. Session requests use dispatcher CSRF protection when configured. API keys use their owner’s identity.

Purchase Order View is required on the singular or plural page. Records must be active and inside the configured TeamAccess or legacy Department Based Filter boundary; administrators are exempt from record restrictions. API-key requests use their owner’s identity. Related display names require the corresponding page View and record visibility.

Parameters

ParameterTypeRequiredDescription
_idsString sentinel or JSON array stringYesExact scalar "1" selects discovery mode. Otherwise supply a nonempty JSON array of header IDs, even for one record. Native arrays are not decoded. IDs must be positive integer values; [] is an error, not an all-record selector.
fieldsJSON array stringIn row modeNonempty stored/export field names: attention, cdate, created_by, date_approved, date_sent, delivery_address, delivery_date, delivery_net, delivery_tax, delivery_taxcode, form_id, id, instructions, invoice_received, last_edited, metaStatus, meta_date_order_fully_received, po_num, reference, ro_id, rows, status, supplier_id, target_id, target_type, tax_inc, total_net, total_tax. Output keys are f0,f1,… in request positions, plus po_id. Native field arrays are not decoded.
dateReference / daysFrom / daysToMapped date choice / relative daysDiscovery onlyDefault All disables these bounds. cDate, dateApproved or deliveryDate enables supplied relative day offsets; literal NaN skips that bound, while a supplied blank integer-converts to day 0. Uses server today through inclusive end-day 23:59:59.
poID / poNum / referenceHeader ID / displayed number / textDiscovery onlyWhen present adds exact integer ID/number or reference substring. Zero is a real ID/number filter here. Reference text is escaped and treated as a literal substring (LIKE wildcards still apply).
formIDs / supplierIDs / statusesComma-separated numeric stringsDiscovery onlyNonempty comma-separated unsigned integer strings, not JSON arrays. Empty/malformed lists return an error before SQL.
customersNative, JSON or comma-separated ID listDiscovery onlyCustomer filter following direct Customer, Quote customer and ordinary customer-Job links. An explicitly empty normalized customer list matches no headers in this discovery branch.
referenceDateField / dateFromFilter / dateToFilter / isDateUnixStored field / relative days / flagDiscovery onlyBoth relative day offsets plus a stored field enable an inclusive range, optionally converted from Unix time. Allowed fields: cdate, date_approved, delivery_date and id. Invalid names and malformed offsets are rejected.
returnedStatusScalar or native listDiscovery onlyEmpty/cleared values disable it. Any remaining nonempty value selects orders with active Goods Returned headers; not a two-way boolean choice.

Example request

$rows = FM_api('PurchaseOrders_exportData', [
	'_ids'=>json_encode(['1042']),
	'fields'=>json_encode(['id','supplier_id','status','total_net']),
]);

Example response

[
  {
    "po_id": "1042",
    "f0": "1042",
    "f1": "Example supplier",
    "f2": "0",
    "f3": "35.00"
  }
]

For legacy discovery, send _ids="1" plus the filter controls; the response is an ids object rather than these f-position rows. No file is written or streamed by this route.

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"}The mode/selection key is absent.
{"error": "_ids should be a JSON array of numbers"}Row mode does not decode to a nonempty array.
{"error": "fields should be an array of requested field names"}Row-mode fields is absent, empty or not an array.
{"error": "unknown field name: unsupported"}A non-custom field token is outside the export map.
{"error":"permission denied"}The required page permission is missing. Hidden/deleted records are omitted from collections; explicit parent readers reject an inaccessible parent.

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

Behaviour and edge cases

  • Discovery returns {ids:[integer IDs]} without counts, cap or guaranteed order. Row mode returns a bare array for explicit active visible IDs; discovery search/date filters are not repeated. No cursor or batch-size limit.
  • The legacy Department Based Filter follows direct Customer links, Quote customers and ordinary customer-Job links; restricted users cannot discover unlinked or other unsupported targets. Configured TeamAccess uses the same boundary as the singular header readers.
  • Both modes enforce active header scope and Purchase Order View independently of the IDs selected by the UI.
  • po_id is always the local header ID. supplier_id becomes the authorized supplier name; target_type becomes a type label including Warehouse, while target_id remains raw. created_by and received status remain numeric codes.
  • metaStatus resolves numeric meta.status through common_lists type purchaseStatus; missing/non-numeric metadata yields blank. meta_date_order_fully_received maps JSON null/missing to blank. total_net/total_tax are raw carriage-inclusive amounts.
  • Repeated requested names keep separate f-position columns and receive identical transformations. Unknown or custom-table/colon fields fail before querying; no requested column silently disappears.

Side effects

  • Reads tenant data without modifying orders, lines, stock, approval, history or notifications.

See it in Fieldmotion

CRM1

No direct CRM1 literal caller was found in the searched client source. CRM1 downloads fixed CSV through PurchaseOrders_export.

CRM2

In CRM2 Purchase Orders, configure an export map and export headers. The page gathers filtered IDs with the unpaged table, then widgetExportCRM2 sends _ids and fields as JSON strings to PurchaseOrders_exportData and creates the CSV client-side.

Related endpoints