> ## Documentation Index
> Fetch the complete documentation index at: https://help.polygon-one.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Push Material Tonnage

> The aggregate-kg mode, for a producer whose packaging composition is not modelled unit by unit — and the same rows that declare the ambiguous material families (metals, composites) in SKU-grain mode. **LUCID (Germany) only.** Synchronous, upsert keyed on (`zsvrCategory`, `periodYear`, `market`). A category a human entered in the app is reported in `skipped` with `manualOverridePresent` rather than overwritten; delete that override in the app and the next push recreates it as ERP-owned. At most 1000 rows per request (`400` otherwise). Requires `packaging:write`; customer workspace with the PPWR module enabled — see the guide.



## OpenAPI

````yaml POST /api/ppwr/tonnage
openapi: 3.1.0
info:
  title: Polygon One Compliance API
  description: >-
    API for integrating ERP systems with the Polygon One EUDR Compliance
    Platform. Allows management of Articles, Suppliers, Orders, and Due
    Diligence Statements (DDS). PPWR packaging master data, the SKU quantity
    feed and Mengenmeldung reports are covered by the PPWR groups.
  version: 1.0.0
servers:
  - url: https://app.polygon-one.com
    description: Production Server
security:
  - bearerAuth: []
paths:
  /api/ppwr/tonnage:
    post:
      summary: Push Material Tonnage
      description: >-
        The aggregate-kg mode, for a producer whose packaging composition is not
        modelled unit by unit — and the same rows that declare the ambiguous
        material families (metals, composites) in SKU-grain mode. **LUCID
        (Germany) only.** Synchronous, upsert keyed on (`zsvrCategory`,
        `periodYear`, `market`). A category a human entered in the app is
        reported in `skipped` with `manualOverridePresent` rather than
        overwritten; delete that override in the app and the next push recreates
        it as ERP-owned. At most 1000 rows per request (`400` otherwise).
        Requires `packaging:write`; customer workspace with the PPWR module
        enabled — see the guide.
      operationId: pushPpwrTonnage
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - type: array
                  items:
                    $ref: '#/components/schemas/PpwrTonnageRow'
                  maxItems: 1000
                  description: Bare array form.
                - $ref: '#/components/schemas/PpwrTonnageIntakeInput'
      responses:
        '200':
          description: Tonnage result
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PpwrTonnageResult'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  schemas:
    PpwrTonnageRow:
      type: object
      description: >-
        One aggregate-tonnage row for `POST /api/ppwr/tonnage`. Upsert key:
        (`zsvrCategory`, `periodYear`, `market`). LUCID (Germany) only.
      required:
        - periodYear
        - market
        - zsvrCategory
        - tonnageKg
      properties:
        periodYear:
          type:
            - integer
            - string
          minimum: 2000
          maximum: 2100
        market:
          type: string
          pattern: ^[A-Za-z]{2}$
          description: ISO alpha-2 market code.
        zsvrCategory:
          $ref: '#/components/schemas/ZsvrCategory'
        tonnageKg:
          type: number
          minimum: 0
          description: >-
            Kilograms placed. A JSON **number** — unlike the intake row schemas,
            this field is not string-coerced.
        note:
          type:
            - string
            - 'null'
          maxLength: 500
    PpwrTonnageIntakeInput:
      type: object
      description: Envelope form for the tonnage intake.
      required:
        - rows
      properties:
        rows:
          type: array
          items:
            $ref: '#/components/schemas/PpwrTonnageRow'
          maxItems: 1000
    PpwrTonnageResult:
      type: object
      description: >-
        Result of the synchronous tonnage intake. A category a human entered in
        the app is reported in `skipped`, never overwritten; delete the override
        in the app and the next push recreates it as ERP-owned.
      required:
        - written
        - skipped
        - failed
        - invalid
      properties:
        written:
          type: array
          items:
            type: object
            properties:
              periodYear:
                type: integer
              market:
                type: string
              zsvrCategory:
                $ref: '#/components/schemas/ZsvrCategory'
        skipped:
          type: array
          items:
            type: object
            properties:
              periodYear:
                type: integer
              market:
                type: string
              zsvrCategory:
                $ref: '#/components/schemas/ZsvrCategory'
              reason:
                type: string
                enum:
                  - manualOverridePresent
        failed:
          type: array
          items:
            $ref: '#/components/schemas/PpwrIndexedRowError'
          description: >-
            Rows that hit an unexpected database error (`dbError`). Reported per
            row — the categories that committed are kept.
        invalid:
          type: array
          items:
            $ref: '#/components/schemas/PpwrIndexedRowError'
          description: Rows rejected by schema validation.
    ZsvrCategory:
      type: string
      enum:
        - '10000'
        - '20000'
        - '30000'
        - '40000'
        - '50000'
        - '60000'
        - '70000'
        - '80000'
      description: >-
        VerpackG material category: `10000` glass, `20000` paper/board/carton,
        `30000` ferrous metals, `40000` aluminium, `50000` plastics, `60000`
        beverage cartons, `70000` other composites, `80000` other materials.
    PpwrIndexedRowError:
      type: object
      description: >-
        A row rejected before the upsert engine ran, reported by its position in
        the request.
      properties:
        index:
          type: integer
          description: 0-based position of the row in the request.
        identifier:
          type: string
        error:
          type: string
          description: >-
            Usually a stable machine key; a field with no custom message falls
            back to the validator's own English text.
    ErrorResponse:
      type: object
      properties:
        error:
          type: string
        details:
          description: Additional error details (e.g. validation issues)
      required:
        - error
  responses:
    BadRequest:
      description: Invalid request data
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Unauthorized:
      description: Invalid or missing API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Forbidden:
      description: Insufficient permissions for this resource
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    InternalError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: >-
        API key generated in Settings > API Keys. Include as `Authorization:
        Bearer <key>`.

````