Update BOM
PUT/api/manufacturing/boms/:id
Update a BOM. All fields are optional — omitted fields keep their current values.
manufacturing:writeGrant this scope to your token under Settings → Developer → Personal Access Tokens.
default_consumption_method (nullable, enum: forward_flush | backflush) sets the BOM-level default inherited by component lines that omit their own consumption_method; a per-line consumption_method always overrides it. A component line submitted with an explicit consumption_method: null behaves exactly like omitting the field — a new line inherits the BOM default (falling back to forward_flush), and an existing line keeps its current method. Changing consumption methods only affects manufacturing orders confirmed after the change — each order snapshots the method per component line at confirmation, so open orders keep consuming the way they were confirmed.
Auth: requires Bearer token.
cost_classification (optional, labor|overhead, default labor) sets the expense classification independently of the rate basis: labor posts the operation's variable cost to the Labor bucket (marked up by the work center's overhead %); overhead posts machine/tooling-style cost to the Overhead bucket with no additional markup.
Validation: a component line's product_id may not equal the BOM's own product_id or any output_lines.*.product_id — a BOM cannot consume its own output as a component. Violations return 422 with an error on component_lines.{index}.product_id.
Units: uom_id is optional on every output and component line. When omitted, the line is measured in that line product's own stock unit, so a product stocked by weight, volume or length never needs a conversion it does not have. Send uom_id only to override that deliberately — it must be a unit enabled on the product, or the request is rejected with a 422 naming the unit and product.
Contractor-supplied components: set component_lines[].is_contractor_supplied to true when the contract manufacturer provides that component from their own stock. It stays in the recipe and in lot genealogy, but is never allocated from your inventory, never reported as short, and never costed into the finished good — its cost is already inside the contractor's price on the purchase order. Defaults to false; omit the key on an update and the stored value is left unchanged.
Request
Responses
- 200
- 401
- 403
- 404
- 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.
Not found — no record with the given identifier (or the route does not exist). Verify the ID before retrying.
Validation failed — the body is a field → messages map (Laravel shape) or the platform envelope with a stable machine-readable code. Fix the payload and resubmit.
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.