Skip to content

Merge two customers

POST
/customers/{id}/merge
curl --request POST \
--url https://example.com/customers/019205d1-6e7a-7c3b-9f6e-3a2b1c0d9e8f/merge \
--header 'Content-Type: application/json' \
--cookie __Host-bottle.session_token=<__Host-bottle.session_token> \
--data '{ "intoId": "019205d1-6e7a-7c3b-9f6e-3a2b1c0d9e8f" }'

Everything the duplicate holds moves to the account being kept: addresses, orders, invoices, payment requests, cylinder movements, deposit refunds, standing orders, prices, contacts, shop logins and its Xero match. Where both have something, the kept account keeps its own and the duplicate fills only what it lacks; a different person or contact detail becomes a contact. The duplicate stays as a tombstone pointing at it, because an order taken against it this morning still has to resolve to something.

id
required

UUID v7

string format: uuid

Example

019205d1-6e7a-7c3b-9f6e-3a2b1c0d9e8f

UUID v7

Media typeapplication/json
object
intoId
required

UUID v7

string format: uuid

Example

019205d1-6e7a-7c3b-9f6e-3a2b1c0d9e8f

The account that was kept

Media typeapplication/json
object
accountAccess
object
unpaidInvoices
required
boolean
newOrdersBlocked
required
boolean
deliveriesBlocked
required
boolean
id
required

UUID v7

string format: uuid
tradingName
required
string
>= 1 characters <= 160 characters
accountNumber
string | null
kind
required
string
Allowed values: commercial domestic
legalName
required
string | null
<= 200 characters
contactName
required
string | null
<= 200 characters
email
required
string | null format: email
phone
required
string | null
/^\+?[\d\s()-]{7,20}$/
paymentTerms
required
string
Allowed values: prepaid on_account cash_on_delivery
surchargeRule
string | null
Allowed values: add exclude
blockNewOrdersWhenUnpaid
boolean
blockBookedDeliveriesWhenUnpaid
boolean
preferredLocale
required

A language: en-GB English, ar Arabic, ur Urdu, pa Punjabi (Gurmukhi), hi Hindi, bn Bengali, gu Gujarati, zh-Hans Chinese (Simplified), pl Polish, ro Romanian, es Spanish, fr French, de German.

string | null
Allowed values: en-GB ar ur pa hi bn gu zh-Hans pl ro es fr de
paymentTermsDays
required
integer | null
<= 120
billingAddressId
required

UUID v7

string | null format: uuid
hireBillingPeriod
required
string | null
Allowed values: weekly monthly quarterly
cylinderCharge
required

Deposit: paid once with the cylinder and refunded on return. rent: charged while they keep it, no deposit.

string | null
Allowed values: deposit rent both
rateSetId
required

UUID v7

string | null format: uuid
invoiceSchedule
One of:
object
mode
required
string
Allowed values: business
hireBilledTo
required
string | null format: date
notes
required
string | null
<= 2000 characters
archivedAt
required
string | null format: date-time
mergedIntoId
required

UUID v7

string | null format: uuid
legalHold
required
boolean
erasedAt
required
string | null format: date-time
contacts
Array<object>
object
id
required

UUID v7

string format: uuid
name
required
string
email
required
string format: email
phone
required
string | null
/^\+?[\d\s()-]{7,20}$/
kind
required
string
Allowed values: normal billing both
relationship
required
string | null
<= 60 characters
shopperAccounts
Array<object>
object
id
required

UUID v7

string format: uuid
email
required
string
verified
required
boolean
lastSignInAt
required
string | null format: date-time
twoFactor
required
boolean
role
required
string
Allowed values: manager buyer accounts
shopperInvitations
Array<object>
object
id
required

UUID v7

string format: uuid
email
required
string
role
required
string
Allowed values: manager buyer accounts
expiresAt
required
string format: date-time
createdAt
required
string format: date-time
createdAt
required
string format: date-time
updatedAt
required
string format: date-time

Example

{
"id": "019205d1-6e7a-7c3b-9f6e-3a2b1c0d9e8f",
"tradingName": "Camden Lock Grill",
"accountNumber": "BTL00313",
"kind": "commercial",
"legalName": "Camden Lock Grill Ltd",
"contactName": "Priya Shah",
"email": "orders@camdenlockgrill.co.uk",
"phone": "07700 900123",
"paymentTerms": "prepaid",
"surchargeRule": "add",
"preferredLocale": "en-GB",
"billingAddressId": "019205d1-6e7a-7c3b-9f6e-3a2b1c0d9e8f",
"hireBillingPeriod": "weekly",
"cylinderCharge": "deposit",
"rateSetId": "019205d1-6e7a-7c3b-9f6e-3a2b1c0d9e8f",
"invoiceSchedule": {
"mode": "business"
},
"mergedIntoId": "019205d1-6e7a-7c3b-9f6e-3a2b1c0d9e8f",
"contacts": [
{
"id": "019205d1-6e7a-7c3b-9f6e-3a2b1c0d9e8f",
"phone": "07700 900123",
"kind": "normal",
"relationship": "Accounts"
}
],
"shopperAccounts": [
{
"id": "019205d1-6e7a-7c3b-9f6e-3a2b1c0d9e8f",
"role": "manager"
}
],
"shopperInvitations": [
{
"id": "019205d1-6e7a-7c3b-9f6e-3a2b1c0d9e8f",
"role": "manager"
}
]
}

Not signed in

Media typeapplication/json
object
error
required
string
message
required
string

Example

{
"error": "not_found",
"message": "Customer not found"
}

Not a member of that tenant

Media typeapplication/json
object
error
required
string
message
required
string

Example

{
"error": "not_found",
"message": "Customer not found"
}

Not found

Media typeapplication/json
object
error
required
string
message
required
string

Example

{
"error": "not_found",
"message": "Customer not found"
}

Cannot merge a customer into itself

Media typeapplication/json
object
error
required
string
Allowed values: validation
message
required
string
issues
required
Array<object>
object
path
required
string
message
required
string

Example

{
"error": "validation",
"issues": [
{
"path": "email",
"message": "Invalid email"
}
]
}