When to use this endpoint

Use Customers_list to populate customer pickers, build a small customer export, find an exact or wildcarded name, or retrieve records changed after a timestamp. The response contains records directly, so it works well for modest result sets.

For a large incremental integration, prefer Customers_listByLastEdited to obtain IDs and then fetch only required fields with Customers_getById. That split produces smaller retryable steps.

Authentication and permissions

The request must use signed API-key authentication or a logged-in CRM session. API-key authentication runs as the active user linked to that key.

The handler requires a logged-in user but performs no additional role or page-permission check. It queries only the authenticated tenant's customer table and always excludes rows marked as deleted.

Parameters

ParameterTypeRequiredDescription
results-per-pageInteger stringNoEnables pagination and sets the page size. Must convert to an integer greater than zero. When omitted, the endpoint returns every matching row and does not add an order clause.
current-pageInteger stringNoZero-based page index; defaults to 0 and must not be negative. It affects the query only when results-per-page is set.
fieldsJSON array or arrayNoAdditional allowed fields to return. id, name, and is_active are always selected. Unknown names are silently ignored.
nameStringNoMatches the complete stored name unless the value contains %. A value such as Northwind% uses SQL LIKE and treats % as a wildcard.
last_editedDate-time stringNoReturns rows whose last_edited is strictly later than this value and strictly earlier than the server's current time. Use yyyy-mm-dd hh:mm:ss.
is_activeInteger stringNoCompared with the stored activity flag after integer conversion. Use 1 for active customers or 0 for inactive customers.
check_parentInteger stringNoWhen set to 1, and the tenant setting parent-customer-selection is also 1, excludes customers currently referenced as a parent. Otherwise it has no effect.

Additional fields

account_number, id, name, notes, email, last_edited, industry,
street_address1, street_address2, town, county, postcode, landline,
mobile, contact_name, changes, edited_uuid, appId, cdate,
appointments_open, appointments_closed, custom_values, callback,
account_manager, meta, callback_notes, lead_acc, parent_id, latitude,
longitude, is_active, country, created_by, files, department_id, city,
state, last_edited_all, is_flagged, contacts, has_invoices, type,
price_band, accounts_name, accounts_number, credit_terms, area_id

Field names are exact. For example, isActive is not an alias for is_active. Stored JSON columns are returned as encoded strings.

Example request

This request retrieves the second page of active customers edited after the checkpoint, ordered by customer ID because pagination is enabled:

$customers = FM_api('Customers_list', [
	'last_edited' => '2026-09-24 08:00:00',
	'is_active' => '1',
	'fields' => json_encode(['email', 'account_number', 'last_edited']),
	'results-per-page' => '100',
	'current-page' => '1',
]);

Example response

[
  {
    "id": "1104",
    "name": "Northwind Service Centre",
    "is_active": "1",
    "email": "service@example.test",
    "account_number": "NW-1104",
    "last_edited": "2026-09-24 09:41:18"
  },
  {
    "id": "1107",
    "name": "Northwind Cork",
    "is_active": "1",
    "email": "cork@example.test",
    "account_number": "NW-1107",
    "last_edited": "2026-09-24 09:46:02"
  }
]

The endpoint returns a plain array. It does not return a total count, current-page metadata, or a next-page token.

Errors and unusual responses

ResponseCondition
{"error":"invalid parameter: results-per-page"}The supplied value converts to less than 1.
{"error":"invalid parameter: current-page"}The supplied value converts to a negative integer.
{"error":"not logged in"}The request did not establish an authenticated user.
[]No non-deleted customer matches all supplied filters, or the requested page is past the end.

Malformed fields data and unknown field names do not produce an error; the response falls back to the three always-selected fields. Application errors may arrive in an HTTP 200 response.

Behaviour and edge cases

  • All supplied filters are combined with logical AND.
  • Soft-deleted customers are always excluded; inactive customers remain unless is_active=1 is supplied.
  • Without pagination, no ordering is specified and the full match set is returned. With pagination, rows are ordered by ascending id before applying the offset and limit.
  • current-page is zero-based: page 0 begins at offset zero, page 1 at one page size, and so on.
  • A future-dated or current-second last_edited value returns no matching current rows because the query also applies a strict upper bound of the server's current timestamp.
  • The legacy check_parent filter is tenant-setting dependent. Its parent-ID subquery considers every row with a non-zero parent_id, including deleted child rows.
  • The endpoint does not calculate derived names such as parent_name; use Customers_getById when those are needed.

See it in Fieldmotion

CRM1

Open a job for editing and open its Customer picker. In browser developer tools, filter Network requests for Customers_list. CRM1 sends is_active=1, asks for street_address1 and is_flagged, and sends check_parent=1 so the tenant's parent-selection rule can be applied. The Create Customer dialog also calls this endpoint to populate its Parent list.

CRM2

Open the create/edit Job page with developer tools open and filter for Customers_list. CRM2 loads the customer options with is_active=1 and requests relationship fields such as parent_id, type, department_id, account_manager, and area_id. The endpoint is also used to preload selectors on Contracts, recurring invoices, Tasks, Opportunities, and Assets screens.

Related endpoints

  • Customers_getById retrieves a known set of IDs and can add derived parent, type, and account-manager names.
  • Customers_listByLastEdited returns IDs only and is the better first step for large incremental syncs.
  • Customer_new creates a new record that will appear in this list unless it is later soft-deleted.
  • Short polling explains safe overlap and checkpoint handling.