1. U4 ERPx
  2. API Reference
  3. Accounting
  4. Customers

Customers

The Customers API in Unit4 ERPx manages customer-related data such as creation, retrieval, updates, and termination (soft-delete) of customer records. It is designed for integration with mobile and other external applications, supporting microservice-based development, testing, and maintenance.

Purpose:
This API is used to create and maintain customers within ERPx.

Base URL:
/v1/customers

Authentication:
All APIs require a Client ID and Client Secret.
Refer to the global authentication documentation for details.

System Parameters:
System parameters for this API are available in Online Help → Sales → Customer Management → Fixed Registers → System Parameters.    

Supported Methods

HTTP MethodEndpointDescriptionLimits & Notes
GET/v1/customers/{customerId}Retrieve single customer dataReturns the whole object for a given customer ID / company ID. Only a single customer is returned – for more results please use the object API.
POST/v1/customersCreate a single customer recordOnly 1 customer per call. Can create with auto-numbering.
PATCH/v1/customers/{customerId}Update customer dataAllows patch operations on a customer. Only a single customer can be patched, but multiple operations may be made in a single request.
DELETE/v1/customers/{customerId}Terminate (soft-delete) a customerChanges status to ‘Closed’. Does not delete the customer permanently. The operation may be undone with a Replace operation through the PATCH endpoint on the path “/payment/status”.

   

Swagger / Schema

Version v1

   

Method Details

Sample Request

{
GET /v1/customers/11000002?companyId=EN
}

   

Validation Rules for GET Method – Single

GET_001 - Invalid authorisation
ElementDetails
Scenario IDGET_001
Scenario NameInvalid authorisation
HTTP Code401
GIVENThe token provided does not pass authorisation
WHENThe API request is sent
BUT
THENThe API stops with a 401 error and a message
Example Error Message{"statusCode": 401, "message": "Invalid JWT."}
GET_002 - User is not authorised to access API
ElementDetails
Scenario IDGET_002
Scenario NameUser is not authorised to access API
HTTP Code403
GIVENThe user is not authorised to access the API
WHENThe API request is sent
BUT
THENThe API stops with a 403 error and a message
Example Error Message{"code": 2030, "message": "User is not authorized"}
GET_003 - Missing mandatory parameter
ElementDetails
Scenario IDGET_003
Scenario NameMissing mandatory parameter
HTTP Code405
GIVENThe user does not provide a customerId for the request
WHENThe API request is sent
BUT
THENThe API stops with a 405 error
Example Error Message405 Method Not Allowed
GET_004 - Customer does not exist
ElementDetails
Scenario IDGET_004
Scenario NameCustomer does not exist
HTTP Code404
GIVENThe user provides a customerId which does not exist
WHENThe API request is sent
BUT
THENThe API stops with a 404 error
Example Error Message{"code": 1040, "message": "The entity of the following parameters [Company: EN, Customer: 213549674] was not found."}

Sample Request

{
  "aliasName": "ShortName",
  "companyId": "EN",
  "countryCode": "GB",
  "customerGroupId": "1",
  "customerId": "",
  "customerName": "NewCustomerName",
  "externalReference": 123456,
  "invoice": {
    "calculatePayDiscountOnTax": true,
    "checkCreditOnHeadOffice": false,
    "creditLimit": 300000.0,
    "currencyCode": "GBP",
    "hasFixedCurrency": true,
    "hasFixedPaymentTerms": true,
    "hasFixedTaxSystem": false,
    "languageCode": "EN",
    "paymentTermsId": "30"
  },
  "payment": {
    "bankAccount": "123456789",
    "debtCollectionCode": "IK1",
    "payMethod": "IP",
    "postalAccount": "987654321",
    "status": "Active"
  },
  "contactPoints": [
    {
      "additionalContactInfo": {
        "contactPerson": "ContactName"
      },
      "address": {
        "countryCode": "GB",
        "place": "LONDON WC2R 3LT",
        "streetAddress": "2 Customer Address Street"
      },
      "contactPointType": "1",
      "phoneNumbers": {
        "telephone1": "+44 71 828939"
      }
    }
  ]
}

Note: This request does not contain a customerId and therefore relies on auto-numbering setup to automatically assign a new customerId.    

Validation Rules for POST Method – Single

