Items API
Overview
The Items API provides comprehensive functionality for managing item master data using a composition-based architecture. This API supports the complete item lifecycle from creation through updates, archival, and restoration, with full support for stockable behavior management.
Base URL: /api/items
Key Features
- Composition-Based Architecture: Flexible item model with optional stockable behavior
- Advanced Filtering: Search by term, category, unit class, and stockable status
- Pagination Support: Efficient handling of large item catalogs
- Soft Delete: Archive and restore capabilities with complete history
- Unit Class Flexibility: Items reference unit classes, not specific units
- Category Classification: Optional hierarchical categorization
Core Endpoints
1. Get All Items (with Filtering)
Retrieves items with advanced filtering and pagination support.
GET /api/items?searchTerm=widget&categoryId={guid}&isStockable=true&pageNumber=1&pageSize=50
Accept: application/json
Query Parameters:
searchTerm(optional): Search across item number, name, and descriptioncategoryId(optional): Filter by category ID (Guid)unitClassId(optional): Filter by unit class ID (Guid)isStockable(optional): Filter by stockable statusnull- All itemstrue- Stockable items onlyfalse- Non-stockable items only
pageNumber(optional): Page number, 1-based (default: 1)pageSize(optional): Items per page (default: 50, max: 200)
Response:
[
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"itemNumber": "WIDGET-001",
"name": "Premium Widget",
"description": "High-quality widget for manufacturing",
"categoryId": "cat-12345",
"categoryName": "Widgets",
"categoryPath": "Products > Widgets",
"defaultUnitClassId": "unit-class-weight",
"defaultUnitClassName": "Weight",
"taxGroupId": "tax-group-standard",
"taxGroupName": "Standard Tax",
"isStockable": true,
"stockableBehavior": {
"allowNegativeStock": false,
"trackByLocation": true
},
"isActive": true,
"createdDate": "2025-01-15T10:00:00Z",
"modifiedDate": "2025-01-20T14:30:00Z"
}
]
Status Codes:
200 OK- Items retrieved successfully400 Bad Request- Invalid query parameters
2. Get Item by ID
Retrieves a specific item with all details including stockable behavior.
GET /api/items/{id}
Accept: application/json
Path Parameters:
id: Item ID (Guid)
Response:
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"itemNumber": "RM-STEEL-001",
"name": "Steel Plate 1/4 inch",
"description": "Cold rolled steel plate, 1/4 inch thickness",
"categoryId": "raw-materials-category-id",
"categoryName": "Raw Materials",
"categoryPath": "Materials > Metals > Steel",
"defaultUnitClassId": "weight-unit-class-id",
"defaultUnitClassName": "Weight",
"taxGroupId": "raw-materials-tax-group",
"taxGroupName": "Raw Materials Tax",
"isStockable": true,
"stockableBehavior": {
"allowNegativeStock": false,
"trackByLocation": true
},
"isActive": true,
"createdDate": "2025-01-10T08:00:00Z",
"modifiedDate": "2025-01-15T12:00:00Z"
}
Status Codes:
200 OK- Item found and returned404 Not Found- Item with specified ID not found
3. Create Item
Creates a new item with optional stockable behavior.
POST /api/items
Content-Type: application/json
Request Body:
{
"itemNumber": "WIDGET-100",
"name": "Standard Widget",
"description": "General purpose widget for assembly operations",
"categoryId": "widget-category-id",
"defaultUnitClassId": "weight-unit-class-id",
"taxGroupId": "standard-tax-group-id",
"allowNegativeStock": false,
"trackByLocation": true
}
Field Descriptions:
itemNumber(required): Unique item identifiername(required): Display name for the itemdescription(optional): Detailed descriptioncategoryId(optional): Category assignmentdefaultUnitClassId(optional): Default unit class for transactionstaxGroupId(optional): Tax group for finance integrationallowNegativeStock(optional): Enable stockable behavior with negative stock controltrackByLocation(optional): Enable stockable behavior with location tracking
Stockable Behavior Logic:
- If
allowNegativeStockortrackByLocationis provided → Item created with StockableBehavior - If both are null/omitted → Item created without StockableBehavior (non-stockable)
Response:
{
"id": "newly-created-item-id",
"itemNumber": "WIDGET-100",
"name": "Standard Widget",
"description": "General purpose widget for assembly operations",
"categoryId": "widget-category-id",
"categoryName": "Widgets",
"categoryPath": "Products > Widgets",
"defaultUnitClassId": "weight-unit-class-id",
"defaultUnitClassName": "Weight",
"taxGroupId": "standard-tax-group-id",
"taxGroupName": "Standard Tax",
"isStockable": true,
"stockableBehavior": {
"allowNegativeStock": false,
"trackByLocation": true
},
"isActive": true,
"createdDate": "2025-01-24T10:00:00Z",
"modifiedDate": "2025-01-24T10:00:00Z"
}
Status Codes:
201 Created- Item created successfully400 Bad Request- Validation errors409 Conflict- Item number already exists
4. Update Item
Updates basic item information and stockable behavior.
PATCH /api/items/{id}
Content-Type: application/json
Path Parameters:
id: Item ID (Guid)
Request Body:
{
"name": "Premium Widget - Updated",
"description": "Enhanced widget with improved specifications",
"categoryId": "new-category-id",
"defaultUnitClassId": "new-unit-class-id",
"taxGroupId": "new-tax-group-id",
"allowNegativeStock": true,
"trackByLocation": false
}
Field Descriptions:
name(required): Updated display namedescription(optional): Updated descriptioncategoryId(optional): New category or null to cleardefaultUnitClassId(optional): New unit class or null to cleartaxGroupId(optional): New tax group or null to clearallowNegativeStock(optional): Update or add stockable behaviortrackByLocation(optional): Update or add stockable behavior
Stockable Behavior Update Logic:
- Both
allowNegativeStockandtrackByLocationnull → Remove stockable behavior (make non-stockable) - One or both provided → Create or update stockable behavior
Response:
{
"id": "item-id",
"itemNumber": "WIDGET-100",
"name": "Premium Widget - Updated",
"description": "Enhanced widget with improved specifications",
"categoryId": "new-category-id",
"categoryName": "New Category",
"categoryPath": "Products > New Category",
"defaultUnitClassId": "new-unit-class-id",
"defaultUnitClassName": "New Unit Class",
"taxGroupId": "new-tax-group-id",
"taxGroupName": "New Tax Group",
"isStockable": true,
"stockableBehavior": {
"allowNegativeStock": true,
"trackByLocation": false
},
"isActive": true,
"createdDate": "2025-01-24T10:00:00Z",
"modifiedDate": "2025-01-24T15:30:00Z"
}
Status Codes:
200 OK- Item updated successfully400 Bad Request- Validation errors404 Not Found- Item not found
5. Archive Item
Archives an item (soft delete).
DELETE /api/items/{id}
Path Parameters:
id: Item ID (Guid)
Response:
204 No Content
Status Codes:
204 No Content- Item archived successfully404 Not Found- Item not found409 Conflict- Item cannot be archived (has active references)
Notes:
- Item is not deleted from database, just marked inactive (IsActive = false)
- Archived items cannot be used in new transactions
- Existing references remain intact
- Can be restored using unarchive endpoint
6. Unarchive Item
Restores an archived item.
POST /api/items/{id}/unarchive
Path Parameters:
id: Item ID (Guid)
Response:
204 No Content
Status Codes:
204 No Content- Item restored successfully404 Not Found- Item not found400 Bad Request- Item is not archived
7. Get Archived Items
Retrieves all archived items.
GET /api/items/archived
Accept: application/json
Response:
[
{
"id": "archived-item-id",
"itemNumber": "OBSOLETE-001",
"name": "Obsolete Widget",
"description": "No longer in use",
"categoryId": null,
"categoryName": null,
"categoryPath": null,
"defaultUnitClassId": null,
"defaultUnitClassName": null,
"taxGroupId": null,
"taxGroupName": null,
"isStockable": false,
"stockableBehavior": null,
"isActive": false,
"createdDate": "2024-01-01T00:00:00Z",
"modifiedDate": "2025-01-20T00:00:00Z"
}
]
Status Codes:
200 OK- Archived items retrieved successfully
Response Schema
ItemDto
interface ItemDto {
id: string; // Guid
itemNumber: string; // Unique business identifier
name: string; // Display name
description: string | null; // Optional details
// Category
categoryId: string | null; // Guid or null
categoryName: string | null; // Display name
categoryPath: string | null; // Full hierarchy path
// Unit Class
defaultUnitClassId: string | null; // Guid or null
defaultUnitClassName: string | null; // Display name
// Tax Group
taxGroupId: string | null; // Guid or null
taxGroupName: string | null; // Display name
// Stockable Behavior
isStockable: boolean; // Computed from behavior presence
stockableBehavior: StockableBehaviorDto | null;
// Audit Fields
isActive: boolean; // Soft delete flag
createdDate: string; // ISO 8601 datetime
modifiedDate: string; // ISO 8601 datetime
}
interface StockableBehaviorDto {
allowNegativeStock: boolean; // Allow inventory to go negative
trackByLocation: boolean; // Require location for transactions
}
Use Cases and Examples
Use Case 1: Create Stockable Item for Raw Materials
# Create steel plate item with inventory tracking
POST /api/items
{
"itemNumber": "RM-STEEL-001",
"name": "Steel Plate 1/4 inch",
"description": "Cold rolled steel plate, 1/4 inch thickness",
"categoryId": "raw-materials-category-id",
"defaultUnitClassId": "weight-unit-class-id",
"taxGroupId": "raw-materials-tax-group",
"allowNegativeStock": false,
"trackByLocation": true
}
# Response: Item created with stockable behavior
# Can now be used in inventory transactions
# Requires location specification on all transactions
# Will prevent negative stock
Use Case 2: Create Non-Stockable Service Item
# Create service item without inventory tracking
POST /api/items
{
"itemNumber": "SRV-INSTALL",
"name": "Installation Service",
"description": "Professional installation service - hourly rate",
"categoryId": "services-category-id"
# Note: No allowNegativeStock or trackByLocation = non-stockable
}
# Response: Item created without stockable behavior
# Can be used for billing and documentation
# Will NOT track inventory
# Cannot be used in inventory transactions
Use Case 3: Convert Non-Stockable to Stockable
# Update existing non-stockable item to stockable
PATCH /api/items/{id}
{
"name": "Widget XYZ",
"allowNegativeStock": true,
"trackByLocation": true
}
# Response: Item now has stockable behavior
# Inventory tracking enabled
# Can now be used in transactions
Use Case 4: Search Stockable Items by Category
# Find all stockable items in specific category
GET /api/items?categoryId=widget-category-id&isStockable=true&pageSize=100
# Returns: All stockable items in widget category
# Useful for inventory reports
# Can be filtered further with searchTerm
Use Case 5: Find Items Needing Unit Class Assignment
# Find items without unit class
GET /api/items?unitClassId=null
# Returns: Items that need unit class configuration
# Useful for data cleanup
# Items without unit class have limited transaction support
Error Handling
Common Error Responses
Item Number Already Exists (409 Conflict):
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.8",
"title": "Conflict",
"status": 409,
"detail": "An item with number 'WIDGET-001' already exists."
}
Validation Error (400 Bad Request):
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "Validation Error",
"status": 400,
"errors": {
"itemNumber": ["Item number is required."],
"name": ["Item name is required."]
}
}
Item Not Found (404 Not Found):
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.4",
"title": "Not Found",
"status": 404,
"detail": "Item with ID 'a1b2c3d4-e5f6-7890-abcd-ef1234567890' was not found."
}
Cannot Archive Item with Active References (409 Conflict):
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.8",
"title": "Conflict",
"status": 409,
"detail": "Cannot archive item 'WIDGET-001' because it has active references in BOMs or open transactions."
}
Best Practices
1. Item Creation Strategy
// For physical products (stockable)
const stockableItem = {
itemNumber: "PROD-001",
name: "Physical Product",
allowNegativeStock: false, // Strict inventory control
trackByLocation: true // Required for warehouse management
};
// For services (non-stockable)
const serviceItem = {
itemNumber: "SRV-001",
name: "Service Item"
// No stockable properties = non-stockable
};
2. Search and Filter Optimization
- Use
searchTermfor general searches (searches number, name, description) - Use
isStockableto separate physical products from services - Use
categoryIdfor category-specific reports - Use pagination for large catalogs (pageSize: 50-100)
3. Unit Class Assignment
- Assign unit class at creation if known
- Use Weight class for materials measured by weight
- Use Count class for discrete items (each, dozen)
- Use Volume class for liquids and gases
- Items without unit class have limited transaction support
4. Stockable Behavior Management
- Set
allowNegativeStock: falsefor strict inventory control - Set
allowNegativeStock: truefor backorder support - Set
trackByLocation: truefor warehouse management - Set
trackByLocation: falsefor simplified tracking
Related APIs
- Categories API - For managing item categories
- Units API - For managing unit classes and units
- Transactions API - For inventory transactions using items
- BOM API - For managing bill of materials
- Inventory API - For querying item inventory levels
Last Updated: 2025-10-24 | API Version: 1.0 | Status: Active