### Sales Layer REST APIs

Postman collection for testing the Sales Layer DAM and Catalog REST APIs (v2.0).

This collection covers at least one example of every endpoint exposed by the current OpenAPI specifications. Requests are grouped to match the API reference: setup checks first, then the DAM REST API, then the Catalog REST API organized by resource (Metadata, Attribute Sets, Attribute Sets v2, Products, Variants, Categories, Custom Entities).

### How to use:
1. Import the companion environment 'Sales Layer API - Template'.
2. Set the apiKey secret value in the environment.
3. Run read-only requests first (Setup checks and any GET request).
4. Run write requests (Create/Update/Delete) only against a test account.

Field names such as prod_ref, prod_title, cat_ref, or frmt_ref are examples. Confirm the writable fields available for your account using the matching $metadata endpoint before sending Create or Update requests.

---

### Authentication
- Type: `apikey`
- Key: `X-API-KEY`
- Value: `{{apiKey}}`
- In: `header`

### Variables
- baseUrl: `https://api2.saleslayer.com`
- acceptLanguage: `en`

### Setup checks
#### Catalog service metadata
- **Method:** `GET`
- **Description:** Returns Catalog API metadata. Use this as a first connectivity and authentication check.
- **URL:** `{{baseUrl}}/catalog/$metadata`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### DAM list first page
- **Method:** `GET`
- **Description:** Lists the first DAM image records. This is a read-only check against the DAM API.
- **URL:** `{{baseUrl}}/dam/images?$top=10`
- **Headers:**
  - Accept: `application/json`

### DAM REST API v2.0
#### List images with pagination
- **Method:** `GET`
- **Description:** Retrieves DAM images using limit and offset pagination. Maximum page size is 100.
- **URL:** `{{baseUrl}}/dam/images?$skip=0&$top=20`
- **Headers:**
  - Accept: `application/json`

#### Filter processed JPG images
- **Method:** `GET`
- **Description:** Example combining DAM filtering, sorting, and page size. The status value 'Ok' selects images that finished processing.
- **URL:** `{{baseUrl}}/dam/images?$filter=fileType eq 'jpg' and status eq 'Ok'&$orderby=createdOn desc&$top=20`
- **Headers:**
  - Accept: `application/json`

#### Get image by reference
- **Method:** `GET`
- **Description:** Retrieves the full record for a single image by its reference (filename). Set damImageReference to an existing image filename, for example test-image.jpg. Returns 404 if no image with the given reference exists for this tenant.
- **URL:** `{{baseUrl}}/dam/images({{damImageReference}})`
- **Headers:**
  - Accept: `application/json`

#### Delete image (write)
- **Method:** `DELETE`
- **Description:** Deletes a DAM image by its reference (filename). Set damImageReference to the filename of a controlled test image (for example, test-image.jpg). A successful delete returns 204 No Content. If the image is currently being processed, the API returns 409 Conflict.
- **URL:** `{{baseUrl}}/dam/images({{damImageReference}})`
- **Headers:**
  - Accept: `application/json`

### Catalog REST API v2.0
#### Metadata
##### Catalog model metadata
- **Method:** `GET`
- **Description:** Returns the public metadata of the entire Catalog model, including every resource and the relationships between them.
- **URL:** `{{baseUrl}}/catalog/$metadata`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

##### Products metadata
- **Method:** `GET`
- **Description:** Returns the JSON Schema describing the Product model for the current account.
- **URL:** `{{baseUrl}}/catalog/Products/$metadata`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

##### Variants metadata
- **Method:** `GET`
- **Description:** Returns the JSON Schema describing the Variant model for the current account.
- **URL:** `{{baseUrl}}/catalog/Variants/$metadata`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

##### Categories metadata
- **Method:** `GET`
- **Description:** Returns the JSON Schema describing the Category model for the current account.
- **URL:** `{{baseUrl}}/catalog/Categories/$metadata`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

##### Custom Entities metadata
- **Method:** `GET`
- **Description:** Returns the JSON Schema describing all available Custom Entities for the account. Use it to discover the denominators available for customEntityDenominator.
- **URL:** `{{baseUrl}}/catalog/CustomEntities/$metadata`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

##### Custom Entity metadata (by denominator)
- **Method:** `GET`
- **Description:** Returns the JSON Schema describing a single Custom Entity referenced by its denominator. Set customEntityDenominator first.
- **URL:** `{{baseUrl}}/catalog/CustomEntities('{{customEntityDenominator}}')/$metadata`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Attribute Sets
##### List attribute sets (legacy)
- **Method:** `GET`
- **Description:** Lists legacy OData-style attribute set records. Use $select, $filter, $orderby, $top, $skip, $skipToken, and $expand as supported by the OpenAPI reference.
- **URL:** `{{baseUrl}}/catalog/AttributeSets?$select=id,name&$top=20`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

