Skip to main content
POST
Create Bill-of-Materials Links

Authorizations

Authorization
string
header
required

API key generated in Settings > API Keys. Include as Authorization: Bearer <key>.

Body

application/json

One bill-of-materials link for POST /api/v1/ppwr/links. Create-only and idempotent on (specInternalRef, componentCode) — a replayed row comes back as skipped. Unknown unit references and component codes are row errors, never auto-created.

specInternalRef
string
required

internalRef of an existing packaging unit.

Minimum string length: 1
componentCode
string
required

code of an existing component. An ambiguous code is the row error ambiguousComponentMatch.

Minimum string length: 1
quantity
integer | null

Pieces of this component in the unit. Blank = 1.

Required range: x >= 1
massGrams
string | null

This unit's own mass for ONE piece of the component, in grams. Blank/omitted = the component's own mass applies; on a replayed row a blank never clears a mass already stored.

formatReference
string | null

Name a SIZE of this unit and massGrams is stored for THAT size only, leaving the unit's own mass untouched. A reference naming no size of this unit is the row error unknownFormatRef and the link is NOT created.

Maximum string length: 120

Response

Intake result (partial accept — see the schema).

Result of a synchronous PPWR intake. Partial accept: valid rows commit even when other rows are invalid or failed — the one exception is the 409 overwrite confirmation, which is all-or-nothing. Idempotent: replaying an identical request changes nothing (matched rows return as skipped), except unit rows without internalRef, which are always creates.

imported
integer
required

ENTITIES created (units, components, links) — never sizes.

updated
string[]
required

Identifiers of rows whose existing match changed. A size created on an existing unit appears as <unit ref> / <size ref>.

skipped
string[]
required

Identifiers of rows that matched with nothing to change.

failed
object[]
required

Rows the upsert engine rejected (unknown reference, ambiguous match, a new unit over the plan's unit quota → packagingUnitQuotaReached, …). A row refused before its write (these, and a new unit over the quota) writes nothing — not even the supplier it names; a unit written whose component or article link then failed is reported here with that link's key. Its error values are stable machine keys.

invalid
object[]
required

Rows rejected by schema validation before the engine ran. Most error values are stable machine keys, but a field with no custom message falls back to the validator's own English text — match on the key, fall back to displaying the string.

sizesCreated
integer

Unit intake only: sizes created for the rows' units.

articleNumbersUnmatched
integer

Unit intake only: distinct articleNumbers no live article matched. Skipped, never a row error.

articleLinksCreated
integer

Unit intake only: unit⇄article links created from articleNumbers.

Unit intake only: unit⇄component links created from componentCodes.

componentStubsCreated
integer

Unit intake only: minimal placeholder components created for unknown componentCodes.

suppliersCreated
string[]

Unit + component intake: names of the name-only suppliers created for supplierNames that matched no existing supplier.

unitsWithoutComponents
integer

Unit intake only: units created with neither componentCodes nor a material. They hold no component yet, so no regulated value can be recorded on them — send componentCodes, or material for single-part packaging.

mainPartsCreated
integer

Unit intake only: main-part components created from rows' material (one per unit that had no component yet).