Attribute Relations
The Attribute Relations API in Unit4 ERPx manages attribute relation data - creation, retrieval, updates, and deletion of attribute relationship records. It is designed for integration with mobile and other external applications, supporting microservice-based development, testing, and maintenance.
Purpose:
The Attribute Relations API manages all aspects of attribute relationship data, including creation, update, validation, and deletion. Attribute relations define how different attributes in ERPx are connected to each other, enabling complex master data hierarchies and dependencies between business entities.
Base URL:/v1/attribute-relations
Authentication:
All APIs require a Client ID and Client Secret.
Refer to the global authentication documentation for details.
System Parameters:
System parameters for attribute configuration are available in Online Help → Administration → Attributes → Fixed Registers → System Parameters.
Supported Methods
| HTTP Method | Endpoint | Description | Limits & Notes |
|---|---|---|---|
| POST | /v1/attribute-relations | Create a single attribute relation record | Only 1 attribute relation per call. Only attributes with manual maintenance. |
| GET | /v1/attribute-relations/{attributeId}/{attributeValue}/{relatedAttributeId}/{relationValue} | Retrieve single attribute relation data | Returns complete attribute relation information. All path parameters are mandatory. |
| GET | /v1/objects/attribute-relations | Retrieve multiple attribute relations | Returns array of attribute relations. Supports OData query options. Array of objects returned per call. |
| PATCH | /v1/attribute-relations/{attributeId}/{attributeValue}/{relatedAttributeId}/{relationValue} | Update attribute relation data | One attribute relation per call. Cannot update attributeValue field. |
| DELETE | /v1/attribute-relations/{attributeId}/{attributeValue}/{relatedAttributeId}/{relationValue} | Delete an attribute relation | One delete per call. Permanently removes the relation. |
| POST | /v1/batch/attribute-relations | Creates multiple attribute relations in a single batch request | Submits large volumes without waiting for full completion. Accepts a JSON file containing an array of attribute relations. Submit up to 5,000 attribute relations per batch request for best performance. |
Swagger / Schema
Version v1
Method Details
Sample Request
{
"attributeId": "C1",
"attributeValue": "100",
"relatedAttributeId": "C0",
"relationValue": "907",
"companyId": "EN",
"dateFrom": "1900-01-01T00:00:00.000Z",
"dateTo": "2099-12-31T00:00:00.000Z",
"percentage": 100
}
Limits and notes
Attribute Relation Prerequisites:
- Both attributeId and relatedAttributeId must exist in the ERPx client.
- Both attributeValue and relationValue must be valid values for their respective attributes.
- Attributes must have manual maintenance enabled.
- The relation between the two attributes must be configured in the ERPx client.
- Duplicates or overlapping relations are not allowed.
Validation Rules for POST Method
POST_001 - User is not authorised
| Element | Details |
|---|---|
| Scenario ID | POST_001 |
| Scenario Name | User is not authorised |
| HTTP Code | 403 |
| GIVEN | A new attribute relation needs to be created |
| WHEN | Calling the POST method of the API |
| BUT | User does NOT have permissions |
| THEN | API is not reached; 403 Forbidden response is returned |
| Example Error Message | “User is not authorised.” |
POST_002 - Unknown companyID
| Element | Details |
|---|---|
| Scenario ID | POST_002 |
| Scenario Name | Unknown companyID |
| HTTP Code | 403 |
| GIVEN | A new attribute relation needs to be created |
| WHEN | Calling the POST method of the API |
| BUT | companyID does not exist |
| THEN | API is not reached; 403 Forbidden response is returned |
| Example Error Message | “User is not authorised.” |
POST_003 - Attribute relation created
| Element | Details |
|---|---|
| Scenario ID | POST_003 |
| Scenario Name | Happy path attribute relation |
| HTTP Code | 201 |
| GIVEN | A new attribute relation needs to be created |
| WHEN | Calling the POST method of the API |
| BUT | — |
| THEN | 201 response is returned; attribute relation is created |
| Example Error Message | N/A |
POST_004 - Relations already exist
| Element | Details |
|---|---|
| Scenario ID | POST_004 |
| Scenario Name | Relations already exist and duplicates are not allowed |
| HTTP Code | 422 |
| GIVEN | A new attribute relation needs to be created |
| WHEN | Calling the POST method of the API |
| BUT | Relation already exists |
| THEN | 422 response is returned; relation is not created |
| Example Error Message | {"code": 3010, "message": "{0} : {1} is already connected to {2} : {3} on client {4}. Duplicates or overlaps are not allowed."} |
POST_005 - Invalid AttributeId
| Element | Details |
|---|---|
| Scenario ID | POST_005 |
| Scenario Name | Invalid AttributeId |
| HTTP Code | 422 |
| GIVEN | A new attribute relation needs to be created |
| WHEN | Calling the POST method of the API |
| BUT | attributeId does not exist |
| THEN | 422 response is returned; relation is not created |
| Example Error Message | {"code": 1040, "message": "The entity of the following parameters [Company : EN, Attribute ID : {0}, Attribute value : {1}] was not found."} |
POST_006 - Invalid attributeValue
| Element | Details |
|---|---|
| Scenario ID | POST_006 |
| Scenario Name | Invalid attributeValue |
| HTTP Code | 422 |
| GIVEN | A new attribute relation needs to be created |
| WHEN | Calling the POST method of the API |
| BUT | attributeValue does not exist |
| THEN | 422 response is returned; relation is not created |
| Example Error Message | {"code": 1040, "message": "The entity of the following parameters [Company : {0}, Attribute ID : {1}, Attribute value : {2}] was not found."} |
POST_007 - Invalid relatedAttributeId
| Element | Details |
|---|---|
| Scenario ID | POST_007 |
| Scenario Name | Invalid relatedAttributeId |
| HTTP Code | 422 |
| GIVEN | A new attribute relation needs to be created |
| WHEN | Calling the POST method of the API |
| BUT | relatedAttributeId does not exist |
| THEN | 422 response is returned; relation is not created |
| Example Error Message | {"code": 3010, "message": "Illegal value entered"} |
POST_008 - Invalid relationValue
| Element | Details |
|---|---|
| Scenario ID | POST_008 |
| Scenario Name | Invalid relationValue |
| HTTP Code | 422 |
| GIVEN | A new attribute relation needs to be created |
| WHEN | Calling the POST method of the API |
| BUT | relationValue does not exist |
| THEN | 422 response is returned; relation is not created |
| Example Error Message | "relationValue": [{"code": 3010, "message": "{0} is not a legal {1}"}] |
Sample Request
GET /v1/attribute-relations/C1/100/C0/907?companyId=ENSample Response
{
"attributeId": "C1",
"attributeName": "Cost Center",
"attributeValue": "100",
"relatedAttributeId": "C0",
"relatedAttributeName": "Department",
"relationValue": "907",
"companyId": "EN",
"dateFrom": "1900-01-01T00:00:00.000Z",
"dateTo": "2099-12-31T00:00:00.000Z",
"percentage": 100
}
Path Parameters
The following parameters are required in the URL path:
| Parameter | Value | Description | Data Type | Required |
|---|---|---|---|---|
| attributeId | required | Valid attribute ID (e.g., C0, C1, C2) | string | yes |
| attributeValue | required | Valid value of attribute | string | yes |
| relatedAttributeId | required | Valid related attribute ID (e.g., C0, C1, C2) | string | yes |
| relationValue | required | Valid value of related attribute | string | yes |
Additional Parameters
| Parameter | Value | Description | Data Type | Default Value |
|---|---|---|---|---|
| companyId | optional | Specify if you wish to retrieve an attribute relation that exists in a specific company or client. | string | empty |
Limits & Notes
- Only one attribute relation per call.
- All path parameters are mandatory.
- Returns complete attribute relation information.
Validation Rules for GET Method (Single Relation)
GET_001 - User is not authorised
| Element | Details |
|---|---|
| Scenario ID | GET_001 |
| Scenario Name | User is not authorised |
| HTTP Code | 403 |
| GIVEN | Attribute relations need to be retrieved |
| WHEN | Calling the GET method of the API |
| BUT | User does NOT have permissions |
| THEN | API is not reached; 403 Forbidden response is returned |
| Example Error Message | “User is not authorised.” |
GET_002 - Unknown companyID
| Element | Details |
|---|---|
| Scenario ID | GET_002 |
| Scenario Name | Unknown companyID |
| HTTP Code | 403 |
| GIVEN | Attribute relations need to be retrieved |
| WHEN | Calling the GET method of the API |
| BUT | companyID does not exist |
| THEN | API is not reached; 403 Forbidden response is returned |
| Example Error Message | “User is not authorised.” |
GET_003 - attributeId does not exist
| Element | Details |
|---|---|
| Scenario ID | GET_003 |
| Scenario Name | attributeId does not exist |
| HTTP Code | 404 |
| GIVEN | Attribute relations need to be retrieved |
| WHEN | Calling the GET method of the API |
| BUT | attributeId does not exist for the companyId |
| THEN | Attribute relations are not retrieved; 404 response is returned |
| Example Error Message | {"code": 1040, "message": "The entity of the following parameters [Company : {0}, Attribute ID : {1}, Attribute value : {2}, Related attribute ID : {3}, Relation value : {4}] was not found."} |
GET_004 - attributeValue is not valid
| Element | Details |
|---|---|
| Scenario ID | GET_004 |
| Scenario Name | attributeValue is not a valid value of attribute |
| HTTP Code | 404 |
| GIVEN | Attribute relations need to be retrieved |
| WHEN | Calling the GET method of the API |
| BUT | attributeValue does not exist |
| THEN | Attribute relations are not retrieved; 404 response is returned |
| Example Error Message | {"code": 1040, "message": "The entity of the following parameters [Company : {0}, Attribute ID : {1}, Attribute value : {2}, Related attribute ID : {3}, Relation value : {4}] was not found."} |
GET_005 - relatedAttributeId does not exist
| Element | Details |
|---|---|
| Scenario ID | GET_005 |
| Scenario Name | relatedAttributeId does not exist |
| HTTP Code | 404 |
| GIVEN | Attribute relations need to be retrieved |
| WHEN | Calling the GET method of the API |
| BUT | relatedAttributeId does not exist |
| THEN | Attribute relations are not retrieved; 404 response is returned |
| Example Error Message | {"code": 1040, "message": "The entity of the following parameters [Company : {0}, Attribute ID : {1}, Attribute value : {2}, Related attribute ID : {3}, Relation value : {4}] was not found."} |
GET_006 - relationValue is not valid
| Element | Details |
|---|---|
| Scenario ID | GET_006 |
| Scenario Name | relationValue is not a valid value of attribute |
| HTTP Code | 404 |
| GIVEN | Attribute relations need to be retrieved |
| WHEN | Calling the GET method of the API |
| BUT | relationValue does not exist |
| THEN | Attribute relations are not retrieved; 404 response is returned |
| Example Error Message | {"code": 1040, "message": "The entity of the following parameters [Company : {0}, Attribute ID : {1}, Attribute value : {2}, Related attribute ID : {3}, Relation value : {4}] was not found."} |
GET_007 - Attribute relations get happy path
| Element | Details |
|---|---|
| Scenario ID | GET_007 |
| Scenario Name | Attribute relations get happy path |
| HTTP Code | 200 |
| GIVEN | Attribute relations need to be retrieved |
| WHEN | Calling the GET method of the API |
| BUT | — |
| THEN | 200 attribute relation object is retrieved |
| Example Error Message | N/A |
Sample Request
{
GET /v1/objects/attribute-relations?filter=attributeId%20eq%20%27C1%27&limit=10
}{
GET /v1/objects/attribute-relations?filter=attributeId%20eq%20%27C1%27%20and%20relatedAttributeId%20eq%20%27C0%27&limit=10
}Sample Response
[
{
"attributeId": "C1",
"attributeName": "Cost Center",
"attributeValue": "100",
"attributeValueFrom": 0,
"attributeValueTo": 209999,
"relatedAttributeId": "C0",
"relatedAttributeName": "Department",
"relationValue": "907",
"companyId": "EN",
"dateFrom": "1900-01-01T00:00:00.000Z",
"dateTo": "2099-12-31T00:00:00.000Z",
"percentage": 100
},
{
"attributeId": "C1",
"attributeName": "Cost Center",
"attributeValue": "120",
"attributeValueFrom": 0,
"attributeValueTo": 209999,
"relatedAttributeId": "C0",
"relatedAttributeName": "Department",
"relationValue": "908",
"companyId": "EN",
"dateFrom": "1900-01-01T00:00:00.000Z",
"dateTo": "2099-12-31T00:00:00.000Z",
"percentage": 100
}
]
Additional Parameters
The following OData query parameters help filter and shape the response:
| Parameter | Value | Description | Data Type | Default Value |
|---|---|---|---|---|
| companyId | optional | Specify if you wish to retrieve attribute relations that exist in a specific company or client. | string | empty |
| $select | optional | Properties to include in the response (comma-separated). | string | all properties |
| $filter | optional | OData boolean expression to select matching records. Supports: eq, ne, gt, ge, lt, le, and, or, not. | string | none |
| $orderby | optional | Sort order of results. Format: property [asc|desc], multiple values separated by commas. | string | none |
| $offset (skip) | optional | Number of items to skip before returning results. | integer | 0 |
| $limit (top) | optional | Maximum number of items to return. | integer | system default |
Limits & Notes
- Array of objects returned per call.
- Supports OData query syntax for filtering and sorting.
- Returns only simple attribute relation objects with no additional data.
Validation Rules for GET Method (Objects)
GET_001 - User is not authorised
| Element | Details |
|---|---|
| Scenario ID | GET_001 |
| Scenario Name | User is not authorised |
| HTTP Code | 403 |
| GIVEN | Attribute relations need to be retrieved |
| WHEN | Calling the GET method of the API |
| BUT | User does NOT have permissions |
| THEN | API is not reached; 403 Forbidden response is returned |
| Example Error Message | “User is not authorised.” |
GET_002 - Unknown companyID
| Element | Details |
|---|---|
| Scenario ID | GET_002 |
| Scenario Name | Unknown companyID |
| HTTP Code | 403 |
| GIVEN | Attribute relations need to be retrieved |
| WHEN | Calling the GET method of the API |
| BUT | companyID does not exist |
| THEN | API is not reached; 403 Forbidden response is returned |
| Example Error Message | “User is not authorised.” |
GET_003 - Happy path - no params
| Element | Details |
|---|---|
| Scenario ID | GET_003 |
| Scenario Name | Happy path - no params |
| HTTP Code | 200 |
| GIVEN | Attribute relations need to be retrieved |
| WHEN | Calling the GET method of the API |
| BUT | — |
| THEN | A 200 OK Array with objects is returned |
| Example Error Message | RESPONSE: Check sample response |
GET_004 - Limit results
| Element | Details |
|---|---|
| Scenario ID | GET_004 |
| Scenario Name | Limit results |
| HTTP Code | 200 |
| GIVEN | Attribute relations need to be retrieved |
| WHEN | Calling the GET method of the API with limit=10 |
| BUT | — |
| THEN | A 200 OK Array with ≤ 10 items is returned |
| Example Error Message | RESPONSE: Check sample response |
GET_005 - Limit equal to 0
| Element | Details |
|---|---|
| Scenario ID | GET_005 |
| Scenario Name | Limit equal to 0 |
| HTTP Code | 400 |
| GIVEN | Attribute relations need to be retrieved |
| WHEN | Calling the GET method of the API with limit=0 |
| BUT | — |
| THEN | 400 No data response is retrieved |
| Example Error Message | {"code": 1020, "message": "Limit is invalid. Value should be greater than 0."} |
GET_006 - Limit has a negative value
| Element | Details |
|---|---|
| Scenario ID | GET_006 |
| Scenario Name | Limit has a negative value |
| HTTP Code | 400 |
| GIVEN | Attribute relations need to be retrieved |
| WHEN | Calling the GET method of the API with limit=-5 |
| BUT | — |
| THEN | 400 No data response is retrieved |
| Example Error Message | {"code": 1020, "message": "Limit is invalid. Value should be greater than 0."} |
GET_007 - Limit exceeds int32
| Element | Details |
|---|---|
| Scenario ID | GET_007 |
| Scenario Name | Limit has a bigger value than int32 |
| HTTP Code | 400 |
| GIVEN | Attribute relations need to be retrieved |
| WHEN | Calling the GET method of the API with limit = 9999999999 |
| BUT | — |
| THEN | 400 No data response is retrieved |
| Example Error Message | {"code": 1010, "message": "The value '9999999999' is not valid.\n"} |
GET_008 - Negative Offset
| Element | Details |
|---|---|
| Scenario ID | GET_008 |
| Scenario Name | Negative Offset |
| HTTP Code | 400 |
| GIVEN | Attribute relations need to be retrieved |
| WHEN | Calling the GET method of the API with offset=-100 |
| BUT | — |
| THEN | 400 No data response is retrieved |
| Example Error Message | {"code": 1020, "message": "Offset is invalid. Value should be greater than or equal to 0."} |
GET_009 - Offset exceeds int32
| Element | Details |
|---|---|
| Scenario ID | GET_009 |
| Scenario Name | Offset has a bigger value than int32 |
| HTTP Code | 400 |
| GIVEN | Attribute relations need to be retrieved |
| WHEN | Calling the GET method of the API with offset = 9999999999 |
| BUT | — |
| THEN | 400 No data response is retrieved |
| Example Error Message | {"code": 1010, "message": "The value '9999999999' is not valid.\n"} |
GET_010 - Select returns only requested fields
| Element | Details |
|---|---|
| Scenario ID | GET_010 |
| Scenario Name | Select returns only requested fields |
| HTTP Code | 200 |
| GIVEN | Attribute relations need to be retrieved |
| WHEN | Calling the GET method of the API with select attributeId, attributeName |
| BUT | — |
| THEN | A 200 OK Array with objects is returned; response contains only selected fields |
| Example Error Message | N/A |
GET_011 - Filter returns only expected data
| Element | Details |
|---|---|
| Scenario ID | GET_011 |
| Scenario Name | Filter returns only expected data |
| HTTP Code | 200 |
| GIVEN | Attribute relations need to be retrieved |
| WHEN | Calling the GET method of the API with filter attributeId eq ‘C1’ |
| BUT | — |
| THEN | A 200 OK Array with objects is returned, but only with attributeId field equal C1 |
| Example Error Message | RESPONSE: Check sample response |
GET_012 - OrderBy sorts data ascending
| Element | Details |
|---|---|
| Scenario ID | GET_012 |
| Scenario Name | OrderBy sorts data in an ascending order by attributeValueTo |
| HTTP Code | 200 |
| GIVEN | Attribute relations need to be retrieved |
| WHEN | Calling the GET method of the API with orderby=attributeValueTo |
| BUT | — |
| THEN | A 200 OK The response body is a JSON array sorted by attributeValueTo in ascending order |
| Example Error Message | RESPONSE: Check sample response |
GET_013 - OrderBy sorts data descending
| Element | Details |
|---|---|
| Scenario ID | GET_013 |
| Scenario Name | OrderBy sorts data in a descending order by attributeValueTo |
| HTTP Code | 200 |
| GIVEN | Attribute relations need to be retrieved |
| WHEN | Calling the GET method of the API with orderby=attributeValueTo desc |
| BUT | — |
| THEN | A 200 OK The response body is a JSON array sorted by attributeValueTo in descending order |
| Example Error Message | RESPONSE: Check sample response |
Sample Request
[
{
"path": "/percentage",
"op": "replace",
"value": 50
}
][
{
"path": "/dateTo",
"op": "replace",
"value": "2025-12-31T00:00:00.000Z"
}
][
{
"path": "/relationValue",
"op": "replace",
"value": "908"
}
]Path Parameters
The following parameters are required in the URL path:
| Parameter | Value | Description | Data Type | Required |
|---|---|---|---|---|
| attributeId | required | Valid attribute ID (e.g., C0, C1, C2) | string | yes |
| attributeValue | required | Valid value of attribute | string | yes |
| relatedAttributeId | required | Valid related attribute ID (e.g., C0, C1, C2) | string | yes |
| relationValue | required | Valid value of related attribute | string | yes |
Additional Parameters
| Parameter | Value | Description | Data Type | Default Value |
|---|---|---|---|---|
| companyId | optional | Specify if you wish to update an attribute relation that exists in a specific company or client. | string | empty |
Limits & Notes
- One attribute relation per call.
- Cannot update attributeValue field - this is a key field.
- Patch operators available:
replace
Validation Rules for PATCH Method
PATCH_001 - User is not authorised
| Element | Details |
|---|---|
| Scenario ID | PATCH_001 |
| Scenario Name | User is not authorised |
| HTTP Code | 403 |
| GIVEN | User needs to modify the existing attribute relation |
| WHEN | Calling the PATCH method of the API |
| BUT | User does NOT have permissions |
| THEN | API is not reached; 403 response is returned |
| Example Error Message | “User is not authorised.” |
PATCH_002 - Missing mandatory fields
| Element | Details |
|---|---|
| Scenario ID | PATCH_002 |
| Scenario Name | Missing mandatory fields |
| HTTP Code | 422 |
| GIVEN | User needs to modify the existing attribute relation |
| WHEN | Calling the PATCH method of the API |
| BUT | Mandatory field is missing |
| THEN | Data is not updated; 422 response is returned |
| Example Error Message | “The {0} field is required.” |
PATCH_003 - Unknown companyID
| Element | Details |
|---|---|
| Scenario ID | PATCH_003 |
| Scenario Name | Unknown companyID |
| HTTP Code | 422 |
| GIVEN | User needs to modify the existing attribute relation |
| WHEN | Calling the PATCH method of the API |
| BUT | Invalid companyID |
| THEN | Data is not updated; 422 response is returned |
| Example Error Message | “Unknown {0}.” |
PATCH_004 - AttributeId does not exist
| Element | Details |
|---|---|
| Scenario ID | PATCH_004 |
| Scenario Name | Attribute Id does not exist |
| HTTP Code | 404 |
| GIVEN | User needs to modify the existing attribute relation |
| WHEN | Calling the PATCH method of the API |
| BUT | AttributeId does not exist |
| THEN | Data is not updated; 404 response is returned |
| Example Error Message | {"code": 1040, "message": "Attribute relation where attributeId = {0}, attributeValue = {1}, relatedAttributeId = {2}, relationValue = {3} was not found."} |
PATCH_005 - Attribute Value does not exist
| Element | Details |
|---|---|
| Scenario ID | PATCH_005 |
| Scenario Name | attributeValue does not exist |
| HTTP Code | 404 |
| GIVEN | User needs to modify the existing attribute relation |
| WHEN | Calling the PATCH method of the API |
| BUT | attributeValue does not exist |
| THEN | Data is not updated; 404 response is returned |
| Example Error Message | {"code": 1040, "message": "Attribute relation where attributeId = {0}, attributeValue = {1}, relatedAttributeId = {2}, relationValue = {3} was not found."} |
PATCH_006 - Related Attribute Id does not exist
| Element | Details |
|---|---|
| Scenario ID | PATCH_006 |
| Scenario Name | relatedAttributeId does not exist |
| HTTP Code | 404 |
| GIVEN | User needs to modify the existing attribute relation |
| WHEN | Calling the PATCH method of the API |
| BUT | relatedAttributeId does not exist |
| THEN | Data is not updated; 404 response is returned |
| Example Error Message | {"code": 1040, "message": "Attribute relation where attributeId = {0}, attributeValue = {1}, relatedAttributeId = {2}, relationValue = {3} was not found."} |
PATCH_007 - Relation Value does not exist
| Element | Details |
|---|---|
| Scenario ID | PATCH_007 |
| Scenario Name | relationValue does not exist |
| HTTP Code | 404 |
| GIVEN | User needs to modify the existing attribute relation |
| WHEN | Calling the PATCH method of the API |
| BUT | relationValue does not exist |
| THEN | Data is not updated; 404 response is returned |
| Example Error Message | {"code": 1040, "message": "Attribute relation where attributeId = {0}, attributeValue = {1}, relatedAttributeId = {2}, relationValue = {3} was not found."} |
PATCH_008 - Invalid path
| Element | Details |
|---|---|
| Scenario ID | PATCH_008 |
| Scenario Name | Invalid path |
| HTTP Code | 422 |
| GIVEN | User needs to modify the existing attribute relation |
| WHEN | Calling the PATCH method of the API with Value path |
| BUT | Path is not correct for attribute relation |
| THEN | Data is not updated; 422 response is returned |
| Example Error Message | {"code": 4020, "message": "PatchOperation index 0: Provided path \" Value \" is invalid"} |
PATCH_009 - Invalid value for relation value
| Element | Details |
|---|---|
| Scenario ID | PATCH_009 |
| Scenario Name | Invalid value for relationValue |
| HTTP Code | 422 |
| GIVEN | User needs to modify the existing attribute relation |
| WHEN | Calling the PATCH method of the API with new value for “relationValue” |
| BUT | Value is not correct for field “relationValue” |
| THEN | Data is not updated; 422 response is returned |
| Example Error Message | "relationValue": [{"code": 3010, "message": "222 is not a legal ECMYEAR"}] |
PATCH_010 - Cannot update attribute value
| Element | Details |
|---|---|
| Scenario ID | PATCH_010 |
| Scenario Name | Cannot update attributeValue |
| HTTP Code | 422 |
| GIVEN | User needs to modify the existing attribute relation |
| WHEN | Calling the PATCH method of the API with new value for “attributeValue” |
| BUT | Change for attributeValue is not allowed |
| THEN | Data is not updated; 422 response is returned |
| Example Error Message | {"code": 3010, "message": "Data was rejected because of errors which were detected during saving."} |
Sample Request
DELETE /v1/attribute-relations/C1/100/C0/907?companyId=EN
Path Parameters
The following parameters are required in the URL path:
| Parameter | Value | Description | Data Type | Required |
|---|---|---|---|---|
| attributeId | required | Valid attribute ID (e.g., C0, C1, C2) | string | yes |
| attributeValue | required | Valid value of attribute | string | yes |
| relatedAttributeId | required | Valid related attribute ID (e.g., C0, C1, C2) | string | yes |
| relationValue | required | Valid value of related attribute | string | yes |
Additional Parameters
| Parameter | Value | Description | Data Type | Default Value |
|---|---|---|---|---|
| companyId | optional | Specify if you wish to delete an attribute relation that exists in a specific company or client. | string | empty |
Limits & Notes
- One delete per call.
- Permanently removes the attribute relation.
- Cannot be undone - this is not a soft delete.
Validation Rules for DELETE Method
DEL_001 - User is not authorised
| Element | Details |
|---|---|
| Scenario ID | DEL_001 |
| Scenario Name | User is not authorised |
| HTTP Code | 403 |
| GIVEN | Attribute relations need to be deleted |
| WHEN | Calling the DELETE method of the API |
| BUT | User does NOT have permissions |
| THEN | API is not reached; 403 Forbidden response is returned |
| Example Error Message or Response | “User is not authorised.” |
DEL_002 - Unknown companyID
| Element | Details |
|---|---|
| Scenario ID | DEL_002 |
| Scenario Name | Unknown companyID |
| HTTP Code | 403 |
| GIVEN | Attribute relations need to be deleted |
| WHEN | Calling the DELETE method of the API |
| BUT | companyID does not exist |
| THEN | API is not reached; 403 Forbidden response is returned |
| Example Error Message or Response | “User is not authorised.” |
DEL_003 - attributeId does not exist
| Element | Details |
|---|---|
| Scenario ID | DEL_003 |
| Scenario Name | attributeId does not exist |
| HTTP Code | 404 |
| GIVEN | Attribute relations need to be deleted |
| WHEN | Calling the DELETE method of the API |
| BUT | attributeId does not exist for the companyId |
| THEN | Attribute relations are not deleted; 404 response is returned |
| Example Error Message or Response | {"code": 1040, "message": "Attribute relation where attributeId = {0}, attributeValue = {1}, relatedAttributeId = {2}, relationValue = {3} was not found."} |
DEL_004 - attributeValue does not exist
| Element | Details |
|---|---|
| Scenario ID | DEL_004 |
| Scenario Name | attributeValue does not exist |
| HTTP Code | 404 |
| GIVEN | Attribute relations need to be deleted |
| WHEN | Calling the DELETE method of the API |
| BUT | attributeValue does not exist |
| THEN | Attribute relations are not deleted; 404 response is returned |
| Example Error Message or Response | {"code": 1040, "message": "Attribute relation where attributeId = {0}, attributeValue = {1}, relatedAttributeId = {2}, relationValue = {3} was not found."} |
DEL_005 - relatedAttributeId does not exist
| Element | Details |
|---|---|
| Scenario ID | DEL_005 |
| Scenario Name | relatedAttributeId does not exist |
| HTTP Code | 404 |
| GIVEN | Attribute relations need to be deleted |
| WHEN | Calling the DELETE method of the API |
| BUT | relatedAttributeId does not exist |
| THEN | Attribute relations are not deleted; 404 response is returned |
| Example Error Message or Response | {"code": 1040, "message": "Attribute relation where attributeId = {0}, attributeValue = {1}, relatedAttributeId = {2}, relationValue = {3} was not found."} |
DEL_006 - relationValue does not exist
| Element | Details |
|---|---|
| Scenario ID | DEL_006 |
| Scenario Name | relationValue does not exist |
| HTTP Code | 404 |
| GIVEN | Attribute relations need to be deleted |
| WHEN | Calling the DELETE method of the API |
| BUT | relationValue does not exist |
| THEN | Attribute relations are not deleted; 404 response is returned |
| Example Error Message or Response | {"code": 1040, "message": "Attribute relation where attributeId = {0}, attributeValue = {1}, relatedAttributeId = {2}, relationValue = {3} was not found."} |
Sample Request
[
{
"attributeName": "MGA81",
"attributeId": "M81",
"attributeValue": "M81_004001",
"companyId": "EN",
"percent": 100,
"relatedAttributeName": "MGA82",
"relatedAttributeId": "M82",
"relationValue": "M82_004001",
"relationValueStatus": "N"
},
{
"attributeName": "MGA81",
"attributeId": "M81",
"attributeValue": "M81_004002",
"companyId": "EN",
"percent": 100,
"relatedAttributeName": "MGA82",
"relatedAttributeId": "M82",
"relationValue": "M82_004002",
"relationValueStatus": "N"
},
{
"attributeName": "MGA81",
"attributeId": "M81",
"attributeValue": "M81_004003",
"companyId": "EN",
"percent": 100,
"relatedAttributeName": "MGA82",
"relatedAttributeId": "M82",
"relationValue": "M82_004003",
"relationValueStatus": "N"
},
{
"attributeName": "MGA81",
"attributeId": "M81",
"attributeValue": "M81_004004",
"companyId": "EN",
"percent": 100,
"relatedAttributeName": "MGA82",
"relatedAttributeId": "M82",
"relationValue": "M82_004004",
"relationValueStatus": "N"
},
{
"attributeName": "MGA81",
"attributeId": "M81",
"attributeValue": "M81_004005",
"companyId": "EN",
"percent": 100,
"relatedAttributeName": "MGA82",
"relatedAttributeId": "M82",
"relationValue": "M82_004005",
"relationValueStatus": "N"
},
{
"attributeName": "MGA81",
"attributeId": "M81",
"attributeValue": "M81_004006",
"companyId": "EN",
"percent": 100,
"relatedAttributeName": "MGA82",
"relatedAttributeId": "M82",
"relationValue": "M82_004006",
"relationValueStatus": "N"
},
{
"attributeName": "MGA81",
"attributeId": "M81",
"attributeValue": "M81_004007",
"companyId": "EN",
"percent": 100,
"relatedAttributeName": "MGA82",
"relatedAttributeId": "M82",
"relationValue": "M82_004007",
"relationValueStatus": "N"
},
{
"attributeName": "MGA81",
"attributeId": "M81",
"attributeValue": "M81_004008",
"companyId": "EN",
"percent": 100,
"relatedAttributeName": "MGA82",
"relatedAttributeId": "M82",
"relationValue": "M82_004008",
"relationValueStatus": "N"
},
{
"attributeName": "MGA81",
"attributeId": "M81",
"attributeValue": "M81_004009",
"companyId": "EN",
"percent": 100,
"relatedAttributeName": "MGA82",
"relatedAttributeId": "M82",
"relationValue": "M82_004009",
"relationValueStatus": "N"
},
{
"attributeName": "MGA81",
"attributeId": "M81",
"attributeValue": "M81_004010",
"companyId": "EN",
"percent": 100,
"relatedAttributeName": "MGA82",
"relatedAttributeId": "M82",
"relationValue": "M82_004010",
"relationValueStatus": "N"
}
]
Limits & Notes
Request Format:
- Submit a JSON file (not a JSON object) containing an array of attribute relations
- File format follows the POST /v1/attribute-relations schema
- GZIP compression supported for files exceeding batch framework upload limits
- Maximum recommended: 5,000 relations per request; split larger batches
Processing:
- Asynchronous processing: returns immediately with 201 Created
- Batch tracking link provided in response header (
locationproperty) - Use Batch Operations API to monitor status and retrieve results
Prerequisites:
- Both attributeId and relatedAttributeId must exist in ERPx
- Both attributeValue and relationValue must be valid for their attributes
- Attributes must have manual maintenance enabled
- Relation must be configured in ERPx client
- Duplicates or overlapping relations are not allowed
Tracking Batch Operations:
- GET /v1/batch-operations/{batchRequestId}/status — check batch status (pending, in-progress, completed, failed)
- GET /v1/batch-operations/{batchRequestId}/results — retrieve failed items; add
type=successparameter for successful creations summary - POST /v1/batch-operations/{batchRequestId}/cancel — cancel running batch process
Validation Rules for POST Method
POST_001 - User is not authorised
| Element | Details |
|---|---|
| Scenario ID | POST_001 |
| Scenario Name | User is not authorised |
| HTTP Code | 401 |
| GIVEN | A batch of new attribute relation needs to be created |
| WHEN | Calling the POST method of the API |
| BUT | User does NOT have permissions |
| THEN | API is not reached; 401 Forbidden response is returned |
| Example Error Message or Response | “User is not authorised.” |
POST_002 - File not sent with the request
| Element | Details |
|---|---|
| Scenario ID | POST_002 |
| Scenario Name | File not sent with the request |
| HTTP Code | 400 |
| GIVEN | A batch of new sales orders needs to be created |
| WHEN | Calling the POST batch method of the API |
| BUT | User has not attached the JSON file into the call |
| THEN | API is not reached; 400 Bad Request response is returned |
| Example Error Message or Response | “File not present in MIME multipart content.” |
POST_003 - Happy Path - all attribute relations are created
| Element | Details |
|---|---|
| Scenario ID | POST_003 |
| Scenario Name | Happy Path - all attribute relations are created |
| HTTP Code | 201 |
| GIVEN | A batch of new attribute relations needs to be created |
| WHEN | Calling the POST batch method of the API |
| THEN | 201 Created response is returned with a link to track the batch operation (Batch tracking link in location response header). |
| Example Error Message or Response | “—” |
POST_004 - Partial success - some attribute relations are invalid
| Element | Details |
|---|---|
| Scenario ID | POST_004 |
| Scenario Name | Partial success - some attribute relations are invalid |
| HTTP Code | 201 |
| GIVEN | A batch of new attribute relations needs to be created |
| WHEN | Calling the POST batch method of the API |
| BUT | One or more attribute relations in the file contain validation errors (e.g., invalid attributeId, invalid attributeValue, invalid relatedAttributeId, invalid relationValue) |
| THEN | 201 Created response is returned (See Batch Operations results for individual error details per relation). |
| Example Error Message or Response | “—” |
POST_005 - Duplicate attribute relations
| Element | Details |
|---|---|
| Scenario ID | POST_005 |
| Scenario Name | Duplicate attribute relations |
| HTTP Code | 201 |
| GIVEN | A batch of new attribute relations needs to be created |
| WHEN | Calling the POST batch method of the API |
| BUT | One or more attribute relations already exists in the system |
| THEN | 201 Created response is returned (Duplicate relations reported in Batch Operations results). |
| Example Error Message or Response | “Duplicates or overlaps are not allowed.” |
Best Practices
- Verify attribute relations exist in the ERPx configuration before attempting to create attribute relations via API.
- Validate both attribute IDs and their values before creating relations - both the source and target attributes must exist.
- Check for existing relations before creating new ones to avoid duplicate errors.
- Cannot update key fields - attributeValue is a key field and cannot be modified via PATCH. Delete and recreate the relation if key values need to change.
- Understand deletion is permanent - DELETE permanently removes the relation (not a soft delete like some other APIs).
- Use the Objects endpoint (
/v1/objects/attribute-relations) for bulk queries and filtering with OData syntax. - Leverage OData filters to efficiently retrieve specific relations without fetching all data.
- Test limit and offset parameters to optimize performance when working with large datasets.
- Use Swagger UI for testing and schema validation before production calls.
- Handle error codes gracefully - implement retry/backoff logic according to global rate limits.
- Always check for deprecation alerts on this endpoint version.
- Validate attribute relation before sending DELETE requests to avoid unintentional data loss.