##### Get attribute set (legacy)
- **Method:** `GET`
- **Description:** Retrieves a single legacy OData-style attribute set. Set attributeSetIdentifier first.
- **URL:** `{{baseUrl}}/catalog/AttributeSets({{attributeSetIdentifier}})`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

##### Attribute Sets metadata
- **Method:** `GET`
- **Description:** Returns the metadata for legacy OData-style Attribute Sets.
- **URL:** `{{baseUrl}}/catalog/AttributeSets/$metadata`
- **Headers:**
  - Accept: `application/json`

#### Attribute Sets v2
##### List attribute sets
- **Method:** `GET`
- **Description:** Returns all attribute sets defined for the tenant, including name, identifier, and form layout configuration for Products and Variants.
- **URL:** `{{baseUrl}}/catalog/v2/AttributeSets`
- **Headers:**
  - Accept: `application/json`

##### Get attribute set by identifier
- **Method:** `GET`
- **Description:** Returns a single attribute set. Set attributeSetV2Identifier to `default` to retrieve the tenant default, or to a positive integer for a specific attribute set.
- **URL:** `{{baseUrl}}/catalog/v2/AttributeSets({{attributeSetV2Identifier}})`
- **Headers:**
  - Accept: `application/json`

##### Create attribute set (write)
- **Method:** `POST`
- **Description:** Creates a new attribute set. The `name` field is required and must be unique within the tenant. Returns 201 Created with a Location header pointing to the new resource. On success, stores the new identifier in attributeSetV2Identifier. Use a test account only.
- **URL:** `{{baseUrl}}/catalog/v2/AttributeSets`
- **Headers:**
  - Content-Type: `application/json`
  - Accept: `application/json`

##### Update attribute set (write)
- **Method:** `PATCH`
- **Description:** Partially updates an existing attribute set. All fields are optional; omitted fields are left unchanged. Set attributeSetV2Identifier first. Use a test account only.
- **URL:** `{{baseUrl}}/catalog/v2/AttributeSets({{attributeSetV2Identifier}})`
- **Headers:**
  - Content-Type: `application/json`
  - Accept: `application/json`

##### Delete attribute set (write)
- **Method:** `DELETE`
- **Description:** Deletes an attribute set. When deleteAssociatedProductsAndVariants is false, associated products and variants are reassigned to the tenant default attribute set. Set attributeSetV2Identifier to a positive integer first. The default attribute set cannot be deleted. Use a test account only.
- **URL:** `{{baseUrl}}/catalog/v2/AttributeSets({{attributeSetV2Identifier}})?deleteAssociatedProductsAndVariants=false`
- **Headers:**
  - Accept: `application/json`

### Products
- **Description:** Create, read, update, delete, and track changelog for products. Includes access to products within categories and attribute sets. Confirm writable fields with the Products metadata request before sending Create or Update payloads.

#### List products
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/Products?$select=prod_ref,prod_title&$top=20`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Filter products by title
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/Products?$select=prod_ref,prod_title&$filter=contains(prod_title,'EC')&$orderby=prod_ref asc&$top=20`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Get product by identifier
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/Products({{catalogProductIdentifier}})`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### List products in category
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/Categories({{catalogCategoryIdentifier}})/Products?$select=prod_ref,prod_title&$top=20`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Get product in category
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/Categories({{catalogCategoryIdentifier}})/Products({{catalogProductIdentifier}})`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Create product (write)
- **Method:** `POST`
- **URL:** `{{baseUrl}}/catalog/Products`
- **Headers:**
  - Content-Type: `application/json`
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`
  
#### Update product (write)
- **Method:** `PATCH`
- **URL:** `{{baseUrl}}/catalog/Products({{catalogProductIdentifier}})`
- **Headers:**
  - Content-Type: `application/json`
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Delete product (write)
- **Method:** `DELETE`
- **URL:** `{{baseUrl}}/catalog/Products({{catalogProductIdentifier}})`
- **Headers:**
  - Accept: `application/json`
  
#### Products changelog
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/Products/Changelog?$top=20`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Product changelog by identifier
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/Products({{catalogProductIdentifier}})/Changelog?$top=20`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

### Variants
- **Description:** Create, read, update, delete, and track changelog for product variants. Includes access to variants within a product. Confirm writable fields with the Variants metadata request before sending Create or Update payloads.

