Update a customer

Operation ID: updateCustomer

Group: Accounting › Customers

Open in the interactive reference

PATCH /accounting/customers/{id}

Retry-safe: A write that accepts Idempotency-Key: repeating a request with the same key replays the stored answer instead of executing twice.

Updates a customer with the fields you send. A field you leave out keeps its current value. To clear a field that accepts null, send null.

Use the customer's id, not its customerNumber.

taxRegistrations and addresses each replace the whole list, so include every item you want to keep. To change addresses one at a time, use createAddresses, updateAddresses, and deleteAddresses. External identifiers change through createExternalIdentifiers, updateExternalIdentifiers, and deleteExternalIdentifiers.

To move the customer to another legal entity, send entityId. Documents created afterward use the new legal entity. Existing sales orders, invoices, and payments keep the legal entity they were created under. The customer keeps its payment term unless you also send paymentTermCode, and the request fails with PAYMENT_TERM_NOT_AVAILABLE_FOR_ENTITY when the new legal entity doesn't have that payment term. defaultCurrency doesn't change, so send it too if the new legal entity uses another currency.

If you change name, customerType, or entityId, another customer with the same name, legal entity, and customer type makes the request fail with DUPLICATE_CUSTOMER.

The response is empty. Read the updated record with GET accounting/customers/:id.

Parameters

Name In Type Required Description
Api-Version header string · v1 yes The API version this request targets, named by its public identifier. Required on every request; omitting it, or naming a version this company does not have, is answered with 400. This document describes version v1.
Idempotency-Key header string no An opaque caller-chosen string (1-255 characters) that makes this request safe to retry. Repeating the same key with an identical request body replays the original response instead of re-executing - but only once that original request succeeded; a failed attempt re-executes on retry. Repeating the key with a different body is answered with 422. A key still in flight is answered with 409 - as is a key whose original request was interrupted before it finished, for a few minutes afterwards, until that attempt is presumed dead. A completed response stays replayable for 24 hours. The key is scoped to the caller, not to the action: reusing it for a different action is answered with 409 or 422 rather than treated independently. On read actions this header is ignored. On write actions that cannot offer the guarantee it is answered with 400 IDEMPOTENCY_NOT_SUPPORTED rather than silently ignored.
id path string yes The unique identifier of the customer you want to update.

Request body

Required, application/json: updateCustomerInput.