POST_001 - Autonumbering does not permit manual assignment
ElementDetails
Scenario IDPOST_001
Scenario NameAutonumbering does not permit manual assignment
HTTP Code422
GIVENIf there is an autonumbering series with manual assignment not permitted and the request body contains a customerId
WHENThe API is called
BUT
THENThe API stops with a 422 error which states that the Auto-numbering series is missing
Example Error Message{"code": 1010, "message": "Auto-numbering series is missing"}
POST_002 - Autonumbering series cannot be established
ElementDetails
Scenario IDPOST_002
Scenario NameAutonumbering series cannot be established
HTTP Code422
GIVENThere are multiple autonumbering series available
WHENThe API is called
BUT
THENThe API stops with a 422 error which states that the Auto-numbering series is missing
Example Error Message{"code": 1010, "message": "Auto-numbering series is missing"}
POST_003 - Autonumbering does not allow manual assignment
ElementDetails
Scenario IDPOST_003
Scenario NameAutonumbering does not allow manual assignment
HTTP Code422
GIVENThere is a single autonumbering series which does not permit providing a manual customerId and the request body contains a customerId
WHENThe API request is sent
BUT
THENThe API stops with a 422 error which states that you may not manually provide a customer ID
Example Error Message{"code": 1010, "message": "You cannot enter a new ID manually (CustomerID)."}
POST_004 - Missing mandatory fields
ElementDetails
Scenario IDPOST_004
Scenario NameMissing mandatory fields
HTTP Code422
GIVENA user is authorised AND the JSON body is missing a field that is marked mandatory in the schema
WHENThe API request is sent
BUT
THENThe API stops with a 422 error and a message
Example Error Message"The {0} field is required."
POST_005 - Illegal value
ElementDetails
Scenario IDPOST_005
Scenario NameIllegal value
HTTP Code422
GIVENA user is authorised AND the JSON body contains all mandatory properties AND one or more of the properties contain a value that is not permitted (for example, restricted to a list of attribute values)
WHENThe API request is sent
BUT
THENThe API stops with a 422 error and a message
Example Error Message"countryCode": [{"code": 3010, "message": "Illegal value."}]
POST_006 - Invalid format of fields
ElementDetails
Scenario IDPOST_006
Scenario NameInvalid format of fields
HTTP Code400
GIVENA user is authorised AND the JSON body contains all mandatory properties AND one or more of the properties contain a value that does not meet the requirements of the data type defined in the schema
WHENThe API request is sent
BUT
THENThe API stops with a 400 error and a message
Example Error Message`{“code”: 1010, “message”: “The JSON value could not be converted to System.DateTime. Path: $.payment.expiryDate
POST_007 - Maximum string length is exceeded
ElementDetails
Scenario IDPOST_007
Scenario NameMaximum string length is exceeded
HTTP Code422
GIVENA user is authorised AND the JSON body contains all mandatory properties AND one or more of the properties contain a value that exceeds the maximum length defined in the schema
WHENThe API request is sent
BUT
THENThe API stops with a 400 error and a message
Example Error Message"The field {0} must be a string or array type with a maximum length of {1}."
POST_008 - Duplicated customer
ElementDetails
Scenario IDPOST_008
Scenario NameDuplicated customer
HTTP Code400
GIVENA user is authorised AND the JSON body contains all mandatory properties AND all the properties meet the schema requirements AND the customer ID provided already exists in the system
WHENThe API request is sent
BUT
THENThe API stops with a 400 error and a message
Example Error Message"Your entry is not saved because meanwhile data has been changed by another user. Reload and try again."
POST_009 - Invalid authorisation
ElementDetails
Scenario IDPOST_009
Scenario NameInvalid authorisation
HTTP Code401
GIVENThe token provided does not pass authorisation
WHENThe API request is sent
BUT
THENThe API stops with a 401 error and a message
Example Error Message{"statusCode": 401, "message": "Invalid JWT."}
POST_010 - User is not authorised to access API
ElementDetails
Scenario IDPOST_010
Scenario NameUser is not authorised to access API
HTTP Code403
GIVENThe user is not authorised to access the API
WHENThe API request is sent
BUT
THENThe API stops with a 403 error and a message
Example Error Message{"code": 2030, "message": "User is not authorized"}
POST_011 - Missing general address
ElementDetails
Scenario IDPOST_011
Scenario NameMissing general address
HTTP Code400
GIVENA user is authorised AND the JSON body does not contain at least one contactPoint of the “General” type
WHENThe API request is sent
BUT
THENThe API stops with a 400 error and a message
Example Error Message{"code": 3010, "message": "General address has to be entered"}
POST_012 - Missing mandatory relation
ElementDetails
Scenario IDPOST_012
Scenario NameMissing mandatory relation
HTTP Code422
GIVENA user is authorised AND the JSON body does not contain a relation that is mandatory
WHENThe API request is sent
BUT
THENThe API stops with a 422 error and a message
Example Error Message{"code": 3010, "message": "Relation for attribute LEGALID is mandatory."}
POST_013 - Missing mandatory flexi-field values
ElementDetails
Scenario IDPOST_013
Scenario NameMissing mandatory flexi-field values
HTTP Code422
GIVENA user is authorised AND the JSON body does not contain a flexi-field value that is set as mandatory in the flexi-field group definition
WHENThe API request is sent
BUT
THENThe API stops with a 422 error and a message
Example Error Message"customFieldGroups": {"Test_value": {"n2_fx": "", "notificationMessages": {"n2_fx": [{"code": 3010, "message": "Please enter a value"}]}}}
POST_014 - Flexi-field value is not valid
ElementDetails
Scenario IDPOST_014
Scenario NameFlexi-field value is not valid
HTTP Code422
GIVENA user is authorised AND the JSON body contains a flexi-field value that is not permitted according to the flexi-field group definition
WHENThe API request is sent
BUT
THENThe API stops with a 422 error and a message
Example Error Message{"code": 3010, "message": "The value entered is not valid according to the restrictions for this field."}
POST_015 - Invalid JSON structure
ElementDetails
Scenario IDPOST_015
Scenario NameInvalid JSON structure
HTTP Code400
GIVENA user is authorised
WHENThe PATCH request body is malformed
BUT
THENThe API stops with a 400 error
Example Error Message

Sample Request

[
  {
    "path": "/payment/payMethod",
    "op": "Replace",
    "value": "SB"
  }
]
[
  {
  "path": "/contactPoints/-",
  "op": "Add",
  "value": { 
    "additionalContactInfo": {
      "contactPerson": "Add_Contact_1",
      "contactPosition": "Add_Position_1",
      "eMail": "Add_email_1@test.com",
      "eMailCc": "Add_emailcc_1@test.com",
      "gtin": "add_gtin_1",
      "url": "www.add_url_1_.com"
    },
    "address": {
      "countryCode": "GB",
      "place": "Add_Place_1",
      "postcode": "PST1",
      "province": "ADDPROV_1",
      "streetAddress": "add_street_address_1"
    },
    "contactPointType": "4",
    "phoneNumbers": {
      "telephone1": "+aaaaaa",
      "telephone2": "+bbbbbb",
      "telephone3": "+cccccc",
      "telephone4": "+dddddd",
      "telephone5": "+eeeeee",
      "telephone6": "+ffffff",
      "telephone7": "+gggggg"
      }
    }
  }
]
[
  {
  "path": "/contactPoints/1",
  "op": "Remove"
  }
]
[
  {
  "path": "/payment/payMethod",
  "op": "Replace",
  "value": "DD"
  },
  {
  "path": "invoice/currencyCode",
  "op": "Replace",
  "value": "NOK"
  },
  {
  "path": "/contactPoints/0/additionalContactInfo/contactPerson",
  "op": "Replace",
  "value": "Replaced_ContactPerson"
  },
  {
  "path": "/contactPoints/-",
  "op": "Add",
  "value": { 
    "additionalContactInfo": {
      "contactPerson": "Add_Contact_2",
      "contactPosition": "Add_Position_2",
      "eMail": "Add_email_1@test.com",
      "eMailCc": "Add_emailcc_2@test.com",
      "gtin": "add_gtin_2",
      "url": "www.add_url_2_.com"
    },
    "address": {
      "countryCode": "GB",
      "place": "Add_Place_2",
      "postcode": "PST2",
      "province": "ADDPROV_2",
      "streetAddress": "add_street_address_2"
    },
    "contactPointType": "4",
    "phoneNumbers": {
      "telephone1": "+aaaaaa",
      "telephone2": "+bbbbbb",
      "telephone3": "+cccccc",
      "telephone4": "+dddddd",
      "telephone5": "+eeeeee",
      "telephone6": "+ffffff",
      "telephone7": "+gggggg"
    }
  }
}
]
  

Limits & Notes

  • One customer per call.
  • Multiple patch operations may be made in a single request for that customer.
  • Patch operators available: Replace, Add, Remove
  • Supported operations: Update payment method, currency, contact information, addresses    

Validation Rules for PATCH Method – customerId

PATCH_001 - Invalid authorisation
ElementDetails
Scenario IDPATCH_001
Scenario NameInvalid authorisation
HTTP Code401
GIVENThe token provided does not pass authorisation
WHENThe API request is sent
BUT
THENThe API stops with a 401 error and a message
Example Error Message{"statusCode": 401, "message": "Invalid JWT."}
PATCH_002 - User is not authorised
ElementDetails
Scenario IDPATCH_002
Scenario NameUser is not authorised
HTTP Code403
GIVENA user is not authorised
WHENThe PATCH request is sent
BUT
THENThe API stops with a 403 error
Example Error Message{"code": 2030, "message": "User is not authorized"}
PATCH_003 - Invalid customerId
ElementDetails
Scenario IDPATCH_003
Scenario NameInvalid customerId
HTTP Code404
GIVENA user is authorised
WHENThe PATCH request is sent to a non-existent customerId
BUT
THENThe API stops with a 404 error
Example Error Message{"code": 1040, "message": "Customer with Id 11000999 was not found within company EN"}
PATCH_004 - Invalid JSON structure
ElementDetails
Scenario IDPATCH_004
Scenario NameInvalid JSON structure
HTTP Code400
GIVENA user is authorised
WHENThe PATCH request body is malformed
BUT
THENThe API stops with a 400 error
Example Error Message
PATCH_005 - Invalid path
ElementDetails
Scenario IDPATCH_005
Scenario NameInvalid path
HTTP Code400
GIVENA user is authorised
WHENThe PATCH request contains a path that is not supported
BUT
THENThe API stops with a 400 error and returns a message (content depends on the way the path is malformed)
Example Error Message{"code": 4020, "message": "PatchOperation index 0: Provided path \"/customFieldroups/mfa/name\" is invalid"} / {"code": 4023, "message": "PatchOperation index 0: Provided index (0) is out of range"} / {"code": 4020, "message": "PatchOperation index 0: _Path does not specify object member"}
PATCH_006 - Illegal value
ElementDetails
Scenario IDPATCH_006
Scenario NameIllegal value
HTTP Code422
GIVENA user is authorised
WHENThe PATCH request contains a valid path
BUTOne or more values are not permitted
THENThe API stops with a 422 error
Example Error Message{"code": 3010, "message": "Invalid payment method"}
PATCH_007 - Invalid format
ElementDetails
Scenario IDPATCH_007
Scenario NameInvalid format
HTTP Code400
GIVENA user is authorised
WHENThe PATCH request contains a valid path
BUTOne or more values do not meet the format requirements
THENThe API stops with a 400 error
Example Error Message{"code": 4030, "message": "PatchOperation index 0: Unable to convert value {0} to type 'System.Double' as an input value for the property {1}"}
PATCH_008 - Maximum string length is exceeded
ElementDetails
Scenario IDPATCH_008
Scenario NameMaximum string length is exceeded
HTTP Code422
GIVENA user is authorised AND the JSON body contains all mandatory properties AND one or more of the properties contain a value that exceeds the maximum length defined in the schema
WHENThe API request is sent
BUT
THENThe API stops with a 400 error and a message
Example Error Message"The field {0} must be a string or array type with a maximum length of {1}."
PATCH_009 - Illegal operation value
ElementDetails
Scenario IDPATCH_009
Scenario NameIllegal operation value
HTTP Code400
GIVENThe patch operation is not supported
WHENThe API request is sent
BUT
THENThe API stops with a 400 error and a message
Example Error Message`“The JSON value could not be converted to U4.PublicApiFramework.Core.JsonPatch.OperationType. Path: $[0].op

