Getting Started with Item Categories
This guide walks you through creating Item Categories on the Hii Retail platform. By the end of this guide, you will understand the core concepts and be able to programmatically create and manage your item category hierarchy.
Overview
What is an Item Category?
An Item Category is an entity that represents a node in a hierarchical tree structure used to group items. It can be:
- A user-defined grouping specific to your business
- A Brick following the GS1 Global Product Classification (GPC) standard
Item Categories allow you to organize products and services into meaningful groups for:
- Product navigation and discovery
- Reporting and analytics
- Price management
- Assortment planning
Hierarchical Structure
Item Categories form a tree structure where each category (except the top node) has a parent. Here's an example:
Acme Category top node
|-> Acme Groceries
| |-> Meat
| | |-> Chicken
| | |-> Pork
| |-> Dairy
| |-> Refrigerated
| |-> Milk
| |-> Yoghurt
| |-> Cheese
|-> Electronics
|-> TVs
|-> Computers
|-> Laptops
|-> Workstations
Creating categories: You must ingest Item Categories according to their level in the hierarchy. Always start with top-level nodes before creating child nodes.
Deleting categories: You must delete categories in reverse order. Delete the lowest nodes in the hierarchy first, then work your way up.
GS1 GPC Standard
You can follow the GS1 Global Product Classification (GPC) hierarchy by using these standard level names:
Segment- Top levelFamily- Second levelClass- Third levelBrick- Fourth level (most granular)
Alternatively, you can define your own hierarchy levels using custom level names.
Prerequisites
Before you begin, ensure you have:
- API Access: Valid credentials for the Hii Retail platform
- Authentication Token: A valid JWT bearer token with the
pnp.item-category.createpermission - Tenant ID: Your organization's tenant identifier
For details on obtaining an access token, see the OAuth2 Authentication documentation.
API Base URL
All Item Category Input API requests should be sent to:
https://item-category-input.retailsvc.com/api/v2
Step 1: Create a Top-Level Category
Start by creating the root node of your category tree. A top-level category has no parentId.
Request
POST /api/v2/item-categories
Fields
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier (max 250 characters) |
name | string | Yes | Name of the category |
status | string | Yes | ACTIVE or DELETED |
description | string | Description of the category | |
parentId | string | Parent category ID (omit for top-level) | |
level | string | Hierarchy level (e.g., Segment, Family, Class, Brick, or custom) | |
code | string | Optional code for the category | |
revision | integer | Version number (EPOCH timestamp in milliseconds recommended) | |
additionalProperties | array | Custom key-value properties | |
images | array | Category images |
Code Examples
- cURL
- Java
- Python
- Node.js
- .NET
curl -X POST 'https://item-category-input.retailsvc.com/api/v2/item-categories' \
-H 'Authorization: Bearer <your-access-token>' \
-H 'Content-Type: application/json' \
-d '{
"id": "{{category-id}}",
"name": "{{category-name}}",
"description": "{{category-description}}",
"level": "TOP",
"status": "ACTIVE"
}'
var payload = """
{
"id": "{{category-id}}",
"name": "{{category-name}}",
"description": "{{category-description}}",
"level": "TOP",
"status": "ACTIVE"
}
""";
var request = HttpRequest.newBuilder()
.uri(URI.create("https://item-category-input.retailsvc.com/api/v2/item-categories"))
.header("Authorization", "Bearer " + accessToken)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(payload))
.build();
var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
response = requests.post(
"https://item-category-input.retailsvc.com/api/v2/item-categories",
headers={"Authorization": f"Bearer {access_token}"},
json={
"id": "{{category-id}}",
"name": "{{category-name}}",
"description": "{{category-description}}",
"level": "TOP",
"status": "ACTIVE"
}
)
const response = await fetch(
'https://item-category-input.retailsvc.com/api/v2/item-categories',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
id: '{{category-id}}',
name: '{{category-name}}',
description: '{{category-description}}',
level: 'TOP',
status: 'ACTIVE'
})
}
);
var payload = new {
id = "{{category-id}}",
name = "{{category-name}}",
description = "{{category-description}}",
level = "TOP",
status = "ACTIVE"
};
var content = new StringContent(
JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync(
"https://item-category-input.retailsvc.com/api/v2/item-categories", content);
Response
A successful request returns 202 Accepted.
The Item Categories Input API processes requests asynchronously. A 202 Accepted response means your request has been queued for processing, not that the category has been created yet. The actual creation happens in the background.
To verify your category was created successfully, query the Item Categories API (read endpoint) after a short delay.
Step 2: Create Child Categories
Once the top-level category exists, create child categories by specifying the parentId.
Code Examples
- cURL
- Java
- Python
- Node.js
- .NET
curl -X POST 'https://item-category-input.retailsvc.com/api/v2/item-categories' \
-H 'Authorization: Bearer <your-access-token>' \
-H 'Content-Type: application/json' \
-d '{
"id": "{{child-category-id}}",
"name": "{{child-category-name}}",
"description": "{{child-category-description}}",
"parentId": "{{parent-category-id}}",
"level": "Family",
"code": "{{category-code}}",
"status": "ACTIVE"
}'
var payload = """
{
"id": "{{child-category-id}}",
"name": "{{child-category-name}}",
"description": "{{child-category-description}}",
"parentId": "{{parent-category-id}}",
"level": "Family",
"code": "{{category-code}}",
"status": "ACTIVE"
}
""";
var request = HttpRequest.newBuilder()
.uri(URI.create("https://item-category-input.retailsvc.com/api/v2/item-categories"))
.header("Authorization", "Bearer " + accessToken)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(payload))
.build();
var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
response = requests.post(
"https://item-category-input.retailsvc.com/api/v2/item-categories",
headers={"Authorization": f"Bearer {access_token}"},
json={
"id": "{{child-category-id}}",
"name": "{{child-category-name}}",
"description": "{{child-category-description}}",
"parentId": "{{parent-category-id}}",
"level": "Family",
"code": "{{category-code}}",
"status": "ACTIVE"
}
)
const response = await fetch(
'https://item-category-input.retailsvc.com/api/v2/item-categories',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
id: '{{child-category-id}}',
name: '{{child-category-name}}',
description: '{{child-category-description}}',
parentId: '{{parent-category-id}}',
level: 'Family',
code: '{{category-code}}',
status: 'ACTIVE'
})
}
);
var payload = new {
id = "{{child-category-id}}",
name = "{{child-category-name}}",
description = "{{child-category-description}}",
parentId = "{{parent-category-id}}",
level = "Family",
code = "{{category-code}}",
status = "ACTIVE"
};
var content = new StringContent(
JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync(
"https://item-category-input.retailsvc.com/api/v2/item-categories", content);
Step 3: Build a Complete Hierarchy
Here's an example of building a multi-level category hierarchy. Categories must be created in order from top to bottom.
Code Examples
- cURL
- Java
- Python
- Node.js
- .NET
# Create each level in order. Each request must complete before the next.
# 1. Top node (no parentId)
curl -X POST 'https://item-category-input.retailsvc.com/api/v2/item-categories' \
-H 'Authorization: Bearer <your-access-token>' \
-H 'Content-Type: application/json' \
-d '{"id": "1", "name": "Acme Categories", "level": "TOP", "status": "ACTIVE"}'
# 2. Segment (parentId references top node)
curl -X POST 'https://item-category-input.retailsvc.com/api/v2/item-categories' \
-H 'Authorization: Bearer <your-access-token>' \
-H 'Content-Type: application/json' \
-d '{"id": "11", "name": "Groceries", "parentId": "1", "level": "Segment", "status": "ACTIVE"}'
# 3. Family (parentId references segment)
curl -X POST 'https://item-category-input.retailsvc.com/api/v2/item-categories' \
-H 'Authorization: Bearer <your-access-token>' \
-H 'Content-Type: application/json' \
-d '{"id": "111", "name": "Meat", "parentId": "11", "level": "Family", "status": "ACTIVE"}'
# 4. Class (parentId references family)
curl -X POST 'https://item-category-input.retailsvc.com/api/v2/item-categories' \
-H 'Authorization: Bearer <your-access-token>' \
-H 'Content-Type: application/json' \
-d '{"id": "1111", "name": "Chicken", "parentId": "111", "level": "Class", "status": "ACTIVE"}'
// Categories must be created top-down (parents before children)
var categories = List.of(
Map.of("id", "1", "name", "Acme Categories", "level", "TOP", "status", "ACTIVE"),
Map.of("id", "11", "name", "Groceries", "parentId", "1", "level", "Segment", "status", "ACTIVE"),
Map.of("id", "111", "name", "Meat", "parentId", "11", "level", "Family", "status", "ACTIVE"),
Map.of("id", "1111", "name", "Chicken", "parentId", "111", "level", "Class", "status", "ACTIVE")
);
for (var category : categories) {
var request = HttpRequest.newBuilder()
.uri(URI.create("https://item-category-input.retailsvc.com/api/v2/item-categories"))
.header("Authorization", "Bearer " + accessToken)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(toJson(category)))
.build();
httpClient.send(request, HttpResponse.BodyHandlers.ofString());
}
# Categories must be created top-down (parents before children)
categories = [
{"id": "1", "name": "Acme Categories", "level": "TOP", "status": "ACTIVE"},
{"id": "11", "name": "Groceries", "parentId": "1", "level": "Segment", "status": "ACTIVE"},
{"id": "111", "name": "Meat", "parentId": "11", "level": "Family", "status": "ACTIVE"},
{"id": "1111", "name": "Chicken", "parentId": "111", "level": "Class", "status": "ACTIVE"},
]
for category in categories:
requests.post(
"https://item-category-input.retailsvc.com/api/v2/item-categories",
headers={"Authorization": f"Bearer {access_token}"},
json=category
)
// Categories must be created top-down (parents before children)
const categories = [
{ id: '1', name: 'Acme Categories', level: 'TOP', status: 'ACTIVE' },
{ id: '11', name: 'Groceries', parentId: '1', level: 'Segment', status: 'ACTIVE' },
{ id: '111', name: 'Meat', parentId: '11', level: 'Family', status: 'ACTIVE' },
{ id: '1111', name: 'Chicken', parentId: '111', level: 'Class', status: 'ACTIVE' },
];
for (const category of categories) {
await fetch('https://item-category-input.retailsvc.com/api/v2/item-categories', {
method: 'POST',
headers: { 'Authorization': `Bearer ${accessToken}`, 'Content-Type': 'application/json' },
body: JSON.stringify(category)
});
}
// Categories must be created top-down (parents before children)
var categories = new[] {
new { id = "1", name = "Acme Categories", level = "TOP", status = "ACTIVE", parentId = (string?)null },
new { id = "11", name = "Groceries", level = "Segment", status = "ACTIVE", parentId = "1" },
new { id = "111", name = "Meat", level = "Family", status = "ACTIVE", parentId = "11" },
new { id = "1111", name = "Chicken", level = "Class", status = "ACTIVE", parentId = "111" },
};
foreach (var category in categories) {
var content = new StringContent(JsonSerializer.Serialize(category), Encoding.UTF8, "application/json");
await httpClient.PostAsync("https://item-category-input.retailsvc.com/api/v2/item-categories", content);
}
Working with Additional Properties
Additional Properties allow you to store custom key-value data on categories:
{
"id": "1111",
"name": "Chicken",
"status": "ACTIVE",
"additionalProperties": [
{
"id": "ItemCategoryShelfCode",
"name": "Shelf Code",
"value": "C",
"dataType": "STRING",
"isMandatory": false
},
{
"id": "ForKids",
"name": "Contains Kids Items",
"description": "Flag indicating if category contains items for kids",
"value": "true",
"dataType": "BOOL",
"isMandatory": false
}
]
}
Supported Data Types
| Type | Description |
|---|---|
BOOL | Boolean value (true/false) |
INT | Integer (-2,147,483,648 to 2,147,483,647) |
LONG | Big integer |
DECIMAL | Floating point (~15-17 digits) |
DOUBLE | Floating point (28-29 digits) |
STRING | Text value |
DATE | Date only |
DATETIME | Date and time |
JSON | JSON structure |
ARRAY | List of strings (comma-separated) |
Working with Images
Attach images to categories for display purposes:
{
"id": "1111",
"name": "Chicken",
"status": "ACTIVE",
"images": [
{
"url": "https://example.com/images/chicken.jpg",
"size": "M",
"heightInPixels": 600,
"widthInPixels": 400,
"intendedAudience": ["POS", "ESL"],
"modified": "2024-01-15T10:30:00Z"
}
]
}
Image Sizes
| Size | Description |
|---|---|
THUMB | Thumbnail |
S | Small |
M | Medium |
L | Large |
XL | Extra large |
ORIGINAL | Original size |
Next Steps
Now that you understand Item Categories, you can:
- Explore the full API: See all available endpoints in the Item Category Input API reference
- Link items to categories: Associate your products with categories
- Learn about revision handling: Understand how to manage concurrent updates using the revision concept
Related Resources
- Item Category Input API Reference
- Product, Price and Promotion Concepts
- GS1 GPC Browser
- OAuth2 Authentication
Next: Items - Learn how to create and manage items in your product catalog.