Field Type Required Description
entityId string no The id of the legal entity to move the customer to. Documents created afterward use this legal entity, and existing ones keep theirs.
name string no The name of the customer, as it appears on invoices.
customerType string no The customer type. Accepted values: 'default', 'partner'. Cannot be changed once the customer appears on a sales order. That change fails with CUSTOMER_TYPE_CHANGE_NOT_ALLOWED. 'endCustomer' is not supported and fails with END_CUSTOMER_NOT_SUPPORTED.
partnerType string | null no The partner type, for a customer whose customerType is 'partner'. Accepted values: 'reseller', 'thirdPartyPayer'.
businessType string no The business type of the customer. Accepted values: 'company', 'individual'.
invoiceEmail string | null no The email address invoices are sent to. Example: "ap@example-robotics.com".
mainEmail string | null no The email address of the customer's main contact.
taxExempt boolean no Whether the customer is exempt from tax. Setting it to false also clears exemptionNumber and taxExemptCode.
defaultCurrency string no The default currency for the customer's transactions, as a 3-letter ISO 4217 code.
segment string | null no The market segment of the customer. Accepted values: 'SMB', 'MidMarket', 'Enterprise'. Ignored when businessType is 'individual', in this request or already set. Example: "MidMarket".
exemptionNumber string | null no The tax-exemption certificate number. Accepted only when taxExempt is true, in this request or already set. Otherwise the request fails with EXEMPTION_NUMBER_REQUIRES_TAX_EXEMPT.
paymentTermCode string no The code of a payment term on the customer's legal entity's list. When the request also changes entityId, the code must be on the new legal entity's list. A code that is not on the list fails with UNKNOWN_REFERENCE. See code on GET accounting/payment-terms.
parentId string no The id of the parent customer. An unknown id fails with UNKNOWN_REFERENCE.
partnerId string no The id of the partner this customer buys through. An unknown id fails with UNKNOWN_REFERENCE.
salesChannel string | null no The sales channel for this customer. Accepted values: 'salesAssisted' (sold through a salesperson), 'selfServe'.
additionalContactEmail string | null no Another email address for the customer, besides invoiceEmail and mainEmail.
mainContactName string | null no The name of the customer's main contact.
preferredLanguage string | null no The customer's preferred language. Accepted values: 'english'.
crmCustomerId string | null no The customer's identifier in an external CRM system.
businessIdentificationNumber string | null no The customer's business registration number.
invoiceConsolidation string | null no How the customer's invoices are consolidated. Accepted values: 'customer', 'purchaseOrderNumber', 'salesArrangement'.
invoiceDeliveryMode string | null no How invoices are delivered to the customer. Accepted values: 'manual', 'automated'.
isExemptFromCreditCardFee boolean no Whether the customer is exempt from credit-card fees.
billableTravelExpenseInvoiceDetail string no How billable travel and expense items appear on invoices. Accepted values: 'detailed', 'consolidated'.
status string no The status of the customer. Accepted values: 'active', 'inactive'.
taxExemptCode string | null no The tax-exemption reason code. Cleared when taxExempt is false.
taxRegistrations array<object> no The customer's tax registrations. This array replaces the customer's whole set of registrations. An entry matching an existing registration on country and type updates it. Any other entry is added. A registration not in the array is deleted. Send an empty array to remove them all.
taxRegistrations[].country string yes The country the registration applies in, as an ISO 3166-1 code.
taxRegistrations[].taxNumber string yes The tax identification number issued by the tax authority.
taxRegistrations[].type string yes The kind of tax registration. Accepted values: 'tax', 'salesTax', 'VAT', 'GST', 'EIN', 'TIN'.
taxRegistrations[].effectiveDate date no The date the registration takes effect. Use format YYYY-MM-DD.
taxRegistrations[].isActive boolean no Whether the registration is active. Only one active registration is allowed per country and tax type. Defaults to true.
payment object no The customer's link to a payment provider. externalPaymentMethodId requires externalCustomerId, in this request or already set.
payment.provider string no The name of a payment provider connected to your tenant. An unknown name fails with UNKNOWN_PAYMENT_PROVIDER, which lists the connected providers. Required when any other payment field is sent. Example: 'Stripe'.
payment.externalCustomerId string no The customer's identifier in the payment provider's system.
payment.externalPaymentMethodId string no The customer's default payment method in the payment provider's system.
addresses array<object> no The customer's addresses. This array replaces the customer's whole address set, both types, and every address gets a new addressId. Send an empty array to remove every address.
addresses[].type string yes The address type. Accepted values: 'billTo', 'soldTo'.
addresses[].attention string no The person or department that mail to this address is for.
addresses[].isDefault boolean no Whether this entry is the default address of its type.
addresses[].line1 string yes The first address line: street number and name, or PO box.
addresses[].line2 string no The second address line: apartment, suite, unit, building, or floor.
addresses[].city string yes The city or locality.
addresses[].stateProvince string no The state, province, or region.
addresses[].country string yes The country, as a name or ISO 3166-1 code.
addresses[].zipCode string yes The postal or ZIP code.
createAddresses array<object> no Addresses to add to the customer, alongside its existing ones. Mark at most one entry per type as the default with isDefault. Cannot be combined with addresses. That combination fails with INVALID_FIELD_VALUE.
createAddresses[].type string yes The address type. Accepted values: 'billTo', 'soldTo'.
createAddresses[].attention string no The person or department that mail to this address is for.
createAddresses[].isDefault boolean no Whether this entry is the default address of its type.
createAddresses[].line1 string yes The first address line: street number and name, or PO box.
createAddresses[].line2 string no The second address line: apartment, suite, unit, building, or floor.
createAddresses[].city string yes The city or locality.
createAddresses[].stateProvince string no The state, province, or region.
createAddresses[].country string yes The country, as a name or ISO 3166-1 code.
createAddresses[].zipCode string yes The postal or ZIP code.
updateAddresses array<object> no Changes to existing addresses of the customer, each named by its addressId. A field you omit keeps its current value. Each address keeps its addressId. An addressId the customer does not have fails with ADDRESS_NOT_FOUND. Cannot be combined with addresses. That combination fails with INVALID_FIELD_VALUE.
updateAddresses[].addressId string yes The address to update. See addressId on GET accounting/customers/:id.
updateAddresses[].type string no The address type. Accepted values: 'billTo', 'soldTo'. A different value moves the address to that type.
updateAddresses[].attention string no The person or department that mail to this address is for.
updateAddresses[].isDefault boolean no Whether this entry is the default address of its type.
updateAddresses[].line1 string no The first address line: street number and name, or PO box.
updateAddresses[].line2 string no The second address line: apartment, suite, unit, building, or floor.
updateAddresses[].city string no The city or locality.
updateAddresses[].stateProvince string no The state, province, or region.
updateAddresses[].country string no The country, as a name or ISO 3166-1 code.
updateAddresses[].zipCode string no The postal or ZIP code.
deleteAddresses array<string> no The addressIds of the addresses to remove from the customer. An addressId the customer does not have fails with ADDRESS_NOT_FOUND. When you remove the default address of a type, another address of that type becomes the default. Cannot be combined with addresses. That combination fails with INVALID_FIELD_VALUE. See addressId on GET accounting/customers/:id.
createExternalIdentifiers array<object> no External identifiers to add. A fieldName the customer already has fails with DUPLICATE_EXTERNAL_IDENTIFIER.
createExternalIdentifiers[].fieldName string yes The configured field name of the identifier. Example: 'netsuiteCustomerId'.
createExternalIdentifiers[].value string yes The identifier in the other system.
createExternalIdentifiers[].externalUrl string no A link to the record in the other system.
updateExternalIdentifiers array<object> no External identifiers to replace, matched by fieldName. A fieldName the customer does not have fails with EXTERNAL_IDENTIFIER_NOT_FOUND.
updateExternalIdentifiers[].fieldName string yes The configured field name of the identifier. Example: 'netsuiteCustomerId'.
updateExternalIdentifiers[].value string yes The identifier in the other system.
updateExternalIdentifiers[].externalUrl string no A link to the record in the other system.
deleteExternalIdentifiers array<string> no The fieldNames of external identifiers to remove. A fieldName the customer does not have fails with EXTERNAL_IDENTIFIER_NOT_FOUND.
{
  "entityId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "name": "<name>",
  "customerType": "<customerType>",
  "partnerType": "<partnerType>",
  "businessType": "<businessType>",
  "invoiceEmail": "ap@example-robotics.com",
  "mainEmail": "<mainEmail>",
  "taxExempt": true,
  "defaultCurrency": "<defaultCurrency>",
  "segment": "MidMarket",
  "exemptionNumber": "<exemptionNumber>",
  "paymentTermCode": "<paymentTermCode>",
  "parentId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "partnerId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "salesChannel": "<salesChannel>",
  "additionalContactEmail": "<additionalContactEmail>",
  "mainContactName": "<mainContactName>",
  "preferredLanguage": "<preferredLanguage>",
  "crmCustomerId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "businessIdentificationNumber": "<businessIdentificationNumber>",
  "invoiceConsolidation": "<invoiceConsolidation>",
  "invoiceDeliveryMode": "<invoiceDeliveryMode>",
  "isExemptFromCreditCardFee": true,
  "billableTravelExpenseInvoiceDetail": "<billableTravelExpenseInvoiceDetail>",
  "status": "<status>",
  "taxExemptCode": "<taxExemptCode>",
  "taxRegistrations": [
    {
      "country": "<country>",
      "taxNumber": "<taxNumber>",
      "type": "<type>",
      "effectiveDate": "2026-01-15",
      "isActive": true
    }
  ],
  "payment": {
    "provider": "<provider>",
    "externalCustomerId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "externalPaymentMethodId": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
  },
  "addresses": [
    {
      "type": "<type>",
      "attention": "<attention>",
      "isDefault": true,
      "line1": "<line1>",
      "line2": "<line2>",
      "city": "<city>",
      "stateProvince": "<stateProvince>",
      "country": "<country>",
      "zipCode": "<zipCode>"
    }
  ],
  "createAddresses": [
    {
      "type": "<type>",
      "attention": "<attention>",
      "isDefault": true,
      "line1": "<line1>",
      "line2": "<line2>",
      "city": "<city>",
      "stateProvince": "<stateProvince>",
      "country": "<country>",
      "zipCode": "<zipCode>"
    }
  ],
  "updateAddresses": [
    {
      "addressId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "type": "<type>",
      "attention": "<attention>",
      "isDefault": true,
      "line1": "<line1>",
      "line2": "<line2>",
      "city": "<city>",
      "stateProvince": "<stateProvince>",
      "country": "<country>",
      "zipCode": "<zipCode>"
    }
  ],
  "deleteAddresses": [
    "<deleteAddresses>"
  ],
  "createExternalIdentifiers": [
    {
      "fieldName": "<fieldName>",
      "value": "<value>",
      "externalUrl": "<externalUrl>"
    }
  ],
  "updateExternalIdentifiers": [
    {
      "fieldName": "<fieldName>",
      "value": "<value>",
      "externalUrl": "<externalUrl>"
    }
  ],
  "deleteExternalIdentifiers": [
    "<deleteExternalIdentifiers>"
  ]
}

