# Sales Layer Catalog REST API

The Sales Layer Catalog REST API provides programmatic access to the catalog data managed in Sales Layer.

Use this reference to retrieve, filter, create, update, or delete products, variants, categories, attribute sets, custom entities, metadata, and changelog records. These endpoints support synchronization, enrichment, publishing, reporting, and other integration workflows across ecommerce platforms, ERPs, marketplaces, DAM systems, supplier systems, and internal tools.

Start with metadata endpoints when your integration needs to discover available fields and relationships, use pagination and filtering for large reads, and rely on changelogs for incremental synchronization whenever possible.


Version: 2.0.0

## Servers

Sales Layer Catalog API
```
https://api2.saleslayer.com/catalog
```

## Download OpenAPI description

[Sales Layer Catalog REST API](https://docs.api.saleslayer.com/_bundle/apis/catalog-v2.0.yaml)

## Attribute Sets

### Filter Attribute Sets

 - [GET /AttributeSets](https://docs.api.saleslayer.com/apis/catalog-v2.0/attribute-sets/filterattributesetsasync.md): Filters the tenant's Attribute Set resources using OData query options ($select, $expand, $filter, $orderby, $skip, $top, $skipToken). Result's paging is done using the default paging size options.
            


  Parameters details
  

  
    
      X-API-KEY
    
    
Custom HTTP request header containing the API key used for authentication.
            
  

    
      Accept-Language
    
    
Standard HTTP request header indicates the natural language and locale that the client prefers.
            
It can take one of the following values:
            
* : All the localized content is available in the result, regardless of the culture . This option is currently disabled.
            
null : The content localized in the default culture is available in the result.
            
culture-code : The content localized in the specified culture is available in the result.
            
 Specifying various culture codes or q-factor weighting are currently disabled.
            
Examples:
 - Expression es returns the content localized in the culture es. 
            
 - Expression en-us returns the content localized in the culture en-us.
            
  

    
      $select
    
    
Expression describing the list of Attribute Set resource properties to be included in the result.
            
The full list of the available Attribute Set resource properties is available in the JSON schema returned by the /AttributeSets/$metadata endpoint.
            
The name of the Attribute Set resource properties (both implicit and custom properties) must be specified.
            
Currently, the API does not support selecting the properties of an embedded resource or the properties of a resource within an embedded collection.
            
The expression follows the format: ATTRIBUTE_SET_PROPERTY1_NAME{, ATTRIBUTE_SET_PROPERTY2_NAME...}.
            
Examples:
 - Expression typ_title includes in the result only the property typ_title of the current resource (Attribute Set).
            
 - Expression typ_stat,typ_title includes in the result only the properties typ_stat and typ_title of the current resource (Attribute Set).
            
  

    
      $expand
    
    
Expression describing the list of collections embedded in the Attribute Set resource (Products) to be included in the result.
            
By default (if no value is supplied to this parameter), the result doesn't include the embedded collections (Products).
            
The expression follows the format: EMBEDDED_COLLECTION_OF_RESOURCE1_NAME{,EMBEDDED_COLLECTION_OF_RESOURCE1_NAME...}.
            
Currently only the embedded collections are supported, not the embedded resources.
            
Examples:
 - Expression Products includes in the result the number elements of the Products resource, embedded in the current resource (Attribute Set).
            
  

    
      $filter
    
    
Expression describing the filters applied to the resources included in the result.
            
By default (if no value is supplied to this parameter), no filters are applied
            
Currently, filtering on the nested resources properties is not supported.
            
The expression follows the ODATA version 4.01 URI conventions (http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html).
            
 The following filter options are currently supported:
            
 - logical operators (eq, ne, gt, lt, ge, le, or, and, in)
            
 - functions: string functions (contains, startswith, endswith)
            
 Currently it supports only the operators and functions applied on the properties of the root resource (Category).
            
 The logical operators/functions are applied over the data types of the corresponding properties in the filter criteria:
            
 - integer : property_of_type_integer lt -100
 - big integer: property_of_type_big_integer gt 10000
 - double: property_of_type_double ge 0.31415926535897931e1
 - decimal: property_of_type_decimal eq 12.34
 - string: property_of_type_string eq 'Hello world!'
 - date: property_of_type_date eq 2023-12-01
 - date time offset: property_of_type_datetimeoffset lt 2012-12-03T07:16:23Z or property_of_type_datetimeoffset lt 2012-12-03T07:16:23+00:00 or property_of_type_datetimeoffset lt 2012-12-03
Further examples:
            
 - contains(property1, 'stringValue1')
 - endswith(property1, 'stringValue1')
 - startswith(property1, 'stringValue1')
 - property1 in (value1, value2)
 - property1 gt integerValue1 and property2 eq 'stringValue1'
 - property1 gt integerValue1 or property2 eq 'stringValue1'
 - (property1 eq 'stringValue1' or property1 eq 'stringValue2') and (contains(property2, 'stringValue3') or startsWith(property3, 'stringValue4') or startsWith(property4, 'stringValue5'))
  

    
      $orderby
    
    
Expression describing the ordering applied to the properties of resources included in the result.
            
By default (if no value is supplied to this parameter), no sorting is applied.
            
Currently, ordering on multiple properties and ordering on embedded resources properties are not supported.
            
The expression follows the format: RESOURCE_PROPERTY_NAME (asc)|desc. 
            
Examples:
 - Expression typ_title orders the result ascendingly on the property typ_title of the current resource (Attribute Set).
            
 - Expression typ_title asc orders the result ascendingly on the property typ_title of the current resource (Attribute Set).
            
 - Expression typ_stat desc orders the result descendingly on the property typ_stat of the current resource (Attribute Set).
            
  

    
      $skip
    
    
Expression setting up result's paging according to the limit and offset paging strategy.
            
Using this paging strategy involves using both $skip and $top parameters.
            
We recommend limit and offset paging strategy for the extraction of data where $orderby clauses needs to be applied to the data to be extracted.
            
limit and offset paging is not as fast as the continuation token paging, but has 2 advantages over the later:
            
 - the possibility of applying sorting on the result;
            
 - a fine control over the data extracted.
            
The expression follows the format: NUMBER_OF_ITEMS_TO_BE_SKIPPED_IN_THE_RESULT. 
            
The page size for the Attribute Set resource is limited by default to 100 items.
            
The paging is performed through resource (Attribute Set), not through the resources in the embedded collections.
            
Examples:
 - Expression 1000 returns the Attribute Set items starting from the 1001st element in the result.
            
  

    
      $skipToken
    
    
Expression setting up the continuation token used in paging the result.
            
The expression follows the format: [CONTINUATION_TOKEN]. 
            
The page size for the Attribute Set resource is limited to 1 item.
            
The paging is performed through resource (Attribute Set), not through the resources in the embedded collections.
            
Examples:
 - Expression 123456789 limits the Attribute Set items to the next default number of items, starting from the continuation token 123456789.
            
  

    
      $top
    
    
Expression setting up the number of items in the result.
            
The expression follows the format: [PAGE_SIZE]. 
            
The page size for the Attribute Set resource is limited to 1 item.
            
The paging is performed through resource (Attribute Set), not through the resources in the embedded collections.
            
Examples:
 - Expression 10 limits the Attribute Set items to the first 10 elements, given the other filter, sorting and paging criteria.
            
  

    See also: A newer version of this endpoint is available at GET /v2/AttributeSets.
            The v2 endpoint returns a structured response (GetAttributeSetsResponse) that includes form layout configuration (ProductLayout, VariantLayout) and is not interchangeable with the OData-style response returned by this endpoint.

### Get Attribute Set

 - [GET /AttributeSets({attributeSetIdentifier})](https://docs.api.saleslayer.com/apis/catalog-v2.0/attribute-sets/searchattributesetasync.md): Returns a single Attribute Set resource by its identifier, using OData query options ($select, $expand) to shape the result.
            


  Parameters details
  

  
    
      X-API-KEY
    
    
Custom HTTP request header containing the API key used for authentication.
            
  

    
      Accept-Language
    
    
Standard HTTP request header indicates the natural language and locale that the client prefers.
            
It can take one of the following values:
            
* : All the localized content is available in the result, regardless of the culture . This option is currently disabled.
            
null : The content localized in the default culture is available in the result.
            
culture-code : The content localized in the specified culture is available in the result.
            
 Specifying various culture codes or q-factor weighting are currently disabled.
            
Examples:
 - Expression es returns the content localized in the culture es. 
            
 - Expression en-us returns the content localized in the culture en-us.
            
  

    
      $select
    
    
Expression describing the list of Attribute Set resource properties to be included in the result.
            
The full list of the available Attribute Set resource properties is available in the JSON schema returned by the /AttributeSets/$metadata endpoint.
            
The name of the Attribute Set resource properties (both implicit and custom properties) must be specified.
            
Currently, the API does not support selecting the properties of an embedded resource or the properties of a resource within an embedded collection.
            
The expression follows the format: ATTRIBUTE_SET_PROPERTY1_NAME{, ATTRIBUTE_SET_PROPERTY2_NAME...}.
            
Examples:
 - Expression typ_title includes in the result only the property typ_title of the current resource (Attribute Set).
            
 - Expression typ_stat,typ_title includes in the result only the properties typ_stat and typ_title of the current resource (Attribute Set).
            
  

    
      $expand
    
    
Expression describing the list of collections embedded in the Attribute Set resource (Products) to be included in the result.
            
By default (if no value is supplied to this parameter), the result doesn't include the embedded collections (Products).
            
The expression follows the format: EMBEDDED_COLLECTION_OF_RESOURCE1_NAME{,EMBEDDED_COLLECTION_OF_RESOURCE1_NAME...}.
            
Currently only the embedded collections are supported, not the embedded resources.
            
Examples:
 - Expression Products includes in the result the number elements of the Products resource, embedded in the current resource (Attribute Set).
            
  

    See also: A newer version of this endpoint is available at GET /v2/AttributeSets({id}).
            The v2 endpoint returns a typed response with form layout details (ProductLayout, VariantLayout) and differs in structure from this endpoint.

### Filter Attribute Set Products

 - [GET /AttributeSets({attributeSetIdentifier})/Products](https://docs.api.saleslayer.com/apis/catalog-v2.0/attribute-sets/filterproductsinattributesetasync.md): Filters and returns a paginated collection of Product resources scoped to the given Attribute Set, using OData query options.
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Headers
            
### Accept-Language
            
Indicates the preferred natural language and locale for localized content.
- omitted / null: content in the tenant's default culture.
- culture-code (e.g. en-US, es): content localized in the specified culture.
- * and q-factor weighting are currently not supported.
            
## OData Query Support
            
### $select
            
Comma-separated list of root-resource property names to include in the response.
See /Products/$metadata for the available properties.
Selecting properties of embedded resources is not supported.
            
Example: $select=prod_description,prod_tags
            
### $expand
            
Comma-separated list of embedded collections to include (e.g. Variants).
By default, embedded collections are not included.
Only embedded collections (not embedded resources) are supported.
            
Example: $expand=Variants
            
### $filter
            
OData v4.01 URI conventions. Filtering is restricted to properties of the root resource (Product).
            
Comparison operators: eq, ne, gt, ge, lt, le
            
Logical operators: and, or, not
            
Set operator: in
            
String functions: contains, startswith, endswith
            
Examples:
- $filter=prod_ref eq 'SKU-001'
- $filter=contains(prod_description, 'pro')
- $filter=prod_id gt 100 and contains(prod_description, 'pro')
            
### $orderby
            
Single property, ascending by default. Multi-property ordering and ordering on embedded
properties are not supported.
            
Examples:
- $orderby=prod_description
- $orderby=prod_ref desc
            
### Pagination — $top, $skip, $skipToken
            
- $top — maximum number of items returned.
- $skip — number of items to skip (offset paging).
- $skipToken — continuation-token paging. Recommended when no $orderby is applied
  (faster than offset paging).
            
Paging applies only to the root resource (Product), never to embedded collections.
            
## Response
            
200 OK — CollectionRepresentation with the matching Product resources, pagination
metadata (Count, Skip, Top, HasNext, continuation token) and the cultures echoed
from Accept-Language.
            
## Error Responses
            
- 400 Bad Request — Invalid OData expression or unsupported $orderby/$filter field
  (returns ValidationFailureRepresentation).
- 401 Unauthorized — Missing or invalid API key. Returned by the API gateway as
  { "message": "Unauthorized", "request_id": "d8aafa5b8f3e400b60bea0123dd33317" }.
- 404 Not Found — Attribute Set with the given identifier does not exist.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
GET /AttributeSets(7)/Products?$filter=contains(prod_description,'pro')&$top=20 HTTP/1.1
X-API-KEY: your-api-key-here
Accept-Language: en-US

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

### Get Attribute Set Metadata

 - [GET /AttributeSets/$metadata](https://docs.api.saleslayer.com/apis/catalog-v2.0/attribute-sets/getattributesetmetadataasync.md): Returns the public metadata of the Attribute Set model as a JSON schema document describing the resources (Product, Variant) associated to the Attribute Set and the relationships between them. Use it to build requests against the various methods of the API.

## Attribute Sets v2

### Get Attribute Sets

 - [GET /v2/AttributeSets](https://docs.api.saleslayer.com/apis/catalog-v2.0/attribute-sets-v2/getattributesets.md): Returns all attribute sets defined for the tenant, each including its name, identifier,
and form layout configuration for Products and Variants (ProductLayout, VariantLayout).
            
See also: A legacy OData-style version of this endpoint is available at GET /AttributeSets.
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Response
            
200 OK — GetAttributeSetsResponse containing the list of attribute sets.
            
## Error Responses
            
- 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 /v2/AttributeSets HTTP/1.1
X-API-KEY: your-api-key-here

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

### Create Attribute Set

 - [POST /v2/AttributeSets](https://docs.api.saleslayer.com/apis/catalog-v2.0/attribute-sets-v2/createattributeset.md): Creates a new attribute set for the tenant from the supplied name and optional Product and
Variant form layouts, returning the created attribute set and a Location header pointing to it.
            
The Product and Variant layouts behave differently when omitted: an omitted productLayout
falls back to a standard default layout, whereas an omitted variantLayout is not created
at all (no Variant layout is stored). A Variant layout can be added later with
PATCH /v2/AttributeSets({id}).
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Request Body
            
| Field | Required | Description |
|---|---|---|
| name | ✅ Yes | Unique name for the attribute set within the tenant. |
| productLayout | ❌ No | Form layout for Products. Defaults to the standard layout when omitted. |
| variantLayout | ❌ No | Form layout for Variants. When omitted, no Variant layout is created (it can be added later via PATCH). |
            
## Layout Structure
            
Each layout is a JSON document with a sections array. Each section has a title and a rows
array. Each row has a fields array and an optional divider (dividerType, dividerTitle).
Each field carries an attributeId and a size.
            
json
{
  "sections": [
    {
      "title": "General",
      "rows": [
        {
          "fields": [
            { "attributeId": "prod_title", "size": "half" },
            { "attributeId": "prod_ref",   "size": "half" }
          ]
        },
        {
          "dividerType": "normal",
          "dividerTitle": "Details",
          "fields": [
            { "attributeId": "prod_description", "size": "row" }
          ]
        }
      ]
    }
  ]
}

            
size — width of the field in the form grid. One of: quarter, half, threeQuarters, row.
            
dividerType — optional visual separator above the row. One of: normal, wide, lineBreak.
dividerTitle is optional and only meaningful when dividerType is set.
Both properties are omitted from rows that have no divider.
            
## Layout Validation
            
A layout may contain any subset of the tenant's valid attributes — you do not need to
include all of them. Attributes omitted from the layout simply do not appear in the form
for this attribute set; they are not removed from the tenant.
            
If a layout is supplied it must satisfy all of the following rules; otherwise the request
returns 400 Bad Request describing each failure:
            
- The layout must be well-formed: the sections, rows and fields arrays must all be present (non-null). Omitting a sections, rows or fields array (or sending it as null) is rejected.
- Every attributeId included must exist for the entity type (Products or Variants) in the tenant's storage definition.
- No attributeId may appear more than once across the entire layout.
- 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.
            
### Required attributes
            
These attributes must always be present in their respective layout:
            
| Layout | Required attribute IDs |
|---|---|
| productLayout | typ_id, prod_ref, prod_title, cat_ref, prod_stat, prod_description, prod_image, prod_tags |
| variantLayout | frmt_stat, prod_ref, frmt_ref, frmt_tags |
            
            
## Response
            
201 Created — The Location header points to the new resource: /v2/AttributeSets({id}).
The response body contains the created attribute set (CreateAttributeSet2Response).
            
## Error Responses
            
- 400 Bad Request — Missing body, missing name, duplicate name, or layout validation failure.
- 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.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
POST /v2/AttributeSets HTTP/1.1
X-API-KEY: your-api-key-here
Content-Type: application/json
            
{ "name": "Electronics" }

            
Response:
http
HTTP/1.1 201 Created
Location: /v2/AttributeSets(7)

### Get Attribute Set

 - [GET /v2/AttributeSets({id})](https://docs.api.saleslayer.com/apis/catalog-v2.0/attribute-sets-v2/getattributeset.md): Returns a single attribute set identified by id. Accepted values:
- default (case-insensitive) — retrieves the tenant's default attribute set.
- Positive integer — retrieves the attribute set with that numeric ID.
            
Any other value is rejected with 400 Bad Request.
            
The response includes the attribute set name and its form layout configuration for Products
and Variants (ProductLayout, VariantLayout). When the set has no Variant layout configured,
VariantLayout and VariantAttributeIds are omitted from the response.
            
See also: A legacy OData-style version of this endpoint is available at
GET /AttributeSets({attributeSetIdentifier}).
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Response
            
200 OK — The requested attribute set with its layout configuration.
            
## Error Responses
            
- 400 Bad Request — id is not default or a valid positive integer.
- 401 Unauthorized — Missing or invalid API key. Returned by the API gateway as
  { "message": "Unauthorized", "request_id": "d8aafa5b8f3e400b60bea0123dd33317" }.
- 404 Not Found — No attribute set with the given identifier exists for this tenant.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
GET /v2/AttributeSets(1) HTTP/1.1
X-API-KEY: your-api-key-here

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

### Update Attribute Set

 - [PATCH /v2/AttributeSets({id})](https://docs.api.saleslayer.com/apis/catalog-v2.0/attribute-sets-v2/updateattributeset.md): Partially updates an existing attribute set identified by id. Accepted values:
- default (case-insensitive) — updates the tenant's default attribute set.
- Positive integer — updates the attribute set with that numeric ID.
            
Any other value is rejected with 400 Bad Request.
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Request Body
            
All fields are optional. Omitted (null) fields are left unchanged (PATCH semantics).
When a layout is supplied it fully replaces the currently stored layout — it is not merged.
            
| Field | Description |
|---|---|
| name | New unique name for the attribute set. |
| productLayout | Replacement form layout for Products. |
| variantLayout | Form layout for Variants. Sets the Variant layout when the set does not yet have one (e.g. created without it), or replaces it when it does. |
            
## Layout Structure
            
Each layout is a JSON document with a sections array. Each section has a title and a rows
array. Each row has a fields array and an optional divider (dividerType, dividerTitle).
Each field carries an attributeId and a size.
            
json
{
  "sections": [
    {
      "title": "General",
      "rows": [
        {
          "fields": [
            { "attributeId": "prod_title", "size": "half" },
            { "attributeId": "prod_ref",   "size": "half" }
          ]
        },
        {
          "dividerType": "normal",
          "dividerTitle": "Details",
          "fields": [
            { "attributeId": "prod_description", "size": "row" }
          ]
        }
      ]
    }
  ]
}

            
size — width of the field in the form grid. One of: quarter, half, threeQuarters, row.
            
dividerType — optional visual separator above the row. One of: normal, wide, lineBreak.
dividerTitle is optional and only meaningful when dividerType is set.
Both properties are omitted from rows that have no divider.
            
## Layout Validation
            
A layout may contain any subset of the tenant's valid attributes — you do not need to
include all of them. Attributes omitted from the layout simply do not appear in the form
for this attribute set; they are not removed from the tenant.
            
This is different from PUT /Categories/layout and PUT /CustomEntities('{id}')/layout,
where the payload must contain every attribute currently in the stored layout — no more, no less.
            
If a layout is supplied it must satisfy all of the following rules; otherwise the request
returns 400 Bad Request describing each failure:
            
- The layout must be well-formed: the sections, rows and fields arrays must all be present (non-null). Omitting a sections, rows or fields array (or sending it as null) is rejected.
- Every attributeId included must exist for the entity type (Products or Variants) in the tenant's storage definition.
- No attributeId may appear more than once across the entire layout.
- 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.
            
### Required attributes
            
These attributes must always be present in their respective layout:
            
| Layout | Required attribute IDs |
|---|---|
| productLayout | typ_id, prod_ref, prod_title, cat_ref, prod_stat, prod_description, prod_image, prod_tags |
| variantLayout | frmt_stat, prod_ref, frmt_ref, frmt_tags |
            
            
## Response
            
200 OK — The updated attribute set (UpdateAttributeSet2Response).
            
## Error Responses
            
- 400 Bad Request — Invalid id, missing body, or layout validation failure.
- 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 — No attribute set with the given identifier exists for this tenant.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
PATCH /v2/AttributeSets(1) HTTP/1.1
X-API-KEY: your-api-key-here
Content-Type: application/json
            
{ "name": "Electronics v2" }

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

### Delete Attribute Set

 - [DELETE /v2/AttributeSets({id})](https://docs.api.saleslayer.com/apis/catalog-v2.0/attribute-sets-v2/deleteattributeset.md): Deletes the attribute set identified by id (a positive integer). The tenant's default
attribute set cannot be deleted.
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Query Parameters
            
| Parameter | Required | Description |
|---|---|---|
| deleteAssociatedProductsAndVariants | ❌ No | When true, products and variants associated to the attribute set are deleted along with it. When false or omitted, those products and variants are reassigned to the tenant's default attribute set. |
            
## Response
            
- 200 OK — Attribute set deleted; the response body (DeleteAttributeSet2Response) summarises the operation.
- 204 No Content — Nothing to delete (idempotent success).
            
## Error Responses
            
- 400 Bad Request — id is not a positive integer or the request is otherwise invalid (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 — No attribute set with the given identifier exists for this tenant.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
DELETE /v2/AttributeSets(7)?deleteAssociatedProductsAndVariants=false HTTP/1.1
X-API-KEY: your-api-key-here

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

## Categories

### Filter Categories

 - [GET /Categories](https://docs.api.saleslayer.com/apis/catalog-v2.0/categories/filtercategoriesasync.md): Filters the tenant's Categories using OData query options and returns the matching
resources as a paginated collection.
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Headers
            
### Accept-Language
            
Indicates the preferred natural language and locale for localized content.
- omitted / null: content in the tenant's default culture.
- culture-code (e.g. en-US, es): content localized in the specified culture.
- * and q-factor weighting are currently not supported.
            
## OData Query Support
            
### $select
            
Comma-separated list of root-resource property names to include in the response.
The available property names are published in /Categories/$metadata.
Selecting properties of embedded resources is not supported.
            
Example: $select=cat_title,cat_description
            
### $expand
            
Comma-separated list of embedded collections to include.
By default, embedded collections are not included.
Only embedded collections (not embedded resources) are supported.
            
Example: $expand=Products
            
### $filter
            
OData v4.01 URI conventions. Filtering is restricted to properties of the root resource (Category).
            
Comparison operators: eq, ne, gt, ge, lt, le
            
Logical operators: and, or, not
            
Set operator: in
            
String functions: contains, startswith, endswith
            
Examples:
- $filter=cat_title eq 'Outdoor'
- $filter=contains(cat_title, 'pro')
- $filter=cat_id in (1, 2, 3)
- $filter=cat_id gt 100 and contains(cat_title, 'pro')
            
### $orderby
            
Single property, ascending by default. Multi-property ordering and ordering on embedded
properties are not supported.
            
Examples:
- $orderby=cat_title (asc by default)
- $orderby=cat_title asc
- $orderby=cat_ref desc
            
### Pagination — $top, $skip, $skipToken
            
- $top — maximum number of items returned.
- $skip — number of items to skip (offset paging).
- $skipToken — continuation-token paging. Recommended when no $orderby is applied
  (faster than offset paging).
            
Paging applies only to the root resource (Category), never to embedded collections.
            
## Response
            
200 OK — CollectionRepresentation with the matching Category resources, pagination
metadata (Count, Skip, Top, HasNext, continuation token) and the cultures echoed
from Accept-Language.
            
## Error Responses
            
- 400 Bad Request — Invalid OData expression or unsupported $orderby/$filter field
  (returns ValidationFailureRepresentation).
- 401 Unauthorized — Missing or invalid API key. Returned by the API gateway as
  { "message": "Unauthorized", "request_id": "d8aafa5b8f3e400b60bea0123dd33317" }.
- 404 Not Found — Tenant or model not found.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
GET /Categories?$filter=contains(cat_title,'pro')&$orderby=cat_title asc&$top=20 HTTP/1.1
X-API-KEY: your-api-key-here
Accept-Language: en-US

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

### Create Category

 - [POST /Categories](https://docs.api.saleslayer.com/apis/catalog-v2.0/categories/createcategoryasync.md): Creates a new Category from the supplied JSON object and returns its 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
/Categories/$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: /Categories({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 referenced resource not found.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
POST /Categories HTTP/1.1
X-API-KEY: your-api-key-here
Accept-Language: en-US
Content-Type: application/json
            
{
  "cat_title": "Outdoor",
  "cat_ref": "OUT-001",
  "cat_description": "Outdoor products category"
}

            
Response:
http
HTTP/1.1 201 Created
Location: /Categories(123)

### Get Category

 - [GET /Categories({categoryIdentifier})](https://docs.api.saleslayer.com/apis/catalog-v2.0/categories/searchcategoryasync.md): Returns a single Category resource identified by its route identifier, optionally shaping
the response with $select and $expand.
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Headers
            
### Accept-Language
            
Indicates the preferred natural language and locale for localized content.
- omitted / null: content in the tenant's default culture.
- culture-code (e.g. en-US, es): content localized in the specified culture.
- * and q-factor weighting are currently not supported.
            
## OData Query Support
            
### $select
            
Comma-separated list of root-resource property names to include in the response.
See /Categories/$metadata for the available properties.
Selecting properties of embedded resources is not supported.
            
Example: $select=cat_title,cat_description
            
### $expand
            
Comma-separated list of embedded collections to include.
By default, embedded collections are not included.
Only embedded collections (not embedded resources) are supported.
            
Example: $expand=Products
            
$filter, $orderby, $top, $skip and $skipToken are not applicable to this endpoint.
            
## Response
            
200 OK — EntityRepresentation with the requested Category resource.
            
## Error Responses
            
- 400 Bad Request — Invalid $select or $expand expression (returns ValidationFailureRepresentation).
- 401 Unauthorized — Missing or invalid API key. Returned by the API gateway as
  { "message": "Unauthorized", "request_id": "d8aafa5b8f3e400b60bea0123dd33317" }.
- 404 Not Found — Category with the given identifier does not exist.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
GET /Categories(123)?$select=cat_title,cat_description&$expand=Products HTTP/1.1
X-API-KEY: your-api-key-here
Accept-Language: en-US

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

### Update Category

 - [PATCH /Categories({categoryId})](https://docs.api.saleslayer.com/apis/catalog-v2.0/categories/updatecategoryasync.md): Updates an existing Category identified by its route identifier, applying only the writable
fields supplied in the request body (PATCH semantics).
            
## 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
/Categories/$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 — Category with the given identifier does not exist.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
PATCH /Categories(123) HTTP/1.1
X-API-KEY: your-api-key-here
Accept-Language: en-US
Content-Type: application/json
            
{
  "cat_title": "Outdoor & Camping"
}

            
Response:
http
HTTP/1.1 200 OK

### Delete Category

 - [DELETE /Categories({categoryId})](https://docs.api.saleslayer.com/apis/catalog-v2.0/categories/deletecategoryasync.md): Deletes the Category identified by its route identifier.
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Response
            
204 No Content — Category 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 — Category with the given identifier does not exist.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
DELETE /Categories(123) HTTP/1.1
X-API-KEY: your-api-key-here

            
Response:
http
HTTP/1.1 204 No Content

### Filter Category Products

 - [GET /Categories({categoryIdentifier})/Products](https://docs.api.saleslayer.com/apis/catalog-v2.0/categories/filterproductsincategoryasync.md): Filters and returns a paginated collection of Product resources scoped to the given Category, using OData query options.
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Headers
            
### Accept-Language
            
Indicates the preferred natural language and locale for localized content.
- omitted / null: content in the tenant's default culture.
- culture-code (e.g. en-US, es): content localized in the specified culture.
- * and q-factor weighting are currently not supported.
            
## OData Query Support
            
### $select
            
Comma-separated list of root-resource property names to include in the response.
See /Products/$metadata for the available properties.
Selecting properties of embedded resources is not supported.
            
Example: $select=prod_description,prod_tags
            
### $expand
            
Comma-separated list of embedded collections to include (e.g. Variants).
By default, embedded collections are not included.
Only embedded collections (not embedded resources) are supported.
            
Example: $expand=Variants
            
### $filter
            
OData v4.01 URI conventions. Filtering is restricted to properties of the root resource (Product).
            
Comparison operators: eq, ne, gt, ge, lt, le
            
Logical operators: and, or, not
            
Set operator: in
            
String functions: contains, startswith, endswith
            
Examples:
- $filter=prod_ref eq 'SKU-001'
- $filter=contains(prod_description, 'pro')
- $filter=prod_id gt 100 and contains(prod_description, 'pro')
            
### $orderby
            
Single property, ascending by default. Multi-property ordering and ordering on embedded
properties are not supported.
            
Examples:
- $orderby=prod_description
- $orderby=prod_ref desc
            
### Pagination — $top, $skip, $skipToken
            
- $top — maximum number of items returned.
- $skip — number of items to skip (offset paging).
- $skipToken — continuation-token paging. Recommended when no $orderby is applied
  (faster than offset paging).
            
Paging applies only to the root resource (Product), never to embedded collections.
            
## Response
            
200 OK — CollectionRepresentation with the matching Product resources, pagination
metadata (Count, Skip, Top, HasNext, continuation token) and the cultures echoed
from Accept-Language.
            
## Error Responses
            
- 400 Bad Request — Invalid OData expression or unsupported $orderby/$filter field
  (returns ValidationFailureRepresentation).
- 401 Unauthorized — Missing or invalid API key. Returned by the API gateway as
  { "message": "Unauthorized", "request_id": "d8aafa5b8f3e400b60bea0123dd33317" }.
- 404 Not Found — Category with the given identifier does not exist.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
GET /Categories(123)/Products?$filter=contains(prod_description,'pro')&$top=20 HTTP/1.1
X-API-KEY: your-api-key-here
Accept-Language: en-US

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

### Get Category Product

 - [GET /Categories({categoryIdentifier})/Products({productIdentifier})](https://docs.api.saleslayer.com/apis/catalog-v2.0/categories/searchproductincategoryasync.md): Returns a single Product resource by its identifier, scoped to the given Category.
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Headers
            
### Accept-Language
            
Indicates the preferred natural language and locale for localized content.
- omitted / null: content in the tenant's default culture.
- culture-code (e.g. en-US, es): content localized in the specified culture.
- * and q-factor weighting are currently not supported.
            
## OData Query Support
            
### $select
            
Comma-separated list of root-resource property names to include in the response.
See /Products/$metadata for the available properties.
Selecting properties of embedded resources is not supported.
            
Example: $select=prod_description,prod_tags
            
### $expand
            
Comma-separated list of embedded collections to include (e.g. Variants).
By default, embedded collections are not included.
Only embedded collections (not embedded resources) are supported.
            
Example: $expand=Variants
            
## Response
            
200 OK — EntityRepresentation with the Product resource scoped to the given Category.
            
## Error Responses
            
- 400 Bad Request — Invalid OData expression (returns ValidationFailureRepresentation).
- 401 Unauthorized — Missing or invalid API key. Returned by the API gateway as
  { "message": "Unauthorized", "request_id": "d8aafa5b8f3e400b60bea0123dd33317" }.
- 404 Not Found — Category or Product with the given identifier does not exist, or the
  Product is not associated with the Category.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
GET /Categories(123)/Products(456)?$expand=Variants HTTP/1.1
X-API-KEY: your-api-key-here
Accept-Language: en-US

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

### Get Categories Changelog

 - [GET /Categories/Changelog](https://docs.api.saleslayer.com/apis/catalog-v2.0/categories/filtercategorieschangelogasync.md): Returns the changelog entries for the tenant's Categories as a collection, filterable and
pageable with OData query options.
            
## 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 (CollectionRepresentation).
            
## 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 /Categories/Changelog?$orderby=changedAt desc&$top=50 HTTP/1.1
X-API-KEY: your-api-key-here

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

### Get Category Changelog

 - [GET /Categories({categoryIdentifier})/Changelog](https://docs.api.saleslayer.com/apis/catalog-v2.0/categories/filtercategorychangelogasync.md): Returns the changelog entries for a single Category identified by its route identifier,
filterable and pageable with OData query options.
            
## 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 Category.
            
## 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 /Categories(123)/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 Category Layout

 - [GET /Categories/layout](https://docs.api.saleslayer.com/apis/catalog-v2.0/categories/getcategoryformlayoutasync.md): The layout describes how the Category 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.
            
The Category model has a single layout shared by all categories. A layout must already be
configured for the tenant; if none exists the request fails.

### Update Category Layout

 - [PUT /Categories/layout](https://docs.api.saleslayer.com/apis/catalog-v2.0/categories/updatecategoryformlayoutasync.md): Fully overwrites the currently stored Category layout. The payload is not merged with the
existing layout — it replaces it entirely.
            
A layout must already exist for the tenant; 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 /Categories/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 /Categories/layout response:
            
json
{
  "sections": [
    {
      "title": "General",
      "rows": [
        {
          "fields": [
            { "attributeId": "cat_title", "size": "half" },
            { "attributeId": "cat_ref",   "size": "half" }
          ]
        },
        {
          "dividerType": "normal",
          "dividerTitle": "Details",
          "fields": [
            { "attributeId": "cat_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 Category Metadata

 - [GET /Categories/$metadata](https://docs.api.saleslayer.com/apis/catalog-v2.0/categories/getcategorymetadataasync.md): The metadata is a JSON Schema document that describes:
- The implicit and custom properties exposed by the Category resource.
- The embedded resources (Products, Variants) and their relationships.
            
The schema should be consulted to build requests against the other Category 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 model not found.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
GET /Categories/$metadata HTTP/1.1
X-API-KEY: your-api-key-here

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

## Products

### Filter Products

 - [GET /Products](https://docs.api.saleslayer.com/apis/catalog-v2.0/products/filterproductsasync.md): Filters and returns a paginated collection of Product resources using OData query options.
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Headers
            
### Accept-Language
            
Indicates the preferred natural language and locale for localized content.
- omitted / null: content in the tenant's default culture.
- culture-code (e.g. en-US, es): content localized in the specified culture.
- * and q-factor weighting are currently not supported.
            
## OData Query Support
            
### $select
            
Comma-separated list of root-resource property names to include in the response.
See /Products/$metadata for the available properties.
Selecting properties of embedded resources is not supported.
            
Example: $select=prod_description,prod_tags
            
### $expand
            
Comma-separated list of embedded collections to include (e.g. Variants).
By default, embedded collections are not included.
Only embedded collections (not embedded resources) are supported.
            
Example: $expand=Variants
            
### $filter
            
OData v4.01 URI conventions. Filtering is restricted to properties of the root resource (Product).
            
Comparison operators: eq, ne, gt, ge, lt, le
            
Logical operators: and, or, not
            
Set operator: in
            
String functions: contains, startswith, endswith
            
Examples:
- $filter=prod_ref eq 'SKU-001'
- $filter=contains(prod_description, 'pro')
- $filter=prod_id in (1, 2, 3)
- $filter=prod_id gt 100 and contains(prod_description, 'pro')
            
### $orderby
            
Single property, ascending by default. Multi-property ordering and ordering on embedded
properties are not supported.
            
Examples:
- $orderby=prod_description (asc by default)
- $orderby=prod_description asc
- $orderby=prod_ref desc
            
### Pagination — $top, $skip, $skipToken
            
- $top — maximum number of items returned.
- $skip — number of items to skip (offset paging).
- $skipToken — continuation-token paging. Recommended when no $orderby is applied
  (faster than offset paging).
            
Paging applies only to the root resource (Product), never to embedded collections.
            
## Response
            
200 OK — CollectionRepresentation with the matching Product resources, pagination
metadata (Count, Skip, Top, HasNext, continuation token) and the cultures echoed
from Accept-Language.
            
## Error Responses
            
- 400 Bad Request — Invalid OData expression or unsupported $orderby/$filter field
  (returns ValidationFailureRepresentation).
- 401 Unauthorized — Missing or invalid API key. Returned by the API gateway as
  { "message": "Unauthorized", "request_id": "d8aafa5b8f3e400b60bea0123dd33317" }.
- 404 Not Found — Tenant or model not found.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
GET /Products?$filter=contains(prod_description,'pro')&$orderby=prod_description asc&$top=20 HTTP/1.1
X-API-KEY: your-api-key-here
Accept-Language: en-US

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

### Create Product

 - [POST /Products](https://docs.api.saleslayer.com/apis/catalog-v2.0/products/createproductasync.md): Creates a new Product resource from the supplied JSON body and returns its location.
            
## 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
/Products/$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: /Products({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 referenced resource not found.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
POST /Products HTTP/1.1
X-API-KEY: your-api-key-here
Accept-Language: en-US
Content-Type: application/json
            
{
  "prod_ref": "SKU-001",
  "prod_description": "New product",
  "cat_id": 123
}

            
Response:
http
HTTP/1.1 201 Created
Location: /Products(456)

### Get Product

 - [GET /Products({productIdentifier})](https://docs.api.saleslayer.com/apis/catalog-v2.0/products/searchproductasync.md): Returns a single Product resource by its identifier.
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Headers
            
### Accept-Language
            
Indicates the preferred natural language and locale for localized content.
- omitted / null: content in the tenant's default culture.
- culture-code (e.g. en-US, es): content localized in the specified culture.
- * and q-factor weighting are currently not supported.
            
## OData Query Support
            
### $select
            
Comma-separated list of root-resource property names to include in the response.
See /Products/$metadata for the available properties.
Selecting properties of embedded resources is not supported.
            
Example: $select=prod_description,prod_tags
            
### $expand
            
Comma-separated list of embedded collections to include (e.g. Variants).
By default, embedded collections are not included.
Only embedded collections (not embedded resources) are supported.
            
Example: $expand=Variants
            
## Response
            
200 OK — EntityRepresentation with the Product resource.
            
## Error Responses
            
- 400 Bad Request — Invalid OData expression (returns ValidationFailureRepresentation).
- 401 Unauthorized — Missing or invalid API key. Returned by the API gateway as
  { "message": "Unauthorized", "request_id": "d8aafa5b8f3e400b60bea0123dd33317" }.
- 404 Not Found — Product with the given identifier does not exist.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
GET /Products(456)?$select=prod_description,prod_tags&$expand=Variants HTTP/1.1
X-API-KEY: your-api-key-here
Accept-Language: en-US

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

### Update Product

 - [PATCH /Products({productId})](https://docs.api.saleslayer.com/apis/catalog-v2.0/products/updateproductasync.md): Updates an existing Product resource, applying only the fields supplied in the JSON body (PATCH semantics).
            
## 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
/Products/$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.
- The cat_id field is accepted as either a single integer or an array of integers
  to assign the product to one or several categories.
            
## 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 — Product with the given identifier does not exist.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
PATCH /Products(456) HTTP/1.1
X-API-KEY: your-api-key-here
Accept-Language: en-US
Content-Type: application/json
            
{
  "prod_description": "Updated description",
  "cat_id": [123, 124]
}

            
Response:
http
HTTP/1.1 200 OK

### Delete Product

 - [DELETE /Products({productId})](https://docs.api.saleslayer.com/apis/catalog-v2.0/products/deleteproductasync.md): Deletes the Product resource identified by the given identifier.
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Response
            
204 No Content — Product 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 — Product with the given identifier does not exist.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
DELETE /Products(456) HTTP/1.1
X-API-KEY: your-api-key-here

            
Response:
http
HTTP/1.1 204 No Content

### Filter Product Variants

 - [GET /Products({productIdentifier})/Variants](https://docs.api.saleslayer.com/apis/catalog-v2.0/products/filtervariantsinproductasync.md): Filters the Variant resources nested within the specified Product using OData query options and returns the matching collection.
            
## 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 /Variants/$metadata.
            
### $select
Comma-separated list of Variant properties (implicit or custom) to include in the result.
Selection of properties inside embedded resources/collections is not supported.
- Example: frmt_ref
- Example: frmt_ref,frmt_tags
            
### $expand
Comma-separated list of embedded collections to include in the result. 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.
            
### $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 Variant resources associated to the Product.
            
## 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 — Product or tenant not found.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
GET /Products(987)/Variants?$select=frmt_ref&$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

### Get Product Variant

 - [GET /Products({productIdentifier})/Variants({variantIdentifier})](https://docs.api.saleslayer.com/apis/catalog-v2.0/products/searchvariantinproductasync.md): Returns a single Variant resource nested within the specified Product, with the published fields selected via OData query options.
            
## 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 /Variants/$metadata.
            
### $select
Comma-separated list of Variant properties (implicit or custom) to include in the result.
Selection of properties inside embedded resources/collections is not supported.
- Example: frmt_ref
- Example: frmt_ref,frmt_tags
            
### $expand
Comma-separated list of embedded collections to include in the result. By default, embedded collections are not included.
Only embedded collections are supported (not embedded resources).
            
## Response
            
200 OK — Returns an EntityRepresentation with the requested Variant.
            
## 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 — Product, Variant or tenant not found.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
GET /Products(987)/Variants(12345)?$select=frmt_ref HTTP/1.1
X-API-KEY: your-api-key-here
Accept-Language: es

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

### Get Products Changelog

 - [GET /Products/Changelog](https://docs.api.saleslayer.com/apis/catalog-v2.0/products/filterproductschangelogasync.md): Returns a paginated collection of changelog entries recording changes to Products, filterable with OData query options.
            
## 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 (CollectionRepresentation).
            
## 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 /Products/Changelog?$orderby=changedAt desc&$top=50 HTTP/1.1
X-API-KEY: your-api-key-here

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

### Get Product Changelog

 - [GET /Products({productIdentifier})/Changelog](https://docs.api.saleslayer.com/apis/catalog-v2.0/products/filterproductchangelogasync.md): Returns a paginated collection of changelog entries for a single Product, filterable with OData query options.
            
## 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 Product.
            
## 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 /Products(123)/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 Product Metadata

 - [GET /Products/$metadata](https://docs.api.saleslayer.com/apis/catalog-v2.0/products/getproductmetadataasync.md): The metadata is a JSON Schema document that describes:
- The implicit and custom properties exposed by the Product resource.
- The associated resources (Category, Attribute Set, Variant) and their relationships.
            
The schema should be consulted to build requests against the other Product 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 model not found.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
GET /Products/$metadata HTTP/1.1
X-API-KEY: your-api-key-here

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

## Variants

### Filter Variants

 - [GET /Variants](https://docs.api.saleslayer.com/apis/catalog-v2.0/variants/filtervariantsasync.md): Filters the tenant's Variant resources using OData query options and returns the matching collection.
            
## 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 /Variants/$metadata.
            
### $select
Comma-separated list of Variant properties (implicit or custom) to include in the result.
Selection of properties inside embedded resources/collections is not supported.
- Example: frmt_ref
- Example: frmt_ref,frmt_tags
            
### $expand
Comma-separated list of embedded collections to include in the result. 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
- Example: contains(frmt_ref, 'abc')
- Example: frmt_ref in ('A','B') and price gt 10
            
### $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: frmt_ref 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 Variant 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 resource not found.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
GET /Variants?$select=frmt_ref&$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 Variant

 - [POST /Variants](https://docs.api.saleslayer.com/apis/catalog-v2.0/variants/createvariantasync.md): Creates a new Variant resource from the supplied JSON body and returns its 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
/Variants/$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: /Variants({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 referenced Product resource not found.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
POST /Variants HTTP/1.1
X-API-KEY: your-api-key-here
Accept-Language: en-US
Content-Type: application/json
            
{
  "frmt_ref": "SKU-001-RED-M",
  "prod_id": 456
}

            
Response:
http
HTTP/1.1 201 Created
Location: /Variants(789)

### Get Variant

 - [GET /Variants({variantIdentifier})](https://docs.api.saleslayer.com/apis/catalog-v2.0/variants/searchvariantasync.md): Returns a single Variant resource identified by its identifier, with the published fields selected via OData query options.
            
## 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 /Variants/$metadata.
            
### $select
Comma-separated list of Variant properties (implicit or custom) to include in the result.
Selection of properties inside embedded resources/collections is not supported.
- Example: frmt_ref
- Example: frmt_ref,frmt_tags
            
### $expand
Comma-separated list of embedded collections to include in the result. By default, embedded collections are not included.
Only embedded collections are supported (not embedded resources).
            
## Response
            
200 OK — Returns an EntityRepresentation with the requested Variant.
            
## 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 — Variant or tenant not found.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
GET /Variants(12345)?$select=frmt_ref HTTP/1.1
X-API-KEY: your-api-key-here
Accept-Language: es

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

### Update Variant

 - [PATCH /Variants({variantId})](https://docs.api.saleslayer.com/apis/catalog-v2.0/variants/updatevariantasync.md): Updates the writable fields of an existing Variant from the supplied JSON body using PATCH semantics (only the supplied fields are modified).
            
## 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
/Variants/$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 — Variant with the given identifier does not exist.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
PATCH /Variants(789) HTTP/1.1
X-API-KEY: your-api-key-here
Accept-Language: en-US
Content-Type: application/json
            
{
  "frmt_ref": "SKU-001-RED-L"
}

            
Response:
http
HTTP/1.1 200 OK

### Delete Variant

 - [DELETE /Variants({variantId})](https://docs.api.saleslayer.com/apis/catalog-v2.0/variants/deletevariantasync.md): Deletes the Variant resource identified by its identifier.
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Response
            
204 No Content — Variant 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 — Variant with the given identifier does not exist.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
DELETE /Variants(789) HTTP/1.1
X-API-KEY: your-api-key-here

            
Response:
http
HTTP/1.1 204 No Content

### Get Variants Changelog

 - [GET /Variants/Changelog](https://docs.api.saleslayer.com/apis/catalog-v2.0/variants/filtervariantschangelogasync.md): Returns the changelog entries recorded across the tenant's Variants, filtered and paged via OData query options.
            
## 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 (CollectionRepresentation).
            
## 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 /Variants/Changelog?$orderby=changedAt desc&$top=50 HTTP/1.1
X-API-KEY: your-api-key-here

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

### Get Variant Changelog

 - [GET /Variants({variantIdentifier})/Changelog](https://docs.api.saleslayer.com/apis/catalog-v2.0/variants/filtervariantchangelogasync.md): Returns the changelog entries recorded for the Variant identified by its identifier, filtered and paged via OData query options.
            
## 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 Variant.
            
## 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 /Variants(123)/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 Variant Metadata

 - [GET /Variants/$metadata](https://docs.api.saleslayer.com/apis/catalog-v2.0/variants/getvariantmetadataasync.md): The metadata is a JSON Schema document that describes:
- The implicit and custom properties exposed by the Variant resource.
- The associated resources (Product) and their relationships.
            
The schema should be consulted to build requests against the other Variant 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 model not found.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
GET /Variants/$metadata HTTP/1.1
X-API-KEY: your-api-key-here

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

## 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

## Metadata

### Get Catalog Metadata

 - [GET /$metadata](https://docs.api.saleslayer.com/apis/catalog-v2.0/metadata/getmetadataasync.md): Returns the Catalog metadata as a JSON Schema document describing every resource
(Category, Attribute Set, Product, Variant, Point of Sale) and the relationships
between them. Use it to build requests against the rest of the API.
            
## Authentication
            
Requires a valid API key in the X-API-KEY header.
            
## Response
            
200 OK — A JSON schema document describing every resource in the Catalog
(Category, Attribute Set, Product, Variant, Point of Sale) and the relationships
between them. Use this document to build requests against the rest of the API.
            
## 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 model not found.
- 500 Internal Server Error — Unexpected technical error.
            
## Example
            
Request:
http
GET /$metadata HTTP/1.1
X-API-KEY: your-api-key-here

            
Response:
http
HTTP/1.1 200 OK
Content-Type: application/json

