POST

Customer.Update

Update an existing customer. The method validates folder permission, validates custom fields from User.Basic, blocks duplicate email/phone/mobile/company_id/name conflicts, pushes the changed customer to the team, and runs customer.updated automation when enabled.

Permissions

  • User must be allowed to edit this customer.
  • If folder_id is changed, user must be allowed to see this folder or be owner/manager in the organization.

Action

  • Updates the customer row.
  • Validates folder/status access.
  • Validates custom fields from User.Basic.
  • Blocks duplicate email, phone, mobile, company_id, or name conflicts.

Push Service

Pushes the changed customer to team members that can see this customer.

Automation

Runs automation event customer.updated with customer_id and changed fields when enabled.

Special Instructions

  • If a sent email/phone/company id belongs to another customer, the response returns existing_customer_id and duplicate details.

Required Parameters

NameTypeSampleExplanation
customer_id
post
int123Customer id to update. You may also send cust_id.

Optional Parameters

NameTypeSampleWhat it gives
name
post
stringJohn Demo UpdatedCustomer name.
email
post
string[email protected]Customer email. If another customer already has this email, the route returns exists=1 with duplicate_by=email and existing_customer_id.
second_email
post
string[email protected]Updates the secondary email when this field is enabled.
phone
post
string0500000000Primary customer phone. Saved to the customer mobile field after normalization. If another customer already has this phone/mobile, the route returns duplicate_by=phone or duplicate_by=mobile.
mobile
post
string0500000000Alias for the primary customer phone. It participates in the same duplicate check as phone.
second_phone
post
string0500000001Updates the secondary phone. Saved to the customer phone field after normalization.
company
post
stringDemo LtdUpdates the customer company/business name.
company_id
post
string123456789Updates the company identifier. If checkUnique=company_id and another customer already has this value, the route returns duplicate_by=company_id.
checkUnique
post
stringemailDuplicate check mode for the edited values: email, phone, mobile, or company_id. Default follows the same customer rules as Customer.Add.
source
post
stringwebsiteUpdates the lead/customer source.
website
post
stringhttps://example.comUpdates the website field when enabled.
password
post
stringcustomer-passUpdates the customer password/reference field when enabled.
note
post
stringUpdated noteUpdates the customer note.
address
post
string12 Demo StreetUpdates the address.
city
post
stringTel AvivUpdates the city.
folder_id
post
int1Moves the customer to a folder/status id from User.Basic folders/statuses.
folder
post
int|string1Alias for folder_id. Multiple folders can be sent as comma-separated ids.
status_id
post
int1Updates the customer status when the account uses status_id.
tag
post
string1,2Replaces/updates comma-separated tag ids from User.Basic tags.
extra_fields
post
json{"vip_level":"silver"}JSON object for customer custom fields. Allowed keys/types come from User.Basic field_settings.customer.extra_fields.
extra_fields[field_name]
post
mixedsilverAlternative form-data style for one custom field value. Replace field_name with a key from User.Basic field_settings.customer.extra_fields.
cf-field_name
post
mixedsilverCustom-field alias. Replace field_name with a configured custom field key from User.Basic field_settings.customer.extra_fields. Unknown custom fields are rejected.
sub_list_data
post
string5Folder sub-status value. Requires folder/folder_id.
sub_list_data_name
post
stringstageName/key used for folder_sub_status when sub_list_data is sent.
internal_sub_status_list
post
string2Internal sub-status value saved under folder_sub_internal_status when sub_list_data is sent.
parent_customer_id
post
int456Moves/keeps this customer under a parent customer relation. Also accepts parent_cust_IIId.
parent_cust_IIId
post
int456Alias for parent_customer_id.
room_customer_name
post
int1When 1 and name is sent, duplicate detection also checks whether another customer already has the same cleaned name.
followup
post
datetime2026-07-20 10:00:00UTC follow-up date/time saved on the customer. Send UTC date/time as Y-m-d H:i:s, for example 2026-07-20 10:00:00. The SDK converts user local Date/local datetime input to UTC before posting.

Authentication

Send the bearer token returned by Login in the request header.

Authorization: Bearer YOUR TOKEN

Sample Request

{
    "url": "\/app\/Customer.Update",
    "method": "POST",
    "headers": {
        "Authorization": "Bearer YOUR TOKEN"
    },
    "body": {
        "customer_id": "123",
        "name": "John Demo Updated",
        "email": "[email protected]",
        "checkUnique": "email",
        "extra_fields": "{\"vip_level\":\"silver\"}"
    },
    "url_user": "https:\/\/{user}.bull36.com\/app\/Customer.Update",
    "url_domain": "https:\/\/{domain}\/app\/Customer.Update"
}

Endpoint

POST /app/Customer.Update
POST https://{user}.bull36.com/app/Customer.Update
POST https://{domain}/app/Customer.Update

Sample Output

{
    "success": 1,
    "exists": 0,
    "is_new": 0,
    "message": "Customer Updated",
    "customer_id": "123",
    "id": "123",
    "automation_event": "customer.updated",
    "socket_event": "customer.updated"
}

Existing Customer Response

{
    "success": 0,
    "exists": 1,
    "is_new": 0,
    "message": "Customer already exists",
    "customer_id": "123",
    "existing_customer_id": "456",
    "duplicate_by": "email",
    "duplicate_value": "[email protected]",
    "duplicate_reason": "same email"
}

Fail Response

{
    "success": 0,
    "message": "Customer not found or permission denied"
}

JavaScript Example

const token = 'YOUR TOKEN';
const body = new URLSearchParams({
  customer_id: '123',
  name: 'John Demo Updated',
  email: '[email protected]',
  checkUnique: 'email',
  extra_fields: JSON.stringify({ vip_level: 'silver' })
});

const res = await fetch('/app/Customer.Update', {
  method: 'POST',
  headers: { Authorization: `Bearer ${token}` },
  body
});

const data = await res.json();
if (data.exists) {
  console.log('cannot update because another customer already exists', {
    editing_customer_id: data.customer_id,
    existing_customer_id: data.existing_customer_id,
    duplicate_by: data.duplicate_by,
    duplicate_value: data.duplicate_value,
    duplicate_reason: data.duplicate_reason
  });
} else {
  console.log('updated customer id', data.customer_id || data.id);
}
console.log(data);

Error Example

{
    "success": 0,
    "exists": 1,
    "is_new": 0,
    "already": 1,
    "already_id": "456",
    "existing_customer_id": "456",
    "duplicate_customer_id": "456",
    "duplicate_by": "email",
    "duplicate_value": "[email protected]",
    "duplicate_reason": "same email",
    "customer_id": "123",
    "id": "123",
    "message": "Customer already exists"
}