Bill of Materials (BOM) API
Overview
The BOM API provides comprehensive functionality for managing Bill of Materials definitions that specify component requirements for assembling parent items. This API supports the complete BOM lifecycle including creation, component synchronization, header updates, and archival operations.
Base URL: /api/boms
Key Features
- Component Definition: Define "recipes" for manufacturing operations
- Component Explosion: Calculate material requirements for production quantities
- Line Synchronization: Atomic update of all component lines
- Validation: Circular reference prevention and component validation
- Pagination Support: Efficient handling of large BOM catalogs
- Soft Delete: Archive and restore with history preservation
- Integration Ready: Seamless integration with assembly transactions
Core Endpoints
1. Get BOMs (with Pagination)
Retrieves BOMs with pagination and optional filtering.
GET /api/boms?pageNumber=1&pageSize=50&searchTerm=widget&parentItemId={guid}
Accept: application/json
Query Parameters:
pageNumber(optional): Page number, 1-based (default: 1)pageSize(optional): BOMs per page (default: 50, max: 200)searchTerm(optional): Search in BOM name, parent item number, or descriptionparentItemId(optional): Filter by specific parent item (Guid)
Response:
{
"items": [
{
"id": "bom-001-id",
"name": "Premium Widget Assembly",
"description": "Primary assembly process for premium widgets",
"parentItemId": "parent-item-id",
"parentItemNumber": "WIDGET-001",
"parentItemName": "Premium Widget",
"producedUnitOfMeasureId": "unit-each-id",
"producedUnitSymbol": "EA",
"producedUnitName": "Each",
"componentCount": 5,
"isActive": true,
"createdDate": "2025-01-15T10:00:00Z",
"modifiedDate": "2025-01-20T14:30:00Z"
}
],
"pageNumber": 1,
"pageSize": 50,
"totalCount": 1,
"totalPages": 1,
"hasPreviousPage": false,
"hasNextPage": false
}
Status Codes:
200 OK- BOMs retrieved successfully400 Bad Request- Invalid query parameters
2. Get BOM by ID
Retrieves a specific BOM with all component lines and details.
GET /api/boms/{id}
Accept: application/json
Path Parameters:
id: BOM ID (Guid)
Response:
{
"id": "bom-001-id",
"name": "Premium Widget Assembly",
"description": "Primary assembly process for premium widgets",
"parentItemId": "parent-item-id",
"parentItemNumber": "WIDGET-001",
"parentItemName": "Premium Widget",
"producedUnitOfMeasureId": "unit-each-id",
"producedUnitSymbol": "EA",
"producedUnitName": "Each",
"lines": [
{
"id": "line-001-id",
"componentItemId": "steel-frame-id",
"componentItemNumber": "RM-STEEL-001",
"componentItemName": "Steel Frame",
"quantity": 1.0,
"unitOfMeasureId": "unit-each-id",
"unitSymbol": "EA",
"unitName": "Each"
},
{
"id": "line-002-id",
"componentItemId": "bolt-m10-id",
"componentItemNumber": "HW-BOLT-M10",
"componentItemName": "Bolt M10",
"quantity": 8.0,
"unitOfMeasureId": "unit-each-id",
"unitSymbol": "EA",
"unitName": "Each"
},
{
"id": "line-003-id",
"componentItemId": "paint-id",
"componentItemNumber": "CHM-PAINT-001",
"componentItemName": "Paint - Blue",
"quantity": 0.5,
"unitOfMeasureId": "unit-liter-id",
"unitSymbol": "L",
"unitName": "Liter"
}
],
"isActive": true,
"createdDate": "2025-01-15T10:00:00Z",
"modifiedDate": "2025-01-20T14:30:00Z"
}
Status Codes:
200 OK- BOM found and returned404 Not Found- BOM not found
3. Create BOM
Creates a new Bill of Materials with component lines.
POST /api/boms
Content-Type: application/json
Request Body:
{
"parentItemId": "parent-item-id",
"producedUnitOfMeasureId": "unit-each-id",
"name": "Premium Widget Assembly",
"description": "Primary assembly process for premium widgets",
"lines": [
{
"componentItemId": "steel-frame-id",
"quantity": 1.0,
"unitOfMeasureId": "unit-each-id"
},
{
"componentItemId": "motor-id",
"quantity": 1.0,
"unitOfMeasureId": "unit-each-id"
},
{
"componentItemId": "bolt-m10-id",
"quantity": 8.0,
"unitOfMeasureId": "unit-each-id"
},
{
"componentItemId": "paint-id",
"quantity": 0.5,
"unitOfMeasureId": "unit-liter-id"
},
{
"componentItemId": "packaging-id",
"quantity": 1.0,
"unitOfMeasureId": "unit-each-id"
}
]
}
Field Descriptions:
parentItemId(required): Item that will be produced (Guid)producedUnitOfMeasureId(required): Unit of measure for produced item (Guid)name(required): Descriptive name for the BOMdescription(optional): Additional details about assembly processlines(required): Array of component line items (minimum 1)componentItemId(required): Component item (Guid)quantity(required): Quantity per unit of parent (decimal, > 0)unitOfMeasureId(required): Unit for component quantity (Guid)
Validation Rules:
- Parent item cannot be its own component (circular reference)
- Each component can appear only once in BOM
- All quantities must be positive
- Minimum one component line required
- Component items should exist and be stockable
Response:
{
"id": "newly-created-bom-id"
}
Status Codes:
201 Created- BOM created successfully400 Bad Request- Validation errors422 Unprocessable Entity- Circular reference or business rule violation404 Not Found- Parent item or component items not found
4. Update BOM Header
Updates BOM name, description, and optionally the produced unit.
PATCH /api/boms/{id}/header
Content-Type: application/json
Path Parameters:
id: BOM ID (Guid)
Request Body:
{
"name": "Premium Widget Assembly - Version 2",
"description": "Updated assembly process with efficiency improvements",
"producedUnitOfMeasureId": "new-unit-id"
}
Field Descriptions:
name(required): Updated BOM namedescription(optional): Updated description (null to clear)producedUnitOfMeasureId(optional): New produced unit (omit to keep existing)
Response:
{
"id": "bom-001-id",
"name": "Premium Widget Assembly - Version 2",
"description": "Updated assembly process with efficiency improvements",
"parentItemId": "parent-item-id",
"parentItemNumber": "WIDGET-001",
"parentItemName": "Premium Widget",
"producedUnitOfMeasureId": "new-unit-id",
"producedUnitSymbol": "EA",
"producedUnitName": "Each",
"lines": [ /* existing lines unchanged */ ],
"isActive": true,
"createdDate": "2025-01-15T10:00:00Z",
"modifiedDate": "2025-01-24T15:30:00Z"
}
Status Codes:
200 OK- Header updated successfully400 Bad Request- Validation errors404 Not Found- BOM not found
5. Sync BOM Lines
Synchronizes component lines with provided list (add/update/remove).
PUT /api/boms/{id}/lines
Content-Type: application/json
Path Parameters:
id: BOM ID (Guid)
Request Body:
{
"lines": [
{
"componentItemId": "steel-frame-id",
"quantity": 1.0,
"unitOfMeasureId": "unit-each-id"
},
{
"componentItemId": "improved-motor-id",
"quantity": 1.0,
"unitOfMeasureId": "unit-each-id"
},
{
"componentItemId": "bolt-m12-id",
"quantity": 8.0,
"unitOfMeasureId": "unit-each-id"
},
{
"componentItemId": "paint-id",
"quantity": 0.3,
"unitOfMeasureId": "unit-liter-id"
},
{
"componentItemId": "packaging-id",
"quantity": 1.0,
"unitOfMeasureId": "unit-each-id"
},
{
"componentItemId": "warranty-card-id",
"quantity": 1.0,
"unitOfMeasureId": "unit-each-id"
}
]
}
Behavior:
- Add: New component items not in current BOM are added
- Update: Existing components have quantities/units updated
- Remove: Components not in provided list are removed
- Atomic: All changes applied in single transaction
Response:
{
"id": "bom-001-id",
"name": "Premium Widget Assembly",
"description": "Primary assembly process",
"parentItemId": "parent-item-id",
"parentItemNumber": "WIDGET-001",
"parentItemName": "Premium Widget",
"producedUnitOfMeasureId": "unit-each-id",
"producedUnitSymbol": "EA",
"producedUnitName": "Each",
"lines": [
/* Updated lines matching request */
],
"isActive": true,
"createdDate": "2025-01-15T10:00:00Z",
"modifiedDate": "2025-01-24T16:00:00Z"
}
Status Codes:
200 OK- Lines synchronized successfully400 Bad Request- Validation errors404 Not Found- BOM not found422 Unprocessable Entity- Circular reference or duplicate component
6. Archive BOM
Archives a BOM (soft delete).
DELETE /api/boms/{id}
Path Parameters:
id: BOM ID (Guid)
Response:
204 No Content
Status Codes:
204 No Content- BOM archived successfully404 Not Found- BOM not found409 Conflict- BOM is referenced by active assembly transactions
Notes:
- BOM is not deleted, just marked inactive (IsActive = false)
- Archived BOMs cannot be used in new assembly operations
- Existing assembly transaction references remain intact
- Can be restored using unarchive endpoint
7. Unarchive BOM
Restores an archived BOM.
POST /api/boms/{id}/unarchive
Path Parameters:
id: BOM ID (Guid)
Response:
204 No Content
Status Codes:
204 No Content- BOM restored successfully404 Not Found- BOM not found400 Bad Request- BOM is not archived
8. Get Archived BOMs
Retrieves all archived BOMs.
GET /api/boms/archived
Accept: application/json
Response:
[
{
"id": "archived-bom-id",
"name": "Obsolete Widget Assembly",
"description": "Old assembly process - no longer used",
"parentItemId": "parent-item-id",
"parentItemNumber": "OLD-WIDGET",
"parentItemName": "Obsolete Widget",
"producedUnitOfMeasureId": "unit-each-id",
"producedUnitSymbol": "EA",
"producedUnitName": "Each",
"componentCount": 4,
"isActive": false,
"createdDate": "2024-01-01T00:00:00Z",
"modifiedDate": "2025-01-20T00:00:00Z"
}
]
Status Codes:
200 OK- Archived BOMs retrieved successfully
Response Schemas
BomSummaryDto (List View)
interface BomSummaryDto {
id: string; // Guid
name: string; // BOM name
description: string | null; // Optional description
// Parent Item
parentItemId: string; // Guid
parentItemNumber: string; // Item number
parentItemName: string; // Item name
// Produced Unit
producedUnitOfMeasureId: string; // Guid
producedUnitSymbol: string; // Unit symbol (EA, kg, etc.)
producedUnitName: string; // Unit name
// Summary Info
componentCount: number; // Number of components
// Audit Fields
isActive: boolean; // Soft delete flag
createdDate: string; // ISO 8601 datetime
modifiedDate: string; // ISO 8601 datetime
}
BomDetailDto (Detail View)
interface BomDetailDto {
id: string; // Guid
name: string; // BOM name
description: string | null; // Optional description
// Parent Item
parentItemId: string; // Guid
parentItemNumber: string; // Item number
parentItemName: string; // Item name
// Produced Unit
producedUnitOfMeasureId: string; // Guid
producedUnitSymbol: string; // Unit symbol
producedUnitName: string; // Unit name
// Component Lines
lines: BomLineDto[]; // Array of components
// Audit Fields
isActive: boolean; // Soft delete flag
createdDate: string; // ISO 8601 datetime
modifiedDate: string; // ISO 8601 datetime
}
interface BomLineDto {
id: string; // Guid
componentItemId: string; // Component item Guid
componentItemNumber: string; // Component item number
componentItemName: string; // Component item name
quantity: number; // Quantity per unit of parent
unitOfMeasureId: string; // Unit Guid
unitSymbol: string; // Unit symbol
unitName: string; // Unit name
}
PagedBomsResult
interface PagedBomsResult {
items: BomSummaryDto[]; // Current page items
pageNumber: number; // Current page (1-based)
pageSize: number; // Items per page
totalCount: number; // Total items across all pages
totalPages: number; // Total number of pages
hasPreviousPage: boolean; // Can navigate to previous page
hasNextPage: boolean; // Can navigate to next page
}
Use Cases and Examples
Use Case 1: Create Complete BOM for Manufacturing
# Create BOM with all components
POST /api/boms
{
"parentItemId": "widget-001-id",
"producedUnitOfMeasureId": "each-unit-id",
"name": "Standard Widget Assembly",
"description": "Primary assembly for standard widget line",
"lines": [
{
"componentItemId": "steel-frame-id",
"quantity": 1.0,
"unitOfMeasureId": "each-unit-id"
},
{
"componentItemId": "motor-id",
"quantity": 1.0,
"unitOfMeasureId": "each-unit-id"
},
{
"componentItemId": "bolt-m10-id",
"quantity": 8.0,
"unitOfMeasureId": "each-unit-id"
},
{
"componentItemId": "paint-id",
"quantity": 0.5,
"unitOfMeasureId": "liter-unit-id"
}
]
}
# Response: BOM created with 4 components
# Ready for assembly operations
Use Case 2: Update BOM with New Components
# Sync lines with new component list
PUT /api/boms/{bom-id}/lines
{
"lines": [
{
"componentItemId": "steel-frame-id",
"quantity": 1.0,
"unitOfMeasureId": "each-unit-id"
},
{
"componentItemId": "improved-motor-id", // Changed
"quantity": 1.0,
"unitOfMeasureId": "each-unit-id"
},
{
"componentItemId": "bolt-m12-id", // Changed from M10 to M12
"quantity": 8.0,
"unitOfMeasureId": "each-unit-id"
},
{
"componentItemId": "paint-id",
"quantity": 0.3, // Reduced quantity
"unitOfMeasureId": "liter-unit-id"
},
{
"componentItemId": "warranty-card-id", // New component
"quantity": 1.0,
"unitOfMeasureId": "each-unit-id"
}
]
}
# Result:
# - Motor changed to improved version
# - Bolts changed from M10 to M12
# - Paint quantity reduced
# - Warranty card added
# - All in single atomic transaction
Use Case 3: Material Requirements Planning
# 1. Get BOM details
GET /api/boms/{bom-id}
# 2. Calculate requirements for production quantity
# If producing 100 units of parent item:
# Steel Frame: 1.0 × 100 = 100 EA
# Motor: 1.0 × 100 = 100 EA
# Bolts M10: 8.0 × 100 = 800 EA
# Paint: 0.5 × 100 = 50 L
# 3. Check inventory availability
# (via Inventory API)
# 4. Create assembly transaction
# (via Transactions API)
Use Case 4: Search BOMs by Parent Item
# Find all BOMs for specific parent item
GET /api/boms?parentItemId=widget-001-id
# Returns all BOMs that produce this item
# Useful for:
# - Multiple production methods
# - Alternate BOMs
# - Version comparison
Use Case 5: Update BOM Documentation
# Update BOM header with new information
PATCH /api/boms/{bom-id}/header
{
"name": "Standard Widget Assembly - Q1 2025",
"description": "Updated assembly process with efficiency improvements. " +
"Uses improved motor and reduced paint consumption."
}
# Components unchanged, only metadata updated
Error Handling
Common Error Responses
Circular Reference Detected (422 Unprocessable Entity):
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.3",
"title": "Unprocessable Entity",
"status": 422,
"detail": "A BOM's parent item cannot be one of its own components."
}
Duplicate Component (400 Bad Request):
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "Validation Error",
"status": 400,
"detail": "Component 'STEEL-FRAME' appears more than once in the BOM."
}
BOM Not Found (404 Not Found):
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.4",
"title": "Not Found",
"status": 404,
"detail": "BOM with ID 'a1b2c3d4-...' was not found."
}
Invalid Quantity (400 Bad Request):
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "Validation Error",
"status": 400,
"errors": {
"lines[0].quantity": ["Quantity must be greater than zero."]
}
}
Cannot Archive Referenced BOM (409 Conflict):
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.8",
"title": "Conflict",
"status": 409,
"detail": "Cannot archive BOM 'Standard Widget Assembly' because it is referenced by active assembly transactions."
}
Best Practices
1. BOM Creation Strategy
// Always include minimum required components
const bom = {
parentItemId: "...",
producedUnitOfMeasureId: "...",
name: "Descriptive Assembly Name",
description: "Clear process description",
lines: [
// All required components
]
};
// Validate before submission:
// - No duplicate components
// - All quantities positive
// - Parent not in components
// - Minimum 1 component
2. Component Synchronization
- Use PUT /lines for complete BOM updates
- Sends entire desired component list
- System handles add/update/remove automatically
- Atomic operation - all or nothing
- Simpler than individual add/remove operations
3. BOM Documentation
- Use clear, descriptive names
- Document production method in description
- Include version information when updating
- Reference engineering change orders (ECOs) in description
4. Material Planning
- Get BOM details before production
- Calculate material requirements (quantity × production)
- Check inventory availability
- Create assembly transaction with BOM reference
Integration with Assembly
Assembly Workflow
Related APIs
- Items API - For managing parent and component items
- Assembly API - For creating assembly transactions
- Inventory API - For checking component availability
- Transactions API - For assembly transaction details
Last Updated: 2025-10-24 | API Version: 1.0 | Status: Active