Skip to main content

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 description
  • parentItemId (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 successfully
  • 400 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 returned
  • 404 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 BOM
  • description (optional): Additional details about assembly process
  • lines (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 successfully
  • 400 Bad Request - Validation errors
  • 422 Unprocessable Entity - Circular reference or business rule violation
  • 404 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 name
  • description (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 successfully
  • 400 Bad Request - Validation errors
  • 404 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 successfully
  • 400 Bad Request - Validation errors
  • 404 Not Found - BOM not found
  • 422 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 successfully
  • 404 Not Found - BOM not found
  • 409 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 successfully
  • 404 Not Found - BOM not found
  • 400 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



Last Updated: 2025-10-24 | API Version: 1.0 | Status: Active