Response

200 Success

{
  "data": {},
  "diagnostics": [
    {
      "code": "<code>",
      "message": "<message>",
      "severity": "error",
      "path": [
        "<path>"
      ],
      "details": "<details>"
    }
  ]
}

Response headers

Errors

Code Status
NOT_FOUND 400
INVALID_ENTITY 400
PAYMENT_TERM_NOT_AVAILABLE_FOR_ENTITY 400
INVALID_FIELD_VALUE 400
MULTIPLE_DEFAULT_ADDRESSES 400
DUPLICATE_CUSTOMER 400
END_CUSTOMER_NOT_SUPPORTED 400
UNKNOWN_EXTERNAL_IDENTIFIER 400
DUPLICATE_EXTERNAL_IDENTIFIER 400
EXTERNAL_IDENTIFIER_NOT_FOUND 400
ADDRESS_NOT_FOUND 400
CUSTOMER_TYPE_CHANGE_NOT_ALLOWED 400
UNKNOWN_REFERENCE 400
UNKNOWN_PAYMENT_PROVIDER 400
PAYMENT_METHOD_REQUIRES_CUSTOMER_ID 400
EXEMPTION_NUMBER_REQUIRES_TAX_EXEMPT 400
IDEMPOTENCY_KEY_CONFLICT 409
IDEMPOTENCY_PAYLOAD_MISMATCH 422

Statuses