# Custom Entities

## Filter Custom Entities

 - [GET /CustomEntities('{customEntityDenominator}')](https://docs.api.saleslayer.com/apis/catalog-v2.0/custom-entities/filtercustomentitiesasync.md): Filters the items of a Custom Entity type, identified by its denominator, returning the
matching resources as a collection. Supports OData query options for selecting, expanding,
filtering, ordering and paging the results.
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Headers
### Accept-Language
            
Indicates the preferred natural language and locale for the localized content:
- culture-code (e.g. es, en-us) — returns content localized in the specified culture.
- null / not set — returns content localized in the default culture.
- * — currently disabled.
            
Multiple culture codes or q-factor weighting are not supported.
            
## OData Query Support
            
The endpoint supports a subset of OData v4.01 URI conventions.
The full list of available properties can be obtained from GET /CustomEntities('{denominator}')/$metadata.
            
### $select
Comma-separated list of Custom Entity properties (implicit or custom) to include in the result.
Selection of properties inside embedded resources/collections is not supported.
- Example: abcd_description
- Example: abcd_description,abcd_tags
            
### $expand
Comma-separated list of embedded collections to include in the result (when applicable). By default, embedded collections are not included.
Only embedded collections are supported (not embedded resources).
            
### $filter
Boolean expression applied on root resource properties. Filtering on nested resource properties is not supported.
- Logical operators: eq, ne, gt, lt, ge, le, or, and, in
- String functions: contains, startswith, endswith
- Supported value types: integer, big integer, double, decimal, string, date, datetimeoffset
            
### $orderby
Sorting expression on a single root resource property. Multiple properties and embedded properties are not supported.
Format: PROPERTY (asc|desc). Default direction is asc.
- Example: abcd_description asc
            
### $top
Page size. Maximum and default is 100 items.
            
### $skip
Offset for the limit-and-offset paging strategy (used together with $top). Recommended when $orderby is required.
            
### $skipToken
Continuation token for the continuation-token paging strategy. Faster than limit-and-offset but does not support $orderby.
            
## Response
            
200 OK — Returns a CollectionRepresentation with the matching Custom Entity resources.
            
## Error Responses
            
- 400 Bad Request — Invalid OData expression or query parameter.
- 401 Unauthorized — Missing or invalid API key. Returned by the API gateway as
  { "message": "Unauthorized", "request_id": "d8aafa5b8f3e400b60bea0123dd33317" }.
- 404 Not Found — Tenant or Custom Entity not found.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
GET /CustomEntities('Brand')?$select=abcd_description&$top=10 HTTP/1.1
X-API-KEY: your-api-key-here
Accept-Language: es

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

## Create Custom Entity

 - [POST /CustomEntities('{customEntityDenominator}')](https://docs.api.saleslayer.com/apis/catalog-v2.0/custom-entities/createcustomentityasync.md): Creates a new item for a Custom Entity type, identified by its denominator, from the supplied
JSON object. On success returns 201 Created with the new resource location in the Location header.
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Headers
            
### Accept-Language
            
Culture used to interpret the localized field values supplied in the request body.
- omitted / null: tenant's default culture.
- culture-code (e.g. en-US, es): the specified culture.
            
## Request Body
            
A single JSON object whose properties match the writable fields published by
/CustomEntities('{denominator}')/$metadata. The body is normalized before reaching the
application layer:
            
- Must be a non-empty JSON object.
- A JSON array is accepted only if it contains exactly one element.
- Values are coerced to CLR primitives (string, long, double, bool, null),
  nested objects and arrays.
            
## Response
            
201 Created — The Location header points to the new resource:
/CustomEntities('{denominator}')/Item({id}). No response body.
            
## Error Responses
            
- 400 Bad Request — Payload normalization or validation failure (empty body,
  multi-element array, invalid field values, etc.). Validation errors are returned
  as ValidationFailureRepresentation.
- 401 Unauthorized — Missing or invalid API key. Returned by the API gateway as
  { "message": "Unauthorized", "request_id": "d8aafa5b8f3e400b60bea0123dd33317" }.
- 403 Forbidden — The API key does not have write permissions for this operation.
- 404 Not Found — Tenant or Custom Entity denominator not found.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
POST /CustomEntities('Brand') HTTP/1.1
X-API-KEY: your-api-key-here
Accept-Language: en-US
Content-Type: application/json
            
{
  "abcd_title": "Acme",
  "abcd_description": "Acme brand"
}

            
Response:
http
HTTP/1.1 201 Created
Location: /CustomEntities('Brand')/Item(42)

## Update Custom Entity

 - [PATCH /CustomEntities('{customEntityDenominator}')/item({itemId})](https://docs.api.saleslayer.com/apis/catalog-v2.0/custom-entities/updatecustomentityasync.md): Updates an existing item of a Custom Entity type, identified by its denominator and item
identifier, applying PATCH semantics so that only the supplied fields are modified. Returns
200 OK when the update is applied.
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Headers
            
### Accept-Language
            
Culture used to interpret the localized field values supplied in the request body.
- omitted / null: tenant's default culture.
- culture-code (e.g. en-US, es): the specified culture.
            
## Request Body
            
A single JSON object with the subset of writable fields to update (PATCH semantics —
only the supplied fields are modified). Field names must match those published by
/CustomEntities('{denominator}')/$metadata. Normalization rules:
            
- Must be a non-empty JSON object.
- A JSON array is accepted only if it contains exactly one element.
- Values are coerced to CLR primitives, nested objects and arrays.
            
## Response
            
200 OK — Update applied.
            
## Error Responses
            
- 400 Bad Request — Payload normalization or validation failure
  (returns ValidationFailureRepresentation for validation errors).
- 401 Unauthorized — Missing or invalid API key. Returned by the API gateway as
  { "message": "Unauthorized", "request_id": "d8aafa5b8f3e400b60bea0123dd33317" }.
- 403 Forbidden — The API key does not have write permissions for this operation.
- 404 Not Found — Custom Entity denominator or item with the given identifier does not exist.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
PATCH /CustomEntities('Brand')/item(42) HTTP/1.1
X-API-KEY: your-api-key-here
Accept-Language: en-US
Content-Type: application/json
            
{
  "abcd_description": "Updated description"
}

            
Response:
http
HTTP/1.1 200 OK

## Delete Custom Entity

 - [DELETE /CustomEntities('{customEntityDenominator}')/item({itemId})](https://docs.api.saleslayer.com/apis/catalog-v2.0/custom-entities/deletecustomentityasync.md): Deletes an item of a Custom Entity type, identified by its denominator and item identifier.
Returns 204 No Content when the item has been deleted.
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Response
            
204 No Content — Custom Entity item deleted.
            
## Error Responses
            
- 401 Unauthorized — Missing or invalid API key. Returned by the API gateway as
  { "message": "Unauthorized", "request_id": "d8aafa5b8f3e400b60bea0123dd33317" }.
- 403 Forbidden — The API key does not have write permissions for this operation.
- 404 Not Found — Custom Entity denominator or item with the given identifier does not exist.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
DELETE /CustomEntities('Brand')/item(42) HTTP/1.1
X-API-KEY: your-api-key-here

            
Response:
http
HTTP/1.1 204 No Content

## Get Custom Entities Changelog

 - [GET /CustomEntities('{customEntityDenominator}')/Changelog](https://docs.api.saleslayer.com/apis/catalog-v2.0/custom-entities/filtercustomentitieschangelogasync.md): Returns the changelog entries for a Custom Entity type, identified by its denominator, as a
collection. Supports OData query options to filter, order and page the results.
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## OData Query Support
            
Supports $filter, $orderby, $top, $skip over the changelog fields.
$select, $expand and $skipToken are not supported by this endpoint.
            
## Response
            
200 OK — Collection of changelog entries for the specified Custom Entity type.
            
## Error Responses
            
- 400 Bad Request — Invalid OData expression.
- 401 Unauthorized — Missing or invalid API key. Returned by the API gateway as
  { "message": "Unauthorized", "request_id": "d8aafa5b8f3e400b60bea0123dd33317" }.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
GET /CustomEntities('Brand')/Changelog?$top=20 HTTP/1.1
X-API-KEY: your-api-key-here

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

## Get Custom Entity Changelog

 - [GET /CustomEntities('{customEntityDenominator}')/Changelog({itemIdentifier})](https://docs.api.saleslayer.com/apis/catalog-v2.0/custom-entities/filtercustomentitychangelogasync.md): Returns the changelog entries for a single Custom Entity item, identified by its denominator
and item identifier, as a collection. Supports OData query options to filter, order and page
the results.
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## OData Query Support
            
Supports $filter, $orderby, $top, $skip over the changelog fields.
$select, $expand and $skipToken are not supported by this endpoint.
            
## Response
            
200 OK — Collection of changelog entries for the specified Custom Entity item.
            
## Error Responses
            
- 400 Bad Request — Invalid OData expression.
- 401 Unauthorized — Missing or invalid API key. Returned by the API gateway as
  { "message": "Unauthorized", "request_id": "d8aafa5b8f3e400b60bea0123dd33317" }.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
GET /CustomEntities('Brand')/Changelog(123)?$top=20 HTTP/1.1
X-API-KEY: your-api-key-here

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

## Get Custom Entity Layout

 - [GET /CustomEntities('{customEntityDenominator}')/layout](https://docs.api.saleslayer.com/apis/catalog-v2.0/custom-entities/getcustomentityformlayoutasync.md): Unlike the Category model — which has a single layout shared by all categories — each Custom
Entity type has its own layout, selected by the route's customEntityDenominator.
            
The layout describes how the Custom Entity edit form is rendered. It is a JSON document with a
sections array; each section has a title and a rows array; each row has a
fields array and, optionally, a divider (dividerType and dividerTitle).
Each field carries an attributeId and a grid size — one of quarter,
half, threeQuarters or row. When a row has a divider its dividerType
is one of normal, wide or lineBreak. dividerType and
dividerTitle are omitted from a row when they have no value, so a row without a divider
contains only its fields.
            
A layout must be configured for the requested Custom Entity; if none exists the request returns
404 Not Found.

## Update Custom Entity Layout

 - [PUT /CustomEntities('{customEntityDenominator}')/layout](https://docs.api.saleslayer.com/apis/catalog-v2.0/custom-entities/updatecustomentityformlayoutasync.md): Each Custom Entity type has its own layout identified by customEntityDenominator. The supplied
layout fully overwrites the currently stored layout for that Custom Entity; it is not merged.
            
A layout must already exist for the requested Custom Entity — this operation replaces it and does
not create one. If none exists the request returns 404 Not Found.
            
## ⚠️ All attributes are required
            
The payload must contain every attribute currently in the stored layout — no more, no less.
Omitting an attribute removes it from the form. Adding an attribute that is not already in the
layout is also rejected. Use GET /CustomEntities('{customEntityDenominator}')/layout first to
obtain the current set of attributes.
            
This is different from PATCH /v2/AttributeSets({id}), where layouts may contain any subset of
the tenant's attributes.
            
## Layout Structure
            
The payload has the same shape as the GET /CustomEntities('{customEntityDenominator}')/layout response:
            
json
{
  "sections": [
    {
      "title": "General",
      "rows": [
        {
          "fields": [
            { "attributeId": "ce_title", "size": "half" },
            { "attributeId": "ce_ref",   "size": "half" }
          ]
        },
        {
          "dividerType": "normal",
          "dividerTitle": "Details",
          "fields": [
            { "attributeId": "ce_description", "size": "row" }
          ]
        }
      ]
    }
  ]
}

            
size — one of: quarter, half, threeQuarters, row.
            
dividerType — optional; one of: normal, wide, lineBreak. dividerTitle is optional
and only meaningful when dividerType is set. Both are omitted from rows that have no divider.
            
## Validation Rules
            
If any rule is violated the request returns 400 Bad Request describing each failure:
            
- The layout must contain every attribute currently in the stored layout — no more, no less.
- No attributeId may appear more than once.
- Each field size must be one of: quarter, half, threeQuarters, row.
- The sum of field sizes within any single row must not exceed a full row.
- Every row must contain at least one field.
- Section title values must be unique (case-insensitive).
- When a row sets dividerType it must be one of: normal, wide, lineBreak.

## Get Custom Entities Metadata

 - [GET /CustomEntities/$metadata](https://docs.api.saleslayer.com/apis/catalog-v2.0/custom-entities/getcustomentitiesmetadataasync.md): The metadata is a JSON Schema document that lists the Custom Entities defined in the PIM
for the current tenant, together with their relationships. Use the returned denominators
to query individual Custom Entity schemas via GET /CustomEntities('{denominator}')/$metadata.
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Response
            
200 OK — Returns the JSON Schema as a ServiceDocumentRepresentation.
            
## Error Responses
            
- 401 Unauthorized — Missing or invalid API key. Returned by the API gateway as
  { "message": "Unauthorized", "request_id": "d8aafa5b8f3e400b60bea0123dd33317" }.
- 404 Not Found — Tenant not found.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
GET /CustomEntities/$metadata HTTP/1.1
X-API-KEY: your-api-key-here

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

## Get Custom Entity Metadata

 - [GET /CustomEntities('{customEntityDenominator}')/$metadata](https://docs.api.saleslayer.com/apis/catalog-v2.0/custom-entities/getcustomentitymetadataasync.md): The metadata is a JSON Schema document that describes the implicit and custom properties
exposed by the specified Custom Entity resource. The schema should be consulted to build
requests against the other Custom Entity endpoints (which fields can be used in $select,
$filter, $orderby, request bodies, etc.).
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Response
            
200 OK — Returns the JSON Schema as a ServiceDocumentRepresentation.
            
## Error Responses
            
- 401 Unauthorized — Missing or invalid API key. Returned by the API gateway as
  { "message": "Unauthorized", "request_id": "d8aafa5b8f3e400b60bea0123dd33317" }.
- 404 Not Found — Tenant or Custom Entity not found.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
GET /CustomEntities('Brand')/$metadata HTTP/1.1
X-API-KEY: your-api-key-here

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

