{
  "openapi": "3.1.0",
  "info": {
    "title": "nuqo API",
    "version": "1",
    "description": "Read your finalized quotes, their work plans and parts lists, the events that tell your system what changed, and your parts; push your parts. Every field is described in English (description) and German (x-description-de); x-unit names a field's unit."
  },
  "servers": [
    {
      "url": "https://backend.nuqo.io"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "paths": {
    "/api/v1/events": {
      "get": {
        "operationId": "list_events",
        "summary": "What happened to your quotes",
        "x-summary-de": "Was mit Ihren Angeboten geschah",
        "description": "Your organization's events after the id you send, oldest first: a quote finalized, or reopened for a revision. Store next_after and send it as after next time; a full page means more are waiting. Events are kept 30 days.",
        "x-description-de": "Die Ereignisse Ihres Betriebs nach der gesendeten ID, das älteste zuerst: ein Angebot finalisiert, oder für eine Revision wieder geöffnet. Speichern Sie next_after und senden Sie es beim nächsten Mal als after; eine volle Seite heißt, dass weitere warten. Ereignisse werden 30 Tage aufbewahrt.",
        "x-scope": "read",
        "parameters": [
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "description": "Answer only events with a higher id.",
            "x-description-de": "Nur Ereignisse mit höherer ID antworten."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 100
            },
            "description": "How many to answer at most.",
            "x-description-de": "Wie viele höchstens geantwortet werden."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventList"
                },
                "example": {
                  "data": [
                    {
                      "id": 20871,
                      "type": "quote.reopened",
                      "created_at": "2026-10-19T08:41:55.120334Z",
                      "quote": {
                        "id": 5120,
                        "revision": 2
                      }
                    },
                    {
                      "id": 20872,
                      "type": "quote.finalized",
                      "created_at": "2026-10-20T14:03:11.394120Z",
                      "quote": {
                        "id": 5120,
                        "revision": 2
                      }
                    }
                  ],
                  "next_after": 20872
                }
              }
            }
          },
          "400": {
            "description": "invalid_request",
            "x-error-codes": [
              "invalid_request"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "api_key_required, invalid_api_key",
            "x-error-codes": [
              "api_key_required",
              "invalid_api_key"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "organization_inactive, insufficient_scope",
            "x-error-codes": [
              "organization_inactive",
              "insufficient_scope"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "405": {
            "description": "method_not_allowed",
            "x-error-codes": [
              "method_not_allowed"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/materials": {
      "get": {
        "operationId": "list_materials",
        "summary": "Your parts, least recently changed first",
        "x-summary-de": "Ihre Teile, die am längsten unveränderten zuerst",
        "description": "The rows of your Materials tab in nuqo, a page at a time. Page with next_cursor while has_more is true, then keep the last next_cursor and poll with it: it answers only the parts changed since. A change is served once it is 3 minutes old.",
        "x-description-de": "Die Zeilen Ihres Reiters Materialien in nuqo, seitenweise. Blättern Sie mit next_cursor, solange has_more true ist, dann behalten Sie den letzten next_cursor und fragen damit regelmäßig: er antwortet nur die seither geänderten Teile. Eine Änderung wird geliefert, sobald sie 3 Minuten alt ist.",
        "x-scope": "read",
        "parameters": [
          {
            "name": "changed_since",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Only parts whose row changed at or after this time. Without an offset it is UTC.",
            "x-description-de": "Nur Teile, deren Zeile sich zu oder nach diesem Zeitpunkt geändert hat. Ohne Zeitzone gilt UTC."
          },
          {
            "name": "include_removed",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "true also answers the parts a user deleted, with status \"obsolete\".",
            "x-description-de": "true antwortet auch die Teile, die ein Nutzer gelöscht hat, mit status \"obsolete\"."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "A next_cursor this API answered, passed back unchanged: reads on after the last row it ended on. Never build one.",
            "x-description-de": "Ein next_cursor, den diese API geantwortet hat, unverändert zurückgegeben: liest nach der letzten Zeile weiter, auf der er endete. Bauen Sie nie selbst einen."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "description": "How many to answer at most.",
            "x-description-de": "Wie viele höchstens geantwortet werden."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MaterialList"
                },
                "example": {
                  "materials": [
                    {
                      "listing_id": 918204,
                      "part_id": 4410273,
                      "catalogue": {
                        "id": 112,
                        "name": "Example Supply 2026"
                      },
                      "org_sku": "300-118",
                      "mpn": "EX-H4",
                      "manufacturer": "Example Housings",
                      "description": "Housing, 4 pole, black",
                      "category_leaf": "Connectors > Housings",
                      "supplier": {
                        "name": "Example Supply",
                        "sku": "ES-H4-01"
                      },
                      "tiers": [
                        {
                          "min_qty": 1,
                          "max_qty": 499,
                          "price": {
                            "amount": 1.58,
                            "currency": "EUR"
                          }
                        },
                        {
                          "min_qty": 500,
                          "max_qty": null,
                          "price": {
                            "amount": 1.42,
                            "currency": "EUR"
                          }
                        }
                      ],
                      "unit_price": {
                        "amount": 1.58,
                        "currency": "EUR",
                        "per": "pcs"
                      },
                      "valid_from": "2026-01-01",
                      "valid_to": "2026-12-31",
                      "order_unit": null,
                      "content_unit": "pcs",
                      "no_cu_per_ou": 1.0,
                      "price_quantity": 1.0,
                      "minimum_order_quantity": 100,
                      "order_multiple": 50,
                      "lead_time_days": 14,
                      "quantity_in_stock": 2400,
                      "notes": null,
                      "prices_quotes": true,
                      "status": "active",
                      "changed_at": "2026-10-21T16:20:05.774812Z"
                    }
                  ],
                  "next_cursor": "MjAyNi0xMC0yMVQxNjoyMDowNS43NzQ4MTIrMDA6MDB8NDQxMDI3Mw",
                  "has_more": false
                }
              }
            }
          },
          "400": {
            "description": "invalid_request",
            "x-error-codes": [
              "invalid_request"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "api_key_required, invalid_api_key",
            "x-error-codes": [
              "api_key_required",
              "invalid_api_key"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "organization_inactive, insufficient_scope",
            "x-error-codes": [
              "organization_inactive",
              "insufficient_scope"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "405": {
            "description": "method_not_allowed",
            "x-error-codes": [
              "method_not_allowed"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/materials/batches": {
      "post": {
        "operationId": "push_materials",
        "summary": "Push your parts",
        "x-summary-de": "Ihre Teile senden",
        "description": "Up to 1000 of your parts, onto your ERP sync price list in nuqo: a new part is added, one you sent before is updated, a field you leave out keeps its value, and a row with removed: true takes its part off the list. Answers the batch's id at once; poll GET /materials/batches/{id} until it is done. One batch at a time: send more parts as consecutive batches.",
        "x-description-de": "Bis zu 1000 Ihrer Teile, auf Ihre Preisliste ERP-Sync in nuqo: ein neues Teil wird angelegt, eines, das Sie schon gesendet haben, aktualisiert, ein Feld, das Sie weglassen, behält seinen Wert, und eine Zeile mit removed: true nimmt ihr Teil von der Liste. Antwortet sofort die ID des Stapels; fragen Sie GET /materials/batches/{id} ab, bis er fertig ist. Ein Stapel nach dem anderen: senden Sie mehr Teile als aufeinanderfolgende Stapel.",
        "x-scope": "catalogue:write",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MaterialBatch"
              },
              "example": {
                "rows": [
                  {
                    "org_sku": "A-10442",
                    "mpn": "1-968849-1",
                    "manufacturer": "TE Connectivity",
                    "description": "Receptacle 2.8 mm, tin",
                    "supplier": {
                      "name": "Example Supply",
                      "sku": "ES-968849"
                    },
                    "tiers": [
                      {
                        "min_qty": 1,
                        "max_qty": 999,
                        "price": {
                          "amount": 0.42,
                          "currency": "EUR"
                        }
                      },
                      {
                        "min_qty": 1000,
                        "max_qty": null,
                        "price": {
                          "amount": 0.31,
                          "currency": "EUR"
                        }
                      }
                    ],
                    "valid_from": "2026-11-01",
                    "valid_to": "2027-03-31",
                    "order_unit": "bag",
                    "content_unit": "pcs",
                    "no_cu_per_ou": 100,
                    "price_quantity": 1,
                    "minimum_order_quantity": 1,
                    "order_multiple": 1,
                    "lead_time_days": 5,
                    "quantity_in_stock": 4200,
                    "notes": null
                  },
                  {
                    "mpn": "FLRY-B 0.5",
                    "manufacturer": "Coroplast",
                    "lead_time_days": 10,
                    "quantity_in_stock": 0
                  },
                  {
                    "mpn": "GR-1100",
                    "manufacturer": "Example Grommets",
                    "supplier": {
                      "name": "digikey.com",
                      "sku": null
                    }
                  },
                  {
                    "mpn": "1-968850-1",
                    "manufacturer": "TE Connectivity",
                    "supplier": {
                      "name": "Example Supply",
                      "sku": "ES-968850"
                    },
                    "removed": true
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchCreated"
                },
                "example": {
                  "batch_id": 88214
                }
              }
            }
          },
          "400": {
            "description": "invalid_request",
            "x-error-codes": [
              "invalid_request"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "api_key_required, invalid_api_key",
            "x-error-codes": [
              "api_key_required",
              "invalid_api_key"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "organization_inactive, insufficient_scope",
            "x-error-codes": [
              "organization_inactive",
              "insufficient_scope"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "405": {
            "description": "method_not_allowed",
            "x-error-codes": [
              "method_not_allowed"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "description": "batch_in_progress, catalogue_retired",
            "x-error-codes": [
              "batch_in_progress",
              "catalogue_retired"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "batch_too_large",
            "x-error-codes": [
              "batch_too_large"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "422": {
            "description": "invalid_row",
            "x-error-codes": [
              "invalid_row"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/materials/batches/{batch_id}": {
      "get": {
        "operationId": "get_material_batch",
        "summary": "A batch of your parts",
        "x-summary-de": "Ein Stapel Ihrer Teile",
        "description": "Where a batch you pushed is, and once it is done, what it did.",
        "x-description-de": "Wo ein Stapel steht, den Sie gesendet haben, und sobald er fertig ist, was er bewirkt hat.",
        "x-scope": "catalogue:write",
        "parameters": [
          {
            "name": "batch_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The batch_id POST /materials/batches answered.",
            "x-description-de": "Die batch_id, die POST /materials/batches antwortete."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Batch"
                },
                "example": {
                  "id": 88214,
                  "status": "done",
                  "summary": {
                    "rows": 4,
                    "imported": 2,
                    "removed": 1,
                    "not_imported": [
                      {
                        "index": 2,
                        "mpn": "GR-1100",
                        "reason": "'digikey.com' is on a domain several markets' storefronts share — name the storefront you buy from"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "api_key_required, invalid_api_key",
            "x-error-codes": [
              "api_key_required",
              "invalid_api_key"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "organization_inactive, insufficient_scope",
            "x-error-codes": [
              "organization_inactive",
              "insufficient_scope"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "x-error-codes": [
              "not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "405": {
            "description": "method_not_allowed",
            "x-error-codes": [
              "method_not_allowed"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/organization": {
      "get": {
        "operationId": "get_organization",
        "summary": "The key's organization",
        "x-summary-de": "Der Betrieb des Schlüssels",
        "description": "The organization the key belongs to. Use it to check a key.",
        "x-description-de": "Der Betrieb, dem der Schlüssel gehört. Damit prüfen Sie einen Schlüssel.",
        "x-scope": "read",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Organization"
                },
                "example": {
                  "id": 318,
                  "name": "Example Assemblies Inc"
                }
              }
            }
          },
          "401": {
            "description": "api_key_required, invalid_api_key",
            "x-error-codes": [
              "api_key_required",
              "invalid_api_key"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "organization_inactive, insufficient_scope",
            "x-error-codes": [
              "organization_inactive",
              "insufficient_scope"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "405": {
            "description": "method_not_allowed",
            "x-error-codes": [
              "method_not_allowed"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/quotes": {
      "get": {
        "operationId": "list_quotes",
        "summary": "Finalized quotes, oldest first",
        "x-summary-de": "Finalisierte Angebote, älteste zuerst",
        "description": "Your finalized quotes, oldest finalization first, headers only: read each quote's work plan with GET /quotes/{quote_id}. Page with next_cursor while has_more is true, then keep the last next_cursor and poll with it: it answers only what was finalized since. A quote revised and finalized again comes again, later, with a higher revision. Every finalized quote is listed, also when your organization doesn't share finalized quotes with all its members.",
        "x-description-de": "Ihre finalisierten Angebote, die älteste Finalisierung zuerst, nur die Köpfe: den Arbeitsplan eines Angebots lesen Sie mit GET /quotes/{quote_id}. Blättern Sie mit next_cursor, solange has_more true ist, dann behalten Sie den letzten next_cursor und fragen damit regelmäßig: er antwortet nur, was seither finalisiert wurde. Ein überarbeitetes und erneut finalisiertes Angebot kommt später noch einmal, mit höherer Revision. Jedes finalisierte Angebot wird gelistet, auch wenn Ihre Organisation finalisierte Angebote nicht mit allen Mitgliedern teilt.",
        "x-scope": "read",
        "parameters": [
          {
            "name": "finalized_since",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Only quotes finalized at or after this time. Without an offset it is UTC.",
            "x-description-de": "Nur Angebote, die zu oder nach diesem Zeitpunkt finalisiert wurden. Ohne Zeitzone gilt UTC."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "A next_cursor this API answered, passed back unchanged: reads on after the last row it ended on. Never build one.",
            "x-description-de": "Ein next_cursor, den diese API geantwortet hat, unverändert zurückgegeben: liest nach der letzten Zeile weiter, auf der er endete. Bauen Sie nie selbst einen."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "description": "How many to answer at most.",
            "x-description-de": "Wie viele höchstens geantwortet werden."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteList"
                },
                "example": {
                  "quotes": [
                    {
                      "id": 5087,
                      "number": "139-1",
                      "revision": 1,
                      "finalized_at": "2026-10-14T08:52:40.611093Z",
                      "valid_until": null,
                      "customer": null,
                      "total": {
                        "amount": 3920.5,
                        "currency": "EUR"
                      }
                    },
                    {
                      "id": 5120,
                      "number": "147-2",
                      "revision": 2,
                      "finalized_at": "2026-10-20T14:03:11.204518Z",
                      "valid_until": "2026-11-19T22:59:59Z",
                      "customer": {
                        "id": 903,
                        "name": "Sample Machines Ltd"
                      },
                      "total": {
                        "amount": 21480.0,
                        "currency": "EUR"
                      }
                    }
                  ],
                  "next_cursor": "MjAyNi0xMC0yMFQxNDowMzoxMS4yMDQ1MTgrMDA6MDB8NTEyMA",
                  "has_more": false
                }
              }
            }
          },
          "400": {
            "description": "invalid_request",
            "x-error-codes": [
              "invalid_request"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "api_key_required, invalid_api_key",
            "x-error-codes": [
              "api_key_required",
              "invalid_api_key"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "organization_inactive, insufficient_scope",
            "x-error-codes": [
              "organization_inactive",
              "insufficient_scope"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "405": {
            "description": "method_not_allowed",
            "x-error-codes": [
              "method_not_allowed"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/quotes/{quote_id}": {
      "get": {
        "operationId": "get_quote",
        "summary": "One finalized quote",
        "x-summary-de": "Ein finalisiertes Angebot",
        "description": "One finalized quote: its header, each assembly with its work plan, and its parts list. A finalized quote with no work plan answers work_plan_available: false and assemblies: []. A draft, or a quote reopened for a revision, answers 409 quote_not_finalized: keep your copy of the last finalized revision. Every finalized quote is served, also when your organization doesn't share finalized quotes with all its members.",
        "x-description-de": "Ein finalisiertes Angebot: sein Kopf, jede Baugruppe mit ihrem Arbeitsplan, und seine Stückliste. Ein finalisiertes Angebot ohne Arbeitsplan antwortet work_plan_available: false und assemblies: []. Ein Entwurf, oder ein für eine Revision wieder geöffnetes Angebot, antwortet 409 quote_not_finalized: behalten Sie Ihre Kopie der zuletzt finalisierten Revision. Jedes finalisierte Angebot wird geliefert, auch wenn Ihre Organisation finalisierte Angebote nicht mit allen Mitgliedern teilt.",
        "x-scope": "read",
        "parameters": [
          {
            "name": "quote_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The quote's id, from the list or from an event.",
            "x-description-de": "Die ID des Angebots, aus der Liste oder einem Ereignis."
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "de",
                "en"
              ],
              "default": "en"
            },
            "description": "The language of the name fields.",
            "x-description-de": "Die Sprache der name-Felder."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Quote"
                },
                "example": {
                  "id": 5120,
                  "number": "147-2",
                  "revision": 2,
                  "finalized_at": "2026-10-20T14:03:11.204518Z",
                  "valid_until": "2026-11-19T22:59:59Z",
                  "customer": {
                    "id": 903,
                    "name": "Sample Machines Ltd"
                  },
                  "total": {
                    "amount": 21480.0,
                    "currency": "EUR"
                  },
                  "work_plan_available": true,
                  "assemblies": [
                    {
                      "id": "A1",
                      "name": "Control cabinet assembly",
                      "shop_part_number": "KS-40-117",
                      "quantity": 250,
                      "piece_count": 250,
                      "work_plan": [
                        {
                          "op_number": 10,
                          "work_center_id": "1010",
                          "name": "Cutting",
                          "setup_seconds": 180.0,
                          "piece_seconds": 42.5,
                          "run_seconds": 10625.0
                        },
                        {
                          "op_number": 20,
                          "work_center_id": "2030",
                          "name": "Crimping",
                          "setup_seconds": 300.0,
                          "piece_seconds": 96.12,
                          "run_seconds": 24030.0
                        },
                        {
                          "op_number": 30,
                          "work_center_id": null,
                          "name": "Special labeling",
                          "setup_seconds": 0.0,
                          "piece_seconds": 3.6,
                          "run_seconds": 900.0
                        }
                      ],
                      "unit_price": {
                        "amount": 84.32,
                        "currency": "EUR",
                        "per": "pcs"
                      },
                      "amount": {
                        "amount": 21080.0,
                        "currency": "EUR"
                      }
                    }
                  ],
                  "parts": [
                    {
                      "line_number": 1,
                      "spec_id": "k7p2q9",
                      "requested": {
                        "mpn": "EX-H4",
                        "manufacturer": "Example Housings",
                        "internal_part_number": "C-100",
                        "description": "Housing, 4 pole"
                      },
                      "status": "selected",
                      "is_substitute": false,
                      "part": {
                        "mpn": "EX-H4",
                        "manufacturer": "Example Housings",
                        "name": "Housing 4p",
                        "shop_part_number": "300-118"
                      },
                      "supplier": {
                        "name": "Example Supply",
                        "sku": "ES-H4-01"
                      },
                      "quantity": {
                        "value": 480.0,
                        "unit": "pcs"
                      },
                      "ordered": {
                        "value": 500.0,
                        "unit": "pcs"
                      },
                      "unit_price": {
                        "amount": 1.42,
                        "currency": "EUR",
                        "per": "pcs"
                      },
                      "line_total": {
                        "amount": 710.0,
                        "currency": "EUR"
                      },
                      "lead_time_days": 14
                    },
                    {
                      "line_number": 2,
                      "spec_id": "m3r8t1",
                      "requested": {
                        "mpn": null,
                        "manufacturer": null,
                        "internal_part_number": "C-215",
                        "description": "Cable tie, black, 100 mm"
                      },
                      "status": "not_found",
                      "is_substitute": false,
                      "part": null,
                      "supplier": null,
                      "quantity": {
                        "value": null,
                        "unit": "pcs"
                      },
                      "ordered": {
                        "value": null,
                        "unit": "pcs"
                      },
                      "unit_price": null,
                      "line_total": {
                        "amount": null,
                        "currency": "EUR"
                      },
                      "lead_time_days": null
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "invalid_request",
            "x-error-codes": [
              "invalid_request"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "api_key_required, invalid_api_key",
            "x-error-codes": [
              "api_key_required",
              "invalid_api_key"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "organization_inactive, insufficient_scope",
            "x-error-codes": [
              "organization_inactive",
              "insufficient_scope"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "x-error-codes": [
              "not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "405": {
            "description": "method_not_allowed",
            "x-error-codes": [
              "method_not_allowed"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "description": "quote_not_finalized",
            "x-error-codes": [
              "quote_not_finalized"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "An API key your organization's admin creates in nuqo under Settings → API keys."
      }
    },
    "schemas": {
      "Assembly": {
        "properties": {
          "id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The assembly's reference on the quote; null for a quote that declares no assemblies (one plan for the whole order).",
            "x-description-de": "Die Referenz der Baugruppe im Angebot; null bei einem Angebot ohne Baugruppen (ein Plan für den ganzen Auftrag)."
          },
          "name": {
            "description": "The assembly's name, else its reference.",
            "type": "string",
            "x-description-de": "Der Name der Baugruppe, sonst ihre Referenz."
          },
          "shop_part_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Your own number for the assembly, what your ERP files the plan under; null when unset.",
            "x-description-de": "Ihre eigene Nummer für die Baugruppe, unter der Ihr ERP den Plan ablegt; null, wenn nicht gesetzt."
          },
          "quantity": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "The quantity ordered of this assembly; null where the quote states none per assembly.",
            "x-description-de": "Die bestellte Stückzahl dieser Baugruppe; null, wo das Angebot keine je Baugruppe angibt.",
            "x-unit": "pieces"
          },
          "piece_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "The pieces each row's piece_seconds is per (the count the run was charged across); null where its operations were charged across different counts.",
            "x-description-de": "Die Stückzahl, auf die sich piece_seconds jeder Zeile bezieht (über die die Laufzeit berechnet wurde); null, wo ihre Arbeitsgänge über verschiedene Stückzahlen berechnet wurden.",
            "x-unit": "pieces"
          },
          "work_plan": {
            "description": "One row per work-center visit, in the order the work flows.",
            "items": {
              "$ref": "#/components/schemas/WorkPlanRow"
            },
            "type": "array",
            "x-description-de": "Eine Zeile je Besuch eines Arbeitsplatzes, in der Reihenfolge, in der die Arbeit läuft."
          },
          "unit_price": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UnitPrice"
              },
              {
                "type": "null"
              }
            ],
            "description": "The price of one piece of the assembly, net, as the quote PDF prints its row (per is \"pcs\"), in the currency of total. amount is quantity × unit_price, as on the PDF (on a quote priced before October 2026 a row can be a cent off, as it printed). Null where the PDF prints no row for it (no quantity ordered).",
            "x-description-de": "Der Preis eines Stücks der Baugruppe, netto, wie ihn die Zeile im Angebots-PDF druckt (per ist \"pcs\"), in der Währung von total. amount ist quantity × unit_price, wie im PDF (bei einem vor Oktober 2026 kalkulierten Angebot kann eine Zeile um einen Cent abweichen, wie sie gedruckt wurde). Null, wo das PDF keine Zeile für sie druckt (keine Stückzahl bestellt)."
          },
          "amount": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Money"
              },
              {
                "type": "null"
              }
            ],
            "description": "The assembly's row on the quote PDF: its price for the quantity ordered, net. The quote's other charges are in total only: setup the row does not carry, shipping, extra charges, the discount, and on a quote priced before September 2026 its overall margin. Null where unit_price is.",
            "x-description-de": "Die Zeile der Baugruppe im Angebots-PDF: ihr Preis für die bestellte Stückzahl, netto. Die übrigen Posten des Angebots stehen nur in total: Rüstkosten, die die Zeile nicht trägt, Versand, Zuschläge, der Rabatt und bei einem vor September 2026 kalkulierten Angebot sein Gesamtaufschlag. Null, wo unit_price null ist."
          }
        },
        "required": [
          "id",
          "name",
          "shop_part_number",
          "quantity",
          "piece_count",
          "work_plan",
          "unit_price",
          "amount"
        ],
        "type": "object"
      },
      "Batch": {
        "properties": {
          "id": {
            "description": "The batch's id.",
            "type": "integer",
            "x-description-de": "Die ID des Stapels."
          },
          "status": {
            "description": "\"pending\" (waiting its turn), \"running\", \"done\" or \"failed\" (nothing more will be taken; send it again). Poll until done or failed.",
            "type": "string",
            "x-description-de": "\"pending\" (wartet), \"running\", \"done\" oder \"failed\" (es wird nichts mehr übernommen; senden Sie ihn erneut). Fragen Sie ab, bis done oder failed."
          },
          "summary": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BatchSummary"
              },
              {
                "type": "null"
              }
            ],
            "description": "What the batch did, once it is done; null until then, and for a failed batch.",
            "x-description-de": "Was der Stapel bewirkt hat, sobald er fertig ist; bis dahin null, und bei einem fehlgeschlagenen Stapel."
          }
        },
        "required": [
          "id",
          "status",
          "summary"
        ],
        "type": "object"
      },
      "BatchCreated": {
        "properties": {
          "batch_id": {
            "description": "The batch's id: poll GET /materials/batches/{id} with it.",
            "type": "integer",
            "x-description-de": "Die ID des Stapels: fragen Sie damit GET /materials/batches/{id} ab."
          }
        },
        "required": [
          "batch_id"
        ],
        "type": "object"
      },
      "BatchSummary": {
        "properties": {
          "rows": {
            "description": "How many rows the batch had.",
            "type": "integer",
            "x-description-de": "Wie viele Zeilen der Stapel hatte."
          },
          "imported": {
            "description": "How many of them are in nuqo now, new or updated.",
            "type": "integer",
            "x-description-de": "Wie viele davon jetzt in nuqo sind, neu oder aktualisiert."
          },
          "removed": {
            "description": "How many of them took a part off your ERP sync price list (removed: true).",
            "type": "integer",
            "x-description-de": "Wie viele davon ein Teil von Ihrer Preisliste ERP-Sync genommen haben (removed: true)."
          },
          "not_imported": {
            "description": "The rows that were not taken, each with why — a removal that found nothing to remove included.",
            "items": {
              "$ref": "#/components/schemas/RowNotImported"
            },
            "type": "array",
            "x-description-de": "Die Zeilen, die nicht übernommen wurden, jede mit Grund — auch eine Entfernung, die nichts zu entfernen fand."
          }
        },
        "required": [
          "rows",
          "imported",
          "removed",
          "not_imported"
        ],
        "type": "object"
      },
      "Catalogue": {
        "properties": {
          "id": {
            "description": "The catalogue's id in nuqo.",
            "type": "integer",
            "x-description-de": "Die ID des Katalogs in nuqo."
          },
          "name": {
            "description": "Its name, as nuqo shows it: the one you gave it, else the supplier and edition (e.g. \"Stocko 2025\").",
            "type": "string",
            "x-description-de": "Sein Name, wie nuqo ihn zeigt: der, den Sie ihm gegeben haben, sonst Lieferant und Ausgabe (z. B. \"Stocko 2025\")."
          }
        },
        "required": [
          "id",
          "name"
        ],
        "type": "object"
      },
      "ChosenPart": {
        "properties": {
          "mpn": {
            "description": "The chosen part's manufacturer part number.",
            "type": "string",
            "x-description-de": "Die Herstellerteilenummer des gewählten Teils."
          },
          "manufacturer": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Its manufacturer.",
            "x-description-de": "Sein Hersteller."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Its product name.",
            "x-description-de": "Sein Produktname."
          },
          "shop_part_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Your own number for the part, from your listing of it in nuqo; null when unset.",
            "x-description-de": "Ihre eigene Nummer für das Teil, aus Ihrem Eintrag dazu in nuqo; null, wenn nicht gesetzt."
          }
        },
        "required": [
          "mpn",
          "manufacturer",
          "name",
          "shop_part_number"
        ],
        "type": "object"
      },
      "Customer": {
        "properties": {
          "id": {
            "description": "Your customer's id in nuqo.",
            "type": "integer",
            "x-description-de": "Die ID Ihres Kunden in nuqo."
          },
          "name": {
            "description": "The customer's company, else the contact's name.",
            "type": "string",
            "x-description-de": "Die Firma des Kunden, sonst der Name des Kontakts."
          }
        },
        "required": [
          "id",
          "name"
        ],
        "type": "object"
      },
      "Error": {
        "properties": {
          "code": {
            "description": "Stable, for your program: what went wrong (see the status table).",
            "type": "string",
            "x-description-de": "Stabil, für Ihr Programm: was schiefging (siehe die Tabelle der Status)."
          },
          "message": {
            "description": "For people; its wording may change.",
            "type": "string",
            "x-description-de": "Für Menschen; der Wortlaut kann sich ändern."
          }
        },
        "required": [
          "code",
          "message"
        ],
        "type": "object"
      },
      "ErrorBody": {
        "properties": {
          "error": {
            "$ref": "#/components/schemas/Error",
            "description": "The error.",
            "x-description-de": "Der Fehler."
          }
        },
        "required": [
          "error"
        ],
        "type": "object"
      },
      "Event": {
        "properties": {
          "id": {
            "description": "The event's id: dedupe on it, and send the last one handled as after.",
            "type": "integer",
            "x-description-de": "Die ID des Ereignisses: erkennen Sie Doppelte daran, und senden Sie die zuletzt verarbeitete als after."
          },
          "type": {
            "description": "quote.finalized or quote.reopened. Ignore a type you don't know: new ones may be added.",
            "type": "string",
            "x-description-de": "quote.finalized oder quote.reopened. Ignorieren Sie einen Typ, den Sie nicht kennen: neue können hinzukommen."
          },
          "created_at": {
            "description": "When it happened.",
            "format": "date-time",
            "type": "string",
            "x-description-de": "Wann es geschah."
          },
          "quote": {
            "$ref": "#/components/schemas/EventQuote",
            "description": "The quote it happened to.",
            "x-description-de": "Das Angebot, dem es geschah."
          }
        },
        "required": [
          "id",
          "type",
          "created_at",
          "quote"
        ],
        "type": "object"
      },
      "EventList": {
        "properties": {
          "data": {
            "description": "The events after after, oldest first.",
            "items": {
              "$ref": "#/components/schemas/Event"
            },
            "type": "array",
            "x-description-de": "Die Ereignisse nach after, das älteste zuerst."
          },
          "next_after": {
            "description": "What to send as after next time: the last event's id, or the after you sent when nothing is new.",
            "type": "integer",
            "x-description-de": "Was Sie beim nächsten Mal als after senden: die ID des letzten Ereignisses, oder das gesendete after, wenn nichts Neues da ist."
          }
        },
        "required": [
          "data",
          "next_after"
        ],
        "type": "object"
      },
      "EventQuote": {
        "properties": {
          "id": {
            "description": "The quote's id: read it with GET /quotes/{id}.",
            "type": "integer",
            "x-description-de": "Die ID des Angebots: lesen Sie es mit GET /quotes/{id}."
          },
          "revision": {
            "description": "quote.finalized: the revision finalized. quote.reopened: the new revision being worked on.",
            "type": "integer",
            "x-description-de": "quote.finalized: die finalisierte Revision. quote.reopened: die neue Revision, an der gearbeitet wird."
          }
        },
        "required": [
          "id",
          "revision"
        ],
        "type": "object"
      },
      "Material": {
        "properties": {
          "listing_id": {
            "description": "This row's id in nuqo: its identity, for as long as it exists. Two of your catalogues listing one part are two rows with one part_id, each with its own listing_id and price.",
            "type": "integer",
            "x-description-de": "Die ID dieser Zeile in nuqo: ihre Identität, solange sie besteht. Zwei Ihrer Kataloge, die ein Teil führen, sind zwei Zeilen mit einer part_id, jede mit eigener listing_id und eigenem Preis."
          },
          "part_id": {
            "description": "The part's id in nuqo, for as long as it exists.",
            "type": "integer",
            "x-description-de": "Die ID des Teils in nuqo, solange es besteht."
          },
          "catalogue": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Catalogue"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which of your catalogues the row's price comes from; null for a price typed in or a part kept from nuqo's catalog, and once the catalogue is deleted.",
            "x-description-de": "Aus welchem Ihrer Kataloge der Preis der Zeile stammt; null für einen eingegebenen Preis oder ein aus nuqos Katalog übernommenes Teil, und sobald der Katalog gelöscht ist."
          },
          "org_sku": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Your own article number for it; null when unset. Two parts can share one, so it is not a key.",
            "x-description-de": "Ihre eigene Artikelnummer dafür; null, wenn nicht gesetzt. Zwei Teile können sie teilen, sie ist also kein Schlüssel."
          },
          "mpn": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The manufacturer part number.",
            "x-description-de": "Die Herstellerteilenummer."
          },
          "manufacturer": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The manufacturer, by the name the Materials tab shows.",
            "x-description-de": "Der Hersteller, mit dem Namen aus dem Reiter Materialien."
          },
          "description": {
            "description": "Its description, else its name; \"\" when it has neither.",
            "type": "string",
            "x-description-de": "Seine Beschreibung, sonst sein Name; \"\", wenn es keins von beiden hat."
          },
          "category_leaf": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The category nuqo files it under, as a path, e.g. \"Protection > Sleeving\"; while nuqo files it under none, the category your file stated.",
            "x-description-de": "Die Kategorie, unter der nuqo es führt, als Pfad, z. B. \"Protection > Sleeving\"; solange nuqo es unter keiner führt, die Kategorie aus Ihrer Datei."
          },
          "supplier": {
            "$ref": "#/components/schemas/Supplier",
            "description": "Where it is bought.",
            "x-description-de": "Wo es gekauft wird."
          },
          "tiers": {
            "description": "Your price, one entry per quantity break; empty when unpriced.",
            "items": {
              "$ref": "#/components/schemas/PriceBreak"
            },
            "type": "array",
            "x-description-de": "Ihr Preis, ein Eintrag je Mengenstaffel; leer, wenn ohne Preis."
          },
          "unit_price": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UnitPrice"
              },
              {
                "type": "null"
              }
            ],
            "description": "The first break's price per content unit (per is the part's own content unit, never scaled); null when unpriced.",
            "x-description-de": "Der Preis der ersten Staffel je Inhaltseinheit (per ist die eigene Inhaltseinheit des Teils, nie umgerechnet); null, wenn ohne Preis."
          },
          "valid_from": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The first day the tiers' prices hold; null when no start is stated.",
            "x-description-de": "Der erste Tag, an dem die Preise der Staffel gelten; null, wenn kein Beginn angegeben ist."
          },
          "valid_to": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The last day the tiers' prices hold; null when no end is stated.",
            "x-description-de": "Der letzte Tag, an dem die Preise der Staffel gelten; null, wenn kein Ende angegeben ist."
          },
          "order_unit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What one is ordered as, e.g. \"stick\", \"reel\"; null when unstated.",
            "x-description-de": "Als was eins bestellt wird, z. B. \"stick\", \"reel\"; null, wenn nicht angegeben."
          },
          "content_unit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The unit one order unit holds (\"pcs\", \"m\", \"ft\", \"kg\"); null when unstated or none of them.",
            "x-description-de": "Die Einheit, die eine Bestelleinheit enthält (\"pcs\", \"m\", \"ft\", \"kg\"); null, wenn nicht angegeben oder keine davon."
          },
          "no_cu_per_ou": {
            "description": "How many content units one order unit holds.",
            "type": "number",
            "x-description-de": "Wie viele Inhaltseinheiten eine Bestelleinheit enthält."
          },
          "price_quantity": {
            "description": "How many order units a break's price is for. A break's price buys price_quantity order units of no_cu_per_ou content units each.",
            "type": "number",
            "x-description-de": "Für wie viele Bestelleinheiten der Preis einer Staffel gilt. Der Preis einer Staffel kauft price_quantity Bestelleinheiten zu je no_cu_per_ou Inhaltseinheiten."
          },
          "minimum_order_quantity": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "The least you can order, in order units.",
            "x-description-de": "Die kleinste Bestellmenge, in Bestelleinheiten."
          },
          "order_multiple": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "The step an order goes up in, in order units.",
            "x-description-de": "Die Schrittweite einer Bestellung, in Bestelleinheiten."
          },
          "lead_time_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Delivery time.",
            "x-description-de": "Lieferzeit.",
            "x-unit": "days"
          },
          "quantity_in_stock": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Stock as last stated; null when unknown.",
            "x-description-de": "Bestand wie zuletzt angegeben; null, wenn unbekannt."
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Your notes on it.",
            "x-description-de": "Ihre Notizen dazu."
          },
          "prices_quotes": {
            "description": "Whether this price may price new quotes: false for a listing an import switched off or one from a price list a user retired; the part and its last prices are still served. Where two of your price lists price the same part, both can read true: quotes use one of them, the one your purchasing rule ranks first, else one not past its end date, else the one priced last.",
            "type": "boolean",
            "x-description-de": "Ob dieser Preis neue Angebote kalkulieren darf: false für einen Eintrag, den ein Import abgeschaltet hat, oder einen aus einer Preisliste, die ein Nutzer zurückgezogen hat; das Teil und seine letzten Preise werden weiter geliefert. Wo zwei Ihrer Preislisten dasselbe Teil bepreisen, können beide true sein: Angebote nutzen eine davon, die Ihre Einkaufsregel zuerst reiht, sonst eine, deren Gültigkeit nicht abgelaufen ist, sonst die zuletzt bepreiste."
          },
          "status": {
            "description": "\"active\", or \"obsolete\" for a part a user deleted (served with include_removed=true); a part of nuqo's global catalog you added can also be \"soft_deleted\" or \"confirmed_gone\" once its supplier stops listing it.",
            "type": "string",
            "x-description-de": "\"active\", oder \"obsolete\" für ein Teil, das ein Nutzer gelöscht hat (geliefert mit include_removed=true); ein Teil aus nuqos globalem Katalog, das Sie hinzugefügt haben, kann auch \"soft_deleted\" oder \"confirmed_gone\" sein, sobald sein Lieferant es nicht mehr führt."
          },
          "changed_at": {
            "description": "When the row last changed: what the list is ordered by.",
            "format": "date-time",
            "type": "string",
            "x-description-de": "Wann sich die Zeile zuletzt geändert hat: danach ist die Liste sortiert."
          }
        },
        "required": [
          "listing_id",
          "part_id",
          "catalogue",
          "org_sku",
          "mpn",
          "manufacturer",
          "description",
          "category_leaf",
          "supplier",
          "tiers",
          "unit_price",
          "valid_from",
          "valid_to",
          "order_unit",
          "content_unit",
          "no_cu_per_ou",
          "price_quantity",
          "minimum_order_quantity",
          "order_multiple",
          "lead_time_days",
          "quantity_in_stock",
          "notes",
          "prices_quotes",
          "status",
          "changed_at"
        ],
        "type": "object"
      },
      "MaterialBatch": {
        "properties": {
          "rows": {
            "description": "Your parts, at most 1000; send more as consecutive batches. A part you leave out stays as it is.",
            "items": {
              "$ref": "#/components/schemas/MaterialRow"
            },
            "type": "array",
            "x-description-de": "Ihre Teile, höchstens 1000; senden Sie mehr als aufeinanderfolgende Stapel. Ein Teil, das Sie weglassen, bleibt, wie es ist."
          }
        },
        "required": [
          "rows"
        ],
        "type": "object"
      },
      "MaterialList": {
        "properties": {
          "materials": {
            "description": "This page, least recently changed first.",
            "items": {
              "$ref": "#/components/schemas/Material"
            },
            "type": "array",
            "x-description-de": "Diese Seite, die am längsten unveränderte zuerst."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Opaque: pass it back unchanged as cursor to read on after this page's last part. On a page with no parts it is the cursor sent (null when none was).",
            "x-description-de": "Undurchsichtig: geben Sie ihn unverändert als cursor zurück, um nach dem letzten Teil dieser Seite weiterzulesen. Auf einer Seite ohne Teile ist es der gesendete cursor (null, wenn keiner gesendet wurde)."
          },
          "has_more": {
            "description": "Whether the next page already holds parts; false once you have caught up.",
            "type": "boolean",
            "x-description-de": "Ob die nächste Seite schon Teile enthält; false, sobald Sie aufgeholt haben."
          }
        },
        "required": [
          "materials",
          "next_cursor",
          "has_more"
        ],
        "type": "object"
      },
      "MaterialRow": {
        "properties": {
          "org_sku": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Your own article number for it.",
            "x-description-de": "Ihre eigene Artikelnummer dafür."
          },
          "mpn": {
            "description": "The manufacturer part number. With manufacturer and supplier, it says which of your parts the row is.",
            "type": "string",
            "x-description-de": "Die Herstellerteilenummer. Mit manufacturer und supplier sagt sie, welches Ihrer Teile die Zeile ist."
          },
          "manufacturer": {
            "description": "The manufacturer, as your system names it or as GET /materials answers it. One nuqo doesn't know yet is added as you spell it.",
            "type": "string",
            "x-description-de": "Der Hersteller, wie Ihr System ihn nennt oder wie GET /materials ihn antwortet. Einen, den nuqo noch nicht kennt, legt nuqo so an, wie Sie ihn schreiben."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Its description.",
            "x-description-de": "Seine Beschreibung."
          },
          "supplier": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Supplier"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Where you buy it: name and your supplier's order number. Leave it out for a part you make or stock yourself.",
            "x-description-de": "Wo Sie es kaufen: Name und Bestellnummer Ihres Lieferanten. Lassen Sie es weg für ein Teil, das Sie selbst fertigen oder lagern."
          },
          "tiers": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/PriceBreak"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Your price, one entry per quantity break, all in one currency; the breaks may not overlap.",
            "x-description-de": "Ihr Preis, ein Eintrag je Mengenstaffel, alle in einer Währung; die Staffeln dürfen sich nicht überschneiden."
          },
          "valid_from": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "The first day the tiers' prices hold. Sent with the tiers; tiers sent without it hold from now.",
            "x-description-de": "Der erste Tag, an dem die Preise der Staffel gelten. Mit der Staffel gesendet; eine Staffel ohne ihn gilt ab sofort."
          },
          "valid_to": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "The last day the tiers' prices hold. Sent with the tiers; tiers sent without it hold with no end.",
            "x-description-de": "Der letzte Tag, an dem die Preise der Staffel gelten. Mit der Staffel gesendet; eine Staffel ohne ihn gilt ohne Ende."
          },
          "order_unit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "What one is ordered as, e.g. \"stick\", \"reel\".",
            "x-description-de": "Als was eins bestellt wird, z. B. \"stick\", \"reel\"."
          },
          "content_unit": {
            "anyOf": [
              {
                "enum": [
                  "pcs",
                  "m",
                  "ft",
                  "kg"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "The unit one order unit holds.",
            "x-description-de": "Die Einheit, die eine Bestelleinheit enthält."
          },
          "no_cu_per_ou": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "How many content units one order unit holds.",
            "x-description-de": "Wie viele Inhaltseinheiten eine Bestelleinheit enthält."
          },
          "price_quantity": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "How many order units a break's price is for.",
            "x-description-de": "Für wie viele Bestelleinheiten der Preis einer Staffel gilt."
          },
          "minimum_order_quantity": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "The least you can order, in order units.",
            "x-description-de": "Die kleinste Bestellmenge, in Bestelleinheiten."
          },
          "order_multiple": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "The step an order goes up in, in order units.",
            "x-description-de": "Die Schrittweite einer Bestellung, in Bestelleinheiten."
          },
          "lead_time_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Delivery time.",
            "x-description-de": "Lieferzeit.",
            "x-unit": "days"
          },
          "quantity_in_stock": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Stock; 0 is out of stock.",
            "x-description-de": "Bestand; 0 heißt nicht auf Lager."
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Your notes on it.",
            "x-description-de": "Ihre Notizen dazu."
          },
          "removed": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "true: you no longer sell it, and it stops being priced from your ERP sync price list. Your other price lists keep theirs. mpn and manufacturer say which part, supplier which of two offers of it; the row's other fields are ignored. It still reads back from GET /materials, with prices_quotes false; pushing it again without removed lists it again. Removals apply after the batch's other rows: a batch that sends and removes one part ends with it removed.",
            "x-description-de": "true: Sie führen es nicht mehr, und es wird nicht mehr aus Ihrer Preisliste ERP-Sync kalkuliert. Ihre anderen Preislisten behalten ihren Eintrag. mpn und manufacturer sagen, welches Teil, supplier, welches von zwei Angeboten dafür; die übrigen Felder der Zeile werden ignoriert. GET /materials liefert es weiter, mit prices_quotes false; senden Sie es wieder ohne removed, wird es wieder geführt. Entfernungen gelten nach den übrigen Zeilen des Stapels: ein Stapel, der ein Teil sendet und entfernt, endet mit dem Teil entfernt."
          }
        },
        "required": [
          "mpn",
          "manufacturer"
        ],
        "type": "object"
      },
      "Money": {
        "properties": {
          "amount": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "The amount, net, in currency; null where there is none to state (a quote never priced, a line with no offer).",
            "x-description-de": "Der Betrag, netto, in currency; null, wo es keinen gibt (ein nie kalkuliertes Angebot, eine Zeile ohne Angebot eines Lieferanten)."
          },
          "currency": {
            "description": "ISO 4217 currency code, e.g. \"EUR\".",
            "type": "string",
            "x-description-de": "Währungscode nach ISO 4217, z. B. \"EUR\"."
          }
        },
        "required": [
          "amount",
          "currency"
        ],
        "type": "object"
      },
      "Organization": {
        "properties": {
          "id": {
            "description": "Your organization's id in nuqo.",
            "type": "integer",
            "x-description-de": "Die ID Ihres Betriebs in nuqo."
          },
          "name": {
            "description": "Your organization's name.",
            "type": "string",
            "x-description-de": "Der Name Ihres Betriebs."
          }
        },
        "required": [
          "id",
          "name"
        ],
        "type": "object"
      },
      "PartLine": {
        "properties": {
          "line_number": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "The line's number in the BOM.",
            "x-description-de": "Die Nummer der Zeile in der Stückliste."
          },
          "spec_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The line's id on the quote.",
            "x-description-de": "Die ID der Zeile im Angebot."
          },
          "requested": {
            "$ref": "#/components/schemas/RequestedPart",
            "description": "What your customer's BOM asks for.",
            "x-description-de": "Was die Stückliste Ihres Kunden verlangt."
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Where the line's part search ended: selected, direct_match, manual (a user chose the part), customer_supplied (the customer provides it), not_found, unavailable, needs_search, pending; null where the line was never searched. New values may be added.",
            "x-description-de": "Wo die Materialsuche der Zeile endete: selected, direct_match, manual (ein Nutzer hat das Teil gewählt), customer_supplied (der Kunde stellt es bei), not_found, unavailable, needs_search, pending; null, wo die Zeile nie gesucht wurde. Neue Werte können hinzukommen."
          },
          "is_substitute": {
            "description": "Whether the chosen part is another article than the line asks for (an alternate your customer approved is not).",
            "type": "boolean",
            "x-description-de": "Ob das gewählte Teil ein anderer Artikel ist, als die Zeile verlangt (eine vom Kunden freigegebene Alternative ist es nicht)."
          },
          "part": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ChosenPart"
              },
              {
                "type": "null"
              }
            ],
            "description": "The part chosen to buy; null when the line matched nothing.",
            "x-description-de": "Das zum Kauf gewählte Teil; null, wenn für die Zeile nichts gefunden wurde."
          },
          "supplier": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Supplier"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who the part is bought from; null when the line has no offer.",
            "x-description-de": "Bei wem das Teil gekauft wird; null, wenn die Zeile kein Angebot eines Lieferanten hat."
          },
          "quantity": {
            "$ref": "#/components/schemas/Quantity",
            "description": "How much of the part the whole order needs.",
            "x-description-de": "Wie viel von dem Teil der ganze Auftrag braucht."
          },
          "ordered": {
            "$ref": "#/components/schemas/Quantity",
            "description": "How much of the part is bought for the whole order, in the same unit as quantity: what it needs, rounded up to the supplier's pack, minimum order and order multiple. value null on a quote finalized before October 2026, whose record does not state it.",
            "x-description-de": "Wie viel von dem Teil für den ganzen Auftrag gekauft wird, in derselben Einheit wie quantity: was er braucht, aufgerundet auf die Packung, die Mindestbestellmenge und das Bestellintervall des Lieferanten. value null bei einem vor Oktober 2026 finalisierten Angebot, dessen Aufzeichnung sie nicht nennt."
          },
          "unit_price": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UnitPrice"
              },
              {
                "type": "null"
              }
            ],
            "description": "The supplier's list price per unit, in the currency the part is bought in; null where the offer states no price per unit (only a pack's), and on a quote finalized before October 2026, whose record does not state it.",
            "x-description-de": "Der Listenpreis des Lieferanten je Einheit, in der Währung, in der das Teil gekauft wird; null, wo das Angebot keinen Preis je Einheit nennt (nur den einer Packung), und bei einem vor Oktober 2026 finalisierten Angebot, dessen Aufzeichnung ihn nicht nennt."
          },
          "line_total": {
            "$ref": "#/components/schemas/Money",
            "description": "What buying ordered costs, in the quote's currency, at list price before your discounts and markups: the over-order beyond quantity included; amount null when the line has no offer.",
            "x-description-de": "Was der Kauf von ordered kostet, in der Währung des Angebots, zum Listenpreis vor Ihren Rabatten und Aufschlägen, die Mehrmenge über quantity hinaus eingeschlossen; amount null, wenn die Zeile kein Angebot eines Lieferanten hat."
          },
          "lead_time_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Days to delivery: the supplier's lead time, its delivery time from stock when stock covers the order, or the default lead time of your price list where its row states none; null when unknown.",
            "x-description-de": "Tage bis zur Lieferung: die Lieferzeit des Lieferanten, seine Lieferzeit ab Lager, wenn der Bestand den Auftrag deckt, oder die Standard-Lieferzeit Ihrer Preisliste, wo deren Zeile keine nennt; null, wenn unbekannt.",
            "x-unit": "days"
          }
        },
        "required": [
          "line_number",
          "spec_id",
          "requested",
          "status",
          "is_substitute",
          "part",
          "supplier",
          "quantity",
          "ordered",
          "unit_price",
          "line_total",
          "lead_time_days"
        ],
        "type": "object"
      },
      "PriceBreak": {
        "properties": {
          "min_qty": {
            "description": "The least quantity the break's price applies to.",
            "type": "integer",
            "x-description-de": "Die kleinste Menge, für die der Preis gilt."
          },
          "max_qty": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "The most; null for no upper end.",
            "x-description-de": "Die größte; null für kein oberes Ende."
          },
          "price": {
            "$ref": "#/components/schemas/Money",
            "description": "The price for price_quantity order units.",
            "x-description-de": "Der Preis für price_quantity Bestelleinheiten."
          }
        },
        "required": [
          "min_qty",
          "max_qty",
          "price"
        ],
        "type": "object"
      },
      "Quantity": {
        "properties": {
          "value": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "The amount, in unit; null when the line has no offer.",
            "x-description-de": "Die Menge, in unit; null, wenn die Zeile kein Angebot eines Lieferanten hat."
          },
          "unit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Its unit: \"pcs\", or the line's measure (\"m\", \"mm\", …).",
            "x-description-de": "Ihre Einheit: \"pcs\" oder das Maß der Zeile (\"m\", \"mm\", …)."
          }
        },
        "required": [
          "value",
          "unit"
        ],
        "type": "object"
      },
      "Quote": {
        "properties": {
          "id": {
            "description": "The quote's id, what GET /quotes/{id} takes.",
            "type": "integer",
            "x-description-de": "Die ID des Angebots, die GET /quotes/{id} nimmt."
          },
          "number": {
            "description": "The number your customer reads, <quote number>-<revision>, e.g. \"42-3\".",
            "type": "string",
            "x-description-de": "Die Nummer, die Ihr Kunde liest, <Angebotsnummer>-<Revision>, z. B. \"42-3\"."
          },
          "revision": {
            "description": "1 for the first; counts up each time the quote is reopened and finalized again.",
            "type": "integer",
            "x-description-de": "1 für die erste; zählt hoch, jedes Mal wenn das Angebot wieder geöffnet und erneut finalisiert wird."
          },
          "finalized_at": {
            "description": "When this revision was finalized.",
            "format": "date-time",
            "type": "string",
            "x-description-de": "Wann diese Revision finalisiert wurde."
          },
          "valid_until": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the offer expires.",
            "x-description-de": "Wann das Angebot abläuft."
          },
          "customer": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Customer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who the quote is for; null when it names nobody.",
            "x-description-de": "Für wen das Angebot ist; null, wenn es niemanden nennt."
          },
          "total": {
            "$ref": "#/components/schemas/Money",
            "description": "The quote's total as finalized, net, in the currency nuqo priced it in (the PDF may show it converted).",
            "x-description-de": "Die Summe des Angebots wie finalisiert, netto, in der Währung, in der nuqo es kalkuliert hat (das PDF kann sie umgerechnet zeigen)."
          },
          "work_plan_available": {
            "description": "Whether the quote has a work plan; false for a quote that was never priced, or priced on nuqo's older labor model.",
            "type": "boolean",
            "x-description-de": "Ob das Angebot einen Arbeitsplan hat; false für ein nie kalkuliertes Angebot oder eines, das auf nuqos älterem Arbeitszeitmodell kalkuliert wurde."
          },
          "assemblies": {
            "description": "The quote's assemblies, in the order the Work plan tab lists them; empty when there is no work plan.",
            "items": {
              "$ref": "#/components/schemas/Assembly"
            },
            "type": "array",
            "x-description-de": "Die Baugruppen des Angebots, in der Reihenfolge des Reiters Arbeitsplan; leer, wenn es keinen Arbeitsplan gibt."
          },
          "parts": {
            "description": "One per BOM line, in BOM order, matched or not.",
            "items": {
              "$ref": "#/components/schemas/PartLine"
            },
            "type": "array",
            "x-description-de": "Eine je Stücklistenzeile, in der Reihenfolge der Stückliste, gefunden oder nicht."
          }
        },
        "required": [
          "id",
          "number",
          "revision",
          "finalized_at",
          "valid_until",
          "customer",
          "total",
          "work_plan_available",
          "assemblies",
          "parts"
        ],
        "type": "object"
      },
      "QuoteHeader": {
        "properties": {
          "id": {
            "description": "The quote's id, what GET /quotes/{id} takes.",
            "type": "integer",
            "x-description-de": "Die ID des Angebots, die GET /quotes/{id} nimmt."
          },
          "number": {
            "description": "The number your customer reads, <quote number>-<revision>, e.g. \"42-3\".",
            "type": "string",
            "x-description-de": "Die Nummer, die Ihr Kunde liest, <Angebotsnummer>-<Revision>, z. B. \"42-3\"."
          },
          "revision": {
            "description": "1 for the first; counts up each time the quote is reopened and finalized again.",
            "type": "integer",
            "x-description-de": "1 für die erste; zählt hoch, jedes Mal wenn das Angebot wieder geöffnet und erneut finalisiert wird."
          },
          "finalized_at": {
            "description": "When this revision was finalized.",
            "format": "date-time",
            "type": "string",
            "x-description-de": "Wann diese Revision finalisiert wurde."
          },
          "valid_until": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the offer expires.",
            "x-description-de": "Wann das Angebot abläuft."
          },
          "customer": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Customer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who the quote is for; null when it names nobody.",
            "x-description-de": "Für wen das Angebot ist; null, wenn es niemanden nennt."
          },
          "total": {
            "$ref": "#/components/schemas/Money",
            "description": "The quote's total as finalized, net, in the currency nuqo priced it in (the PDF may show it converted).",
            "x-description-de": "Die Summe des Angebots wie finalisiert, netto, in der Währung, in der nuqo es kalkuliert hat (das PDF kann sie umgerechnet zeigen)."
          }
        },
        "required": [
          "id",
          "number",
          "revision",
          "finalized_at",
          "valid_until",
          "customer",
          "total"
        ],
        "type": "object"
      },
      "QuoteList": {
        "properties": {
          "quotes": {
            "description": "This page, oldest finalization first.",
            "items": {
              "$ref": "#/components/schemas/QuoteHeader"
            },
            "type": "array",
            "x-description-de": "Diese Seite, die älteste Finalisierung zuerst."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Opaque: pass it back unchanged as cursor to read on after this page's last quote. On a page with no quotes it is the cursor sent (null when none was).",
            "x-description-de": "Undurchsichtig: geben Sie ihn unverändert als cursor zurück, um nach dem letzten Angebot dieser Seite weiterzulesen. Auf einer Seite ohne Angebote ist es der gesendete cursor (null, wenn keiner gesendet wurde)."
          },
          "has_more": {
            "description": "Whether the next page already holds quotes; false once you have caught up.",
            "type": "boolean",
            "x-description-de": "Ob die nächste Seite schon Angebote enthält; false, sobald Sie aufgeholt haben."
          }
        },
        "required": [
          "quotes",
          "next_cursor",
          "has_more"
        ],
        "type": "object"
      },
      "RequestedPart": {
        "properties": {
          "mpn": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The manufacturer part number the BOM states.",
            "x-description-de": "Die Herstellerteilenummer laut Stückliste."
          },
          "manufacturer": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The manufacturer the BOM states.",
            "x-description-de": "Der Hersteller laut Stückliste."
          },
          "internal_part_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Your customer's own number for the part.",
            "x-description-de": "Die eigene Nummer Ihres Kunden für das Teil."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The line's description.",
            "x-description-de": "Die Beschreibung der Zeile."
          }
        },
        "required": [
          "mpn",
          "manufacturer",
          "internal_part_number",
          "description"
        ],
        "type": "object"
      },
      "RowNotImported": {
        "properties": {
          "index": {
            "description": "The row's place in rows, from 0.",
            "type": "integer",
            "x-description-de": "Die Stelle der Zeile in rows, ab 0."
          },
          "mpn": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Its manufacturer part number.",
            "x-description-de": "Ihre Herstellerteilenummer."
          },
          "reason": {
            "description": "Why it wasn't taken, for people; its wording may change.",
            "type": "string",
            "x-description-de": "Warum sie nicht übernommen wurde, für Menschen; der Wortlaut kann sich ändern."
          }
        },
        "required": [
          "index",
          "mpn",
          "reason"
        ],
        "type": "object"
      },
      "Supplier": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who the part is bought from, as nuqo names them (e.g. \"DigiKey\"); a part of your own catalog reads \"<short name> parts\".",
            "x-description-de": "Bei wem das Teil gekauft wird, wie nuqo ihn nennt (z. B. \"DigiKey\"); ein Teil aus Ihrem eigenen Katalog heißt \"<Kurzname>-Teile\"."
          },
          "sku": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The supplier's order number for the part.",
            "x-description-de": "Die Bestellnummer des Lieferanten für das Teil."
          }
        },
        "required": [
          "name",
          "sku"
        ],
        "type": "object"
      },
      "UnitPrice": {
        "properties": {
          "amount": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "The amount, net, in currency; null where there is none to state (a quote never priced, a line with no offer).",
            "x-description-de": "Der Betrag, netto, in currency; null, wo es keinen gibt (ein nie kalkuliertes Angebot, eine Zeile ohne Angebot eines Lieferanten)."
          },
          "currency": {
            "description": "ISO 4217 currency code, e.g. \"EUR\".",
            "type": "string",
            "x-description-de": "Währungscode nach ISO 4217, z. B. \"EUR\"."
          },
          "per": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The unit amount is a price of: \"pcs\" for a piece, \"m\" for a meter, \"ft\" for a foot, \"in\" for an inch, \"kg\" for a kilogram; null for any other unit (the amount stands, look the line up). The list grows by addition only.",
            "x-description-de": "Die Einheit, für die amount gilt: \"pcs\" für ein Stück, \"m\" für einen Meter, \"ft\" für einen Fuß, \"in\" für einen Zoll, \"kg\" für ein Kilogramm; null für jede andere Einheit (der Betrag gilt, schlagen Sie die Zeile nach). Die Liste wächst nur durch Ergänzung."
          }
        },
        "required": [
          "amount",
          "currency",
          "per"
        ],
        "type": "object"
      },
      "WorkPlanRow": {
        "properties": {
          "op_number": {
            "description": "The operation number: 10, 20, 30 … in the order the work flows.",
            "type": "integer",
            "x-description-de": "Die Arbeitsgangnummer: 10, 20, 30 … in der Reihenfolge, in der die Arbeit läuft."
          },
          "work_center_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Your own code for the work center, as set up in nuqo (your ERP's number where you number your work centers); null for an operation no work center was given — the row stays, with its name and time.",
            "x-description-de": "Ihr eigener Code für den Arbeitsplatz, wie in nuqo eingerichtet (die Nummer Ihres ERP, wo Sie Ihre Arbeitsplätze nummerieren); null für einen Arbeitsgang ohne Arbeitsplatz — die Zeile bleibt, mit Name und Zeit."
          },
          "name": {
            "description": "The work center's name, or the operation's own for a row with no work center.",
            "type": "string",
            "x-description-de": "Der Name des Arbeitsplatzes, bei einer Zeile ohne Arbeitsplatz der des Arbeitsgangs."
          },
          "setup_seconds": {
            "description": "Setup time. Setup is charged once per order: this is this assembly's share of it, by quantity, on the first row that needs it — so the setup over all assemblies adds up to the setup the quote charged.",
            "type": "number",
            "x-description-de": "Rüstzeit. Gerüstet wird einmal je Auftrag: dies ist der Anteil dieser Baugruppe daran, nach Stückzahl, auf der ersten Zeile, die ihn braucht — so ergibt die Rüstzeit über alle Baugruppen die, die das Angebot berechnet hat.",
            "x-unit": "seconds"
          },
          "piece_seconds": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Time per piece, rounded to 0.01; null where the quote states none.",
            "x-description-de": "Stückzeit, auf 0,01 gerundet; null, wo das Angebot keine angibt.",
            "x-unit": "seconds_per_piece"
          },
          "run_seconds": {
            "description": "The row's run time for all piece_count pieces. setup_seconds + run_seconds is the row's total time; use it rather than multiplying the rounded piece_seconds back out. Over an assembly's rows, run_seconds adds up to the run time the quote charged for it.",
            "type": "number",
            "x-description-de": "Die Laufzeit der Zeile für alle piece_count Stück. setup_seconds + run_seconds ist die Gesamtzeit der Zeile; nehmen Sie diese, statt die gerundete piece_seconds zurückzurechnen. Über die Zeilen einer Baugruppe ergibt run_seconds die Laufzeit, die das Angebot für sie berechnet hat.",
            "x-unit": "seconds"
          }
        },
        "required": [
          "op_number",
          "work_center_id",
          "name",
          "setup_seconds",
          "piece_seconds",
          "run_seconds"
        ],
        "type": "object"
      }
    }
  }
}