#### List variants
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/Variants?$select=frmt_ref&$top=20`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Get variant by identifier
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/Variants({{catalogVariantIdentifier}})`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### List variants in product
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/Products({{catalogProductIdentifier}})/Variants?$select=frmt_ref&$top=20`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Get variant in product
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/Products({{catalogProductIdentifier}})/Variants({{catalogVariantIdentifier}})`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Create variant (write)
- **Method:** `POST`
- **URL:** `{{baseUrl}}/catalog/Variants`
- **Headers:**
  - Content-Type: `application/json`
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Update variant (write)
- **Method:** `PATCH`
- **URL:** `{{baseUrl}}/catalog/Variants({{catalogVariantIdentifier}})`
- **Headers:**
  - Content-Type: `application/json`
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Delete variant (write)
- **Method:** `DELETE`
- **URL:** `{{baseUrl}}/catalog/Variants({{catalogVariantIdentifier}})`
- **Headers:**
  - Accept: `application/json`

#### Variants changelog
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/Variants/Changelog?$top=20`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Variant changelog by identifier
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/Variants({{catalogVariantIdentifier}})/Changelog?$top=20`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

### Categories
- **Description:** Create, read, update, delete, and track changelog for categories. Confirm writable fields with the Categories metadata request before sending Create or Update payloads.

#### List categories
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/Categories?$select=cat_id,cat_title,cat_ref&$top=20`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### List categories with products
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/Categories?$select=cat_id,cat_title,cat_ref&$expand=Products&$top=20`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Get category by identifier
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/Categories({{catalogCategoryIdentifier}})`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Create category (write)
- **Method:** `POST`
- **URL:** `{{baseUrl}}/catalog/Categories`
- **Headers:**
  - Content-Type: `application/json`
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Update category (write)
- **Method:** `PATCH`
- **URL:** `{{baseUrl}}/catalog/Categories({{catalogCategoryIdentifier}})`
- **Headers:**
  - Content-Type: `application/json`
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Delete category (write)
- **Method:** `DELETE`
- **URL:** `{{baseUrl}}/catalog/Categories({{catalogCategoryIdentifier}})`
- **Headers:**
  - Accept: `application/json`

#### Categories changelog
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/Categories/Changelog?$top=20`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Category changelog by identifier
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/Categories({{catalogCategoryIdentifier}})/Changelog?$top=20`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Get category layout
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/Categories/layout`
- **Headers:**
  - Accept: `application/json`

#### Update category layout (write)
- **Method:** `PUT`
- **URL:** `{{baseUrl}}/catalog/Categories/layout`
- **Headers:**
  - Content-Type: `application/json`
  - Accept: `application/json`

### Custom Entities
- **Description:** Create, read, update, delete, and track changelog for custom entity items. All requests require customEntityDenominator. Confirm writable fields with the Custom Entity metadata (by denominator) request before sending Create or Update payloads.

#### List custom entity items
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/CustomEntities('{{customEntityDenominator}}')?$top=20`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Create custom entity item (write)
- **Method:** `POST`
- **URL:** `{{baseUrl}}/catalog/CustomEntities('{{customEntityDenominator}}')`
- **Headers:**
  - Content-Type: `application/json`
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Update custom entity item (write)
- **Method:** `PATCH`
- **URL:** `{{baseUrl}}/catalog/CustomEntities('{{customEntityDenominator}}')/item({{customEntityItemId}})`
- **Headers:**
  - Content-Type: `application/json`
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Delete custom entity item (write)
- **Method:** `DELETE`
- **URL:** `{{baseUrl}}/catalog/CustomEntities('{{customEntityDenominator}}')/item({{customEntityItemId}})`
- **Headers:**
  - Accept: `application/json`

#### Custom entity changelog
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/CustomEntities('{{customEntityDenominator}}')/Changelog?$top=20`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Custom entity item changelog
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/CustomEntities('{{customEntityDenominator}}')/Changelog({{customEntityItemId}})?$top=20`
- **Headers:**
  - Accept: `application/json`
  - Accept-Language: `{{acceptLanguage}}`

#### Get custom entity layout
- **Method:** `GET`
- **URL:** `{{baseUrl}}/catalog/CustomEntities('{{customEntityDenominator}}')/layout`
- **Headers:**
  - Accept: `application/json`

#### Update custom entity layout (write)
- **Method:** `PUT`
- **URL:** `{{baseUrl}}/catalog/CustomEntities('{{customEntityDenominator}}')/layout`
- **Headers:**
  - Content-Type: `application/json`
  - Accept: `application/json`
