When to use this endpoint

Use Customer_exportChanges from the customer Changes tab after Customer_getChangesDT has normalized any legacy embedded history.

The endpoint streams CSV and exits. FM_api() returns the raw CSV text rather than decoded JSON.

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
customer_idInteger stringYesPositive customer ID. Customer existence is not checked.
f-fieldStringNoCase-insensitive substring filter on the change label. Unlike Customer_getChangesDT.field, this is not an exact match. Blank presence produces a match-all substring.

Example request

$csv = FM_api('Customer_exportChanges', [
	'customer_id' => '1088',
	'f-field' => 'Email',
]);
file_put_contents('customer-changes.csv', $csv);

Example response

Date,User,Field,"Change From","Change To"
2026-09-24,"Aoife Murphy",Email,old@example.test,service@example.test

The response is text/csv with attachment filename customer-changes.csv. Rows are ordered by change epoch descending.

The Date column is rendered as YYYY-MM-DD in the PHP server timezone, not converted through the tenant-time helper.

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: customer_id"}customer_id is absent, zero, negative, or non-numeric.
Header-only CSVNo normalized history row matches, including for a nonexistent positive customer ID.

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

Behaviour and edge cases

  • Array-valued old or new values are JSON-encoded into a CSV cell. Scalar values are written directly.
  • There is no pagination or maximum-row limit; the complete match set is loaded before the response is streamed.
  • The endpoint does not run the legacy-history migration. A customer whose changes still exist only in customers.changes can export an incomplete or header-only file until the table endpoint is called.

Side effects

  • Writes /tmp/<tenant ID>/tmp/customer_changes.csv, creating the tenant directory with mode 0777 when needed, then streams that file.
  • The fixed per-tenant filename is overwritten and left on disk. Concurrent exports in the same tenant can interfere with one another.

See it in Fieldmotion

CRM1

Open a customer’s Changes tab and choose Export. CRM1 submits a form to Customer_exportChanges with the customer ID and current field filter, causing a browser download.

CRM2

A source search found no CRM2 caller for this CSV endpoint.

Related endpoints