Create Manufacturing Order
POST/api/manufacturing/manufacturing-orders
Create a draft MO from a BOM. Hydrates component + output + operation snapshot lines from the BOM.
manufacturing:writeGrant this scope to your token under Settings → Developer → Personal Access Tokens.
For outsourced orders (production_method: outsourced) the request also accepts: contractor_supplier_id (required for outsourced, integer, must be a supplier flagged as a manufacturing contractor); outsourced_cost_basis (optional, string, one of: toll, hybrid) - how the contractor's product charge is costed into the finished output. toll = you own all component materials and the charge is a processing cost only; hybrid = the contractor supplies additional materials of their own and the charge is capitalized into output cost. When omitted the contractor's default_outsourced_cost_basis applies, falling back to hybrid; service_fee_amount (optional, numeric, min 0). These three fields are rejected for in_house orders.
Per-unit tolling rate (service_fee_rate): instead of a flat service_fee_amount, you can supply a per-unit rate. The backing purchase order carries a projected fee of rate x planned_quantity, and each receipt re-trues the fee line to rate x max(planned_quantity, total produced) so cost recognition always matches quantity actually received - including over- and under-production. If omitted, the contractor's default rate applies when one is configured.
Upstream planning (optional, default off). Send plan_upstream: true to also raise the draft orders that supply this one. It applies only when the product being made is contract-manufactured: the stages feeding it are raised recursively, each planned at required ÷ that stage's expected yield (needing 11,280 of a 94%-yield stage plans 12,000), routed to ship into the warehouse that will consume it, and only for the shortfall after stock on hand. Everything raised is a draft, so nothing reaches a vendor until it is confirmed. Omit the field, or send false, to create exactly the order you posted — which is what an ordinary multi-level recipe does either way.
Request
Responses
- 200
- 401
- 403
- 422
- 429
Successful response
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.
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.