Preview Simple Assemble / Disassemble (Dry-Run)
POST/api/manufacturing/simple-assemble/preview
U25: Dry-run preview that returns the BOM-derived components (action=assemble) or the kit itself (action=disassemble) along with required and live on-hand quantities at the chosen warehouse. Does NOT create an MO or consume inventory — used to render a shortage warning beneath the Simple Mode form before submit.
manufacturing:writeGrant this scope to your token under Settings → Developer → Personal Access Tokens.
Body fields (same validation as POST /simple-assemble):
kit_product_id(int, required) — product to assemble or disassemblequantity(numeric, required, >0)warehouse_id(int, required)warehouse_location_id(int, optional)action_date(date, required)action(string, optional) —assemble(default) ordisassemble
Each line is also valued: unit_cost is the weighted-average cost of the product's available FIFO layers at the chosen warehouse (catalog cost when out of stock), and extended_cost = unit_cost × required_quantity. total_input_cost sums the line values. For action=assemble the preview values the order the way it will post: required_quantity includes the recipe's expected scrap (expected_scrap_quantity), costs adds the recipe operations' labor, overhead and fixed cost to the component materials (total = order cost), byproducts claim their value off the material pool first (byproduct_value), and the rest is split across the primary and co-products by the recipe's cost allocation method. outputs lists every recipe output with its expected total_cost / unit_cost; output is the kit's own share (what its FIFO layer will carry). For action=disassemble, costs and output are null and outputs is empty.
Response shape:
{
"data": {
"action": "assemble",
"has_shortage": true,
"total_input_cost": 39.6,
"costs": {
"materials": 39.6,
"expected_scrap": 3.6,
"labor": 20,
"overhead": 0,
"fixed": 6,
"byproduct_value": 0,
"total": 65.6
},
"output": {
"product_id": 42,
"sku": "KIT-001",
"name": "Sample Kit",
"quantity": 3,
"total_cost": 65.6,
"unit_cost": 21.8667
},
"outputs": [
{
"product_id": 42,
"sku": "KIT-001",
"name": "Sample Kit",
"role": "primary",
"quantity": 3,
"total_cost": 65.6,
"unit_cost": 21.8667
}
],
"lines": [
{
"product_id": 91,
"sku": "COMP-A",
"name": "Component A",
"required_quantity": 6.6,
"expected_scrap_quantity": 0.6,
"available_quantity": 5,
"uom": "EACH",
"unit_cost": 5,
"extended_cost": 33,
"shortage": true
},
{
"product_id": 92,
"sku": "COMP-B",
"name": "Component B",
"required_quantity": 3.3,
"expected_scrap_quantity": 0.3,
"available_quantity": 12,
"uom": "EACH",
"unit_cost": 2,
"extended_cost": 6.6,
"shortage": false
}
]
}
}
Request
Responses
- 200
- 401
- 403
- 422
- 429
OK
Response Headers
Unauthenticated — the bearer token is missing, revoked, expired, or malformed. Never retry automatically; fix the credential. See the Errors guide.
Forbidden — the token lacks a required scope, the endpoint is not available to API tokens, or the user behind the token lacks the permission. A human must adjust the token scopes or user permissions; do not retry.
Unprocessable Entity
Response Headers
Rate limited — platform limit is 1,000 requests/min; individual tokens may carry lower limits. Honor the Retry-After header before retrying. See the Rate Limits guide.