Sample Request

DELETE /v1/customers/11000002?companyId=EN

   

Limits & Notes

  • Only a single customer can be updated.
  • This endpoint does not delete the customer, but alters the status to “Closed”.
  • The operation may be undone with a Replace operation through the PATCH endpoint on the path “/payment/status”.
  • To fully delete the customer, you need to use the deletion routine “Delete customers and suppliers” available in the system administration menu.    

Validation Rules for DELETE Method

DEL_001 - Invalid authorisation
ElementDetails
Scenario IDDEL_001
Scenario NameInvalid authorisation
HTTP Code401
GIVENThe token provided does not pass authorisation
WHENThe API request is sent
BUT
THENThe API stops with a 401 error and a message
Example Error Message or Response{"statusCode": 401, "message": "Invalid JWT."}
DEL_002 - User is not authorised to access API
ElementDetails
Scenario IDDEL_002
Scenario NameUser is not authorised to access API
HTTP Code403
GIVENThe user is not authorised to access the API
WHENThe API request is sent
BUT
THENThe API stops with a 403 error and a message
Example Error Message or Response{"code": 2030, "message": "User is not authorized"}
DEL_003 - Customer does not exist
ElementDetails
Scenario IDDEL_003
Scenario NameCustomer does not exist
HTTP Code404
GIVENThe user provides a customerId which does not exist
WHENThe API request is sent
BUT
THENThe API stops with a 404 error and a message
Example Error Message or Response{"code": 1040, "message": "The entity of the following parameters [Company: EN, Customer: 213549674] was not found."}

Best Practices

  • The customers object API schema may differ from the POST/PATCH schema. Therefore, it is recommended to use the GET endpoint instead.
  • The DELETE endpoint does not physically delete customers but updates the status of the record. To ensure proper deletion, the deletion routine should be executed.
  • The customers API is designed for single-customer operations only. For batch functionality, refer to the Import Customers and Suppliers process.
  • Ensure integrations properly manage PATCH operations - always verify target values before and after the operation.
  • Use Swagger UI for testing and schema validation before production calls.
  • Handle error codes gracefully - implement retry/backoff logic in line with global rate limits.
  • Always check for deprecation alerts on the endpoint version in use.    

Action APIs


Query APIs (Read-Only)