Customers
Create a mapped customer
/a/Customer_createData
Create a customer through the CRM2 field-map/layout pipeline.
When to use this endpoint
Use Customer_createData when submitting the configurable CRM2 Customer Create layout or an embedded form that follows the same camel-case field map.
Do not interchange its parameter names with Customer_new. The two routes apply different validation, defaults, audit logging, and side effects.
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
| Parameter | Type | Required | Description |
|---|---|---|---|
name | String | Yes | Mapped customer name. Empty serialized text is rejected. When duplicate names are disabled, an existing exact case-insensitive name is suffixed with the duplicate count in parentheses. |
contactName | String | Yes | Mapped primary contact name. The layout map marks it required even though the older create endpoint treats its snake-case counterpart differently. |
accountNumber, email, industry, landline, mobile, notes | Strings | No | Core mapped identity/contact fields. landline is trimmed only for its uniqueness check; the generic converter stores the submitted mapped value. |
streetAddress1, streetAddress2, town, city, county, state, postcode, country | Strings | No | Mapped address fields. When country is absent, customer-default-country is inserted. A supplied country is not normalized by this create route. |
latitude, longitude | Numbers | No | Stored as numeric coordinates. This endpoint does not geocode a missing point. |
parentId / parent | Integer or picker object | No | Parent customer. Picker form parent: {id: ...} is flattened to parentId. The target is not validated here. |
accountManagerID / accountManager | Integer or picker object | No | Account-manager user ID. Picker form accountManager: {id: ...} is flattened. The target is not validated. |
departmentId, areaID, type, priceBand, billing_target | Integers | No | Mapped relationship/configuration IDs. The generic create path converts them to integers but does not verify referenced rows. |
callback, callbackNotes, creditTerms, accountsName, accountsNumber | Strings | No | Callback, credit, and accounts-contact values. A callback date is accepted as mapped datetime text. |
customValues, contacts | JSON value | No | Stored JSON fields. customValues defaults to {}; JSON conversion follows the generic data processor. |
widgetTableContact | JSON string/array | No | Contact rows using keys name, types, phone, email, notes, and allowReceiveEmail. Recognized values are converted and stored as contacts. |
marketingSource, accountSage, discount, doNotSMS, defaultNominal, defaultTaxcode | Mapped scalar | No | Allow-listed top-level inputs stored inside customer meta. |
accountingEmail, additionalEmail, additionalAccountingEmail, doNotEmailInvoices, owned, defaultInvoiceFormID | Mapped scalar | No | Additional allow-listed metadata values. defaultInvoiceForm picker input can supply defaultInvoiceFormID. |
defaultInvoiceDueDateMode | String | No | One of blank, days_after_invoice_date, days_after_invoice_month_end, day_of_invoice_month, or day_of_following_month. |
defaultInvoiceDueDate | Integer string or blank | No | 0–3650, or 1–31 for day-of-month modes. Blank removes/omits the metadata key. |
isActive, isFlagged, leadAcc, hasInvoices, login, password, passwordSalt | Mapped internal scalar | No | Hidden/internal field-map keys that the generic create helper currently accepts. New integrations should not set them; use supported lifecycle and portal-password endpoints. |
changes, editedUuid, appId, lastEdited, lastEditedAll, files, meta, createdBy, createDate | Mapped internal scalar | No | Legacy/internal storage keys accepted by the generic mapper. Omission supplies server defaults for createdBy and createDate. Do not use these keys as an audit or timestamp override contract. |
appointmentsOpen, appointmentsClosed | Integer | No | Obsolete hidden job-count storage identifiers accepted by the shared map. Do not set them; job counters are maintained by server workflows. |
noRecord / noRecordCustom | Arrays | No | Field/custom-key names whose generic activity-log entries are marked hidden. These internal controls do not prevent storage. |
Example request
$result = FM_api('Customer_createData', [
'name' => 'Northwind Service Centre',
'contactName' => 'Alex Morgan',
'landline' => '+442890123456',
'email' => 'service@example.test',
'country' => 'GBR',
'defaultInvoiceDueDateMode' => 'days_after_invoice_date',
'defaultInvoiceDueDate' => '30',
]);
Example response
{
"ok": 1,
"id": 1042
}
Errors and unusual responses
| Response | Condition |
|---|---|
{"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: name"} | Mapped name is absent or empty. |
{"error":"missing or invalid parameter: contactName"} | Mapped contactName is absent or empty. |
{"error":"That Contact Number is already in use."} | customer-landline-unique is enabled and the trimmed contact number matches a non-deleted customer. |
{"error":"invalid default invoice due date mode"} | The due-date mode is outside the allow-list. |
{"error":"default invoice due date value must be between ..."} | The due-date value is non-numeric, too large, or outside 1–31 for a day-of-month mode. |
{"error":"missing or invalid parameters."} | No mapped value can be converted into an insert. Normal calls hit required-field errors first. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- Unknown request keys are ignored except wrapper controls such as
widgetTableContact. There is no pagination. - If
customer-name-allow-duplicateequals numeric zero and an exact active name exists, the name becomes<name> (<count>). This count-based suffix can still collide when existing suffixes are irregular. - The uniqueness query and contact-number setting consider non-deleted customers only. No permission beyond authenticated tenant access is required.
- The mapped create route does not apply the older endpoint’s required-contact-number setting, length checks, email syntax checks, country normalization, relationship validation, or geocoding.
- Creation and post-create notices/events are not wrapped in a transaction.
Side effects
- Inserts the customer, invalidates its cache, and writes generic activity-log entries for mapped inserted fields.
- Sends mention notices, fires
Customer_new, and publishes the customer create notification after insertion. - Embedded-form creation can call this route internally with a cleared request context.
See it in Fieldmotion
CRM1
No direct CRM1 JavaScript caller was found. CRM1’s create dialog uses Customer_new.
CRM2
The Customer layout map registers this as its create endpoint. Submit Customers → Create Customer and filter Network requests for Customer_createData.
Related endpoints
Customer_getLayoutDetailsreads the same mapped fields.Customer_updateDataupdates the same mapped fields.Customer_newis the older snake-case create contract.