Skip to main content
POST
Upsert Packaging Units

Autorisierungen

Authorization
string
header
erforderlich

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

Body

application/json

One packaging-unit row for POST /api/ppwr/units. Upsert key: internalRef. A row without internalRef can match nothing and is therefore ALWAYS a create — the server names the unit with the next generated PU-<n>; replaying such a row creates another unit. Cells are coerced exactly as the in-app CSV/Excel importer coerces them, so a JSON-native value and its string spelling are equivalent (12 = "12", ["plastic"] = "plastic;paper_board", true = "yes"/"ja"/"1"). An empty or omitted field is a no-op — it never clears a stored value.

name
string
erforderlich

Name of the packaging unit.

packagingType
enum<string>
erforderlich
Verfügbare Optionen:
sales,
grouped,
transport,
ecommerce,
service
role
enum<string>
erforderlich
Verfügbare Optionen:
manufacturer,
importer,
distributor,
authorised_representative,
supplier,
fulfilment_service_provider
notes
string
erforderlich

Required — description and intended use of the packaging. A row without it fails as descriptionRequired, including fill-only updates.

Minimum string length: 1
internalRef
string

Your reference for the unit — the upsert key, unique within your company. Omit it only for rows you never intend to replay (see the schema description).

Maximum string length: 120
supplierName
string | null

Resolved to one of your suppliers by fuzzy name match (case, umlauts, punctuation and legal-form tokens are ignored). A name that matches two or more distinct suppliers fails the row with ambiguousSupplierName — the import never guesses. A name that matches none (and a blank cell) resolves to no supplier: the record lands in your own bucket without a row error, and the supplier is never auto-created.

format
string | null

Packaging form (free text).

recyclabilityGrade
enum<string> | null

A supplied grade is stored as supplier-declared.

Verfügbare Optionen:
A,
B,
C,
non_recyclable,
null
gtin
string | null

GTIN of the unit's PRIMARY size.

Pattern: ^(\d{8}|\d{12}|\d{13}|\d{14})$
widthMm

Width of the primary size, in mm.

heightMm

Height of the primary size, in mm.

depthMm

Depth of the primary size, in mm.

sizeReference
string

The flat spelling of a size: several rows sharing one internalRef, each with its own sizeReference, fold into ONE unit with N sizes. Blank (or equal to internalRef) marks the UNIT row. Prefer sizes[].

Maximum string length: 120
sizeLabel
string | null

Human name of the size. Only a SIZE row may carry it — on a unit row it fails as conflictingSizeRow.

Maximum string length: 120
marketMemberStates

ISO alpha-2 codes (case-insensitive, stored upper-case). A blank column imports as an empty list and is NOT back-filled from your PPWR default.

Pattern: ^[A-Za-z]{2}$
placedUnderOwnBrand

Blank = false; on an update a blank/absent value leaves the stored value unchanged.

modifiesConformity

Blank = false; on an update a blank/absent value leaves the stored value unchanged.

reusable

Art. 11 reusable packaging. Blank = false; on an update a blank/absent value leaves the stored value unchanged.

articleNumbers

Links the unit to existing articles by internal article number. On a SIZE row the link is to that size. An unmatched number is skipped silently (counted in articleNumbersUnmatched), never created and never a row error — unlike POST /api/ppwr/article-links, which errors.

componentCodes

Builds the bill of materials with quantity 1. An unknown code auto-creates a minimal stub component (other, name = code, counted in componentStubsCreated). A code naming two or more live components fails the whole row with ambiguousComponentMatch — the cell has no supplier column to disambiguate with, and the oldest match is never picked. POST /api/ppwr/links reports the same key, so it is not an escape hatch: make the code unique instead.

sizes
object[]

The unit's ADDITIONAL sizes — the primary way to send sizes. On a CREATE the row is one transaction: a refused size (duplicateFormatReference, formatCapReached) rolls the unit back too. On a row matching an EXISTING unit each size is upserted on its own; sizes the payload omits are never deleted.

Maximum array length: 49

Antwort

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 gate, 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
erforderlich

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

updated
string[]
erforderlich

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

skipped
string[]
erforderlich

Identifiers of rows that matched with nothing to change.

failed
object[]
erforderlich

Rows the upsert engine rejected (unknown reference, ambiguous match, …). Its error values are stable machine keys.

invalid
object[]
erforderlich

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.