categories.md
Categories
Filter Categories
- Endpoint: GET /Categories
Description: 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.
- 404 Not Found — Tenant or model not found.
- 500 Internal Server Error — Unexpected technical error.
Example
Request:
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/1.1 200 OK
Content-Type: application/json
Create Category
- Endpoint: POST /Categories
Description: 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.
- 404 Not Found — Tenant or referenced resource not found.
- 500 Internal Server Error — Unexpected technical error.
Example
Request:
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/1.1 201 Created
Location: /Categories(123)
Get Category
- Endpoint: GET /Categories({categoryIdentifier})
Description: 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
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
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.
- 404 Not Found — Category with the given identifier does not exist.
- 500 Internal Server Error — Unexpected technical error.
Example
Request:
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/1.1 200 OK
Content-Type: application/json
Update Category
- Endpoint: PATCH /Categories({categoryId})
Description: 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
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.
- 404 Not Found — Category with the given identifier does not exist.
- 500 Internal Server Error — Unexpected technical error.
Example
Request:
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/1.1 200 OK
Delete Category
- Endpoint: DELETE /Categories({categoryId})
Description: 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.
- 404 Not Found — Category with the given identifier does not exist.
- 500 Internal Server Error — Unexpected technical error.
Example
Request:
DELETE /Categories(123) HTTP/1.1
X-API-KEY: your-api-key-here
Response:
HTTP/1.1 204 No Content
Filter Category Products
- Endpoint: GET /Categories({categoryIdentifier})/Products
Description: 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
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).
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
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.
- 404 Not Found — Category with the given identifier does not exist.
- 500 Internal Server Error — Unexpected technical error.
Example
Request:
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/1.1 200 OK
Content-Type: application/json
Get Category Product
- Endpoint: GET /Categories({categoryIdentifier})/Products({productIdentifier})
Description: 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
OData Query Support
Example: $select=prod_description,prod_tags
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.
- 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:
GET /Categories(123)/Products(456)?$expand=Variants HTTP/1.1
X-API-KEY: your-api-key-here
Accept-Language: en-US
Response:
HTTP/1.1 200 OK
Content-Type: application/json
Get Categories Changelog
- Endpoint: GET /Categories/Changelog
Description: 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.
- 500 Internal Server Error — Unexpected technical error.
Example
Request:
GET /Categories/Changelog?$orderby=changedAt desc&$top=50 HTTP/1.1
X-API-KEY: your-api-key-here
Response:
HTTP/1.1 200 OK
Content-Type: application/json
Get Category Changelog
- Endpoint: GET /Categories({categoryIdentifier})/Changelog
Description: 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.
Example
Request:
GET /Categories(123)/Changelog?$top=20 HTTP/1.1
X-API-KEY: your-api-key-here
Response:
HTTP/1.1 200 OK
Content-Type: application/json
Get Category Layout
- Endpoint: GET /Categories/layout
Description: 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
- Endpoint: PUT /Categories/layout
Description: 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:
{
"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
- Endpoint: GET /Categories/$metadata
Description: 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.
- 404 Not Found — Tenant or model not found.
- 500 Internal Server Error — Unexpected technical error.
Example
Request:
GET /Categories/$metadata HTTP/1.1
X-API-KEY: your-api-key-here
Response:
HTTP/1.1 200 OK
Content-Type: application/json