Skip to content

Auftragsverwaltung – Vollständige API-Referenz ​

Fach-API für Verkaufsbelege: Angebot, Auftrag, Lieferschein, Rechnung, Gutschrift und Retoure. Basis ist https://core-backend.reybex.com/api (Staging: https://io-staging-partner.reybex.com/api). Authentifizierung wie im API: --header "authorization: Basic $TOKEN".

Einkaufsbelege stehen unter Einkauf-Verwaltung. Die Kasse unter Kassenverwaltung. Kunden unter Kunden- und Lieferantenverwaltung. Artikel unter Artikelstamm-Verwaltung, Stammdaten unter Prüftabellen-Verwaltung.

Alle 144 Endpunkte hängen an /api/salesHead. Der normale Schreibweg ist POST /api/salesHead/. POST /api/salesHead/connector und POST /api/salesHead/importOrders bleiben den Konnektoren vorbehalten.

1. Grundlagen ​

Ein Verkaufsbeleg ist ein SalesHead mit Positionen SalesItem. Dieselbe Tabelle trägt Angebot, Rahmenkontrakt, Auftrag, Lieferschein, Rechnung, Gutschrift und Kassenbeleg. Die Belegart docType setzt die Flags isOffer, isContract, isOrder, isDelnote, isInvoice oder isCreditnote. Welche Art auf welche folgen darf, steht in SalesHeadDocRule.

Die Pfeile sind die übliche Kette. Erlaubt ist ein Folgebeleg nur, wenn GET /api/salesHead/docTypes?salesHeadId={id} die Zielart liefert. Ein gesperrter Beleg (blockedDelivery) enthält in dieser Liste keinen Lieferschein.

1.1 Speichern ​

POST /api/salesHead/ erwartet den Belegkopf als Body, ohne Umschlag. Ohne id entsteht ein neuer Beleg. Mit id wird geändert.

Ein Update wird abgelehnt, wenn status mindestens 2 ist oder isPosted gesetzt ist (message.salesHead.already.closed.error).

Die Antwort enthält mindestens id, docNumber, docType, totalAmount, materialIdsForMrp und tags. Plant die Belegart die Disposition, stehen die Artikel-Ids in materialIdsForMrp.

Ein Auftragsstorno (Belegart isOrder und orderType 1) mit refSalesHeadId versucht zuerst, das Fulfillment zu stornieren. Schlägt das fehl, kommt der Beleg nicht an und die Antwort enthält fulfillmentCancelFail.

1.2 Suchschlüssel ​

Am Belegkopf eine bekannte id oder einen Suchschlüssel senden.

ZielSuchschlüssel
Kunde customercustomerNo
Artikel am Kopf, falls als ToOnematCode, sonst sku
Lagercode, sonst name
LagerplatzstockplaceCode oder name, immer mit warehouse
Belegart, Währung, Einheit, Steuer, Zahlungsbedingungcode, sonst type, sonst name

In items[] bleibt die Artikel-id. Ein Suchschlüssel in dieser Liste legt keine bestehende Position an. Dieselbe Regel gilt für Einkaufspositionen.

docDate beim Vorbelegen (GET mit docTypeId) hat das Format yyyy-MM-dd.

1.3 Antwort- und Fehlerformat ​

json
{
  "data": { "id": 510100, "docNumber": "AB-10001" },
  "meta": {
    "domain": "SalesHead",
    "total": 1
  }
}

meta kann requiredFields, readOnlyFields, hiddenFields und invisibleFields enthalten. Die Subdomain in den Feldrechten folgt der Belegart: orders, invoices, deliveryNote, offer, contract.

SituationHTTPKörper
Beleg nicht gefundenFachlicher Fehler{ "error": "…" } oder { "data": { "error": "…" } }
Beleg geschlossen oder gebucht500message.salesHead.already.closed.error
Fehlende Anmeldung401—

2. Belegarten ​

Flags und Feintypen von SalesDocType:

FlagFeintypBedeutung
isOfferofferType 1Angebot
isContractcontractType 1Rahmenkontrakt
isOrderorderType 0Auftragsbestätigung
isOrderorderType 1Auftragsstorno
isDelnotedelnoteType 1Lieferschein
isDelnotedelnoteType 2Eil-Lieferschein
isDelnotedelnoteType 3Rücklieferung
isInvoiceinvoiceType 1Rechnung
isInvoiceinvoiceType 2Sammelrechnung
isInvoiceinvoiceType 6Proforma
isInvoiceinvoiceType 7Anzahlungsrechnung
isInvoiceinvoiceType 8Anzahlungsrechnung B2B
isInvoiceinvoiceType 9Schlussrechnung
isCreditnotecreditnoteType 1Wertgutschrift
isCreditnotecreditnoteType 2Mengengutschrift
isCreditnotecreditnoteType 3Storno-Rechnung
isCashRegister—Kassenbeleg
isTransfer—Umlagerung
isRelocation—Standortwechsel
isAssemblyEnabled, isAssemblyInvoice—Montage
planMrp—Artikel nach dem Speichern zur Disposition
useInMrp—Belegart geht in die Disposition ein
isPartialDeliveryStandard—Teillieferung ist Vorbelegung
isAutomaticCreditNoteForReturn—Retoure erzeugt die Gutschrift
isSalesSetSeparated—Set-Positionen werden getrennt geführt
isRecurrence—Wiederkehrende Rechnung
checkAvailableStock—Bestand vor dem Speichern prüfen
dontAllowZeroPrice—Preis 0 ist unzulässig
dontSendEinvoice—Keine E-Rechnung versenden
xInvoiceType—Kennung für X-Rechnung und ZUGFeRD

GET /api/salesHead/docTypes ohne salesHeadId listet aktive Belegarten. Query type filtert: isOffer, isContract, isOrder, isDelnote, isInvoice (einschließlich Gutschrift), isCreditnote.

GET /api/salesHead/docTypes?salesHeadId={id} listet nur die Ziele aus SalesHeadDocRule, deren Regel nicht deaktiviert ist. Bei blockedDelivery entfallen Lieferscheine.

Belegarten pflegen: GET /api/domains/salesDocType?take=100 und Prüftabellen.

3. Belegkette ​

SalesHeadDocRule verbindet fromDocType mit toDocType und steuert das Kopieren:

FeldWirkung
calculatePricePreis im Ziel neu berechnen
searchVatKeySteuerschlüssel neu suchen
forceToUpdateWarehouseLager im Ziel überschreiben
splitDocumentPerItemEin Zielbeleg je Position
resolveBomStückliste auflösen
overReferencedQuantityPercentageErlaubte Mehrmenge gegenüber der offenen Menge
ignoreQuantityOnItemCopyMenge beim Kopieren nicht übernehmen
resetNewDocumentOnCopyZiel wie ein neuer Beleg zurücksetzen
isManuallyClosedQuelle beim Kopieren manuell schließen
isDisabledRegel ist aus und liefert kein Ziel

3.1 Folgebeleg erzeugen ​

POST /api/salesHead/referencingDocuments

Auftrag aus dem Angebot, alle offenen Positionen. 510010 ist das Angebot AN-10001. 61011 ist die Auftragsart aus GET /api/salesHead/docTypes?salesHeadId=510010.

json
{
  "salesHeadIds": [510010],
  "docType1": { "id": 61011 },
  "isDocument1Created": true,
  "closeRefDocAsManuel": false
}

Response

json
{
  "document1Ids": [510100],
  "document2Ids": [],
  "blockedSalesHeads": []
}

510100 ist der neue Auftrag. Die Menge jeder Position ist die openQuantity der Angebotsposition.

Auftrag aus dem Angebot, nur ein Teil der Positionen. Das Angebot 510010 hat die Positionen 71001 und 71002. Die Ids stehen in salesItems von POST /api/salesHead/salesItemsFromSalesHeads mit { "salesHeadIds": [510010] }. salesItemsToCopy nennt die Positionen, die in den Auftrag kommen.

json
{
  "salesHeadIds": [510010],
  "docType1": { "id": 61011 },
  "isDocument1Created": true,
  "salesItemsToCopy": [71001]
}

Die Position 71002 bleibt am Angebot offen. Lieferschein aus Auftrag, vollständig und mit Teilpositionen: Lieferschein.

FeldBedeutung
salesHeadIdsQuellbelege
docType1, docType2Bis zu zwei Zielbelegarten, je { "id" }
isDocument1Created, isDocument2CreatedOb das jeweilige Ziel gespeichert wird
closeRefDocAsManuelQuelle manuell schließen
salesItemsToCopyNur diese Positionen
isSavedDialogeinstellung merken

Belege mit blockedDelivery werden aus salesHeadIds entfernt und in der Antwort unter blockedSalesHeads geliefert (id, docNumber). Die Ziele stehen in document1Ids und document2Ids.

61020 ist die Id der Ziel-Belegart aus GET /api/salesHead/docTypes?salesHeadId=510100. 71011 ist eine Positions-Id des Quellbelegs. Welche Positionen ein Beleg hat: POST /api/salesHead/salesItemsFromSalesHeads mit { "salesHeadIds": [510100] }.

Dialog-Vorbelegung: GET /api/salesHead/referencingDocuments.

Typische Paare, wenn die Regel sie erlaubt:

QuelleZielAufruf
AngebotAuftragreferencingDocuments mit Auftrags-Belegart
AuftragLieferscheinreferencingDocuments mit der Lieferschein-Belegart
LieferscheinRechnungGET /api/salesHead/createInvoicesFromDelNotes
RechnungGutschriftPOST /api/salesHead/createCreditNotes

3.2 Auftrag teilen ​

POST /api/salesHead/splitSales

json
{
  "ids": [71011, 71012],
  "docTypeId": 61020,
  "isSimpleCopy": false
}

ids sind Positions-Ids, nicht Beleg-Ids. Verarbeitet werden nur Positionen mit openQuantity über 0. isSimpleCopy true kopiert ohne die Referenzlogik (simple), sonst als Bezug (copy).

Antwort: { "success": […], "errors": […] }. Erfolg enthält Quell-id, docNumber und die Bezeichnung des neuen Belegs.

3.3 Zusammenführen ​

AufrufBedeutung
GET /api/salesHead/mergableSalesHead/{id}Belege, die sich mit diesem Beleg zusammenführen lassen
GET /api/salesHead/merge/{id}Zusammenführungsdaten
POST /api/salesHead/mergeZusammenführen

4. Wichtige Felder ​

Die Spalten von Kopf und Position stehen vollständig unter SalesHead und SalesItem. Hier die Felder, die beim Anlegen und in der Belegkette vorkommen. isReturnOrder am Kopf und isMediaItem an der Position sind keine Spalten.

4.1 Kopf ​

FeldBedeutung
docTypeBelegart
docNumberBelegnummer
customerKunde
docDate, orderDate, dueDateBeleg-, Bestell- und Fälligkeitsdatum
deliveryDate, desiredInvoiceDateLiefer- und Wunschrechnungsdatum
paymcond, currency, exchangeRateKondition, Währung, Kurs
orderDescriptionBestellzeichen, oft die externe Bestellnummer
marktplaceOrderIdMarktplatz-Bestellnummer, Duplikatschutz
paymentTypeZahlart
shippingVersandart
partlyDeliveryTeillieferung erlaubt
blockedDeliveryLiefersperre
refSalesHeadVorgänger
statusBelegstatus; ab 2 ist der Beleg für Updates geschlossen
orderStatusAuftragsstatus, Typen 0 offen bis 8 Klärung
connectorStatus, sendStatus, paymentStatusKonnektor, Versand, Zahlung
isPaid, isPacked, isPosted, isPrintedBezahlt, gepackt, gebucht, gedruckt
isSend, isEmailSend, isInvoiceSendVersandkennzeichen
isCanceled, isDelete, isManuallyClosedStorno, Löschung, manueller Abschluss
isOfferConfirmed, isOfferLostAngebot angenommen oder verloren
isReturnOrderRetourenauftrag
pickNumberKommissioniernummer
receiver*Empfängeradresse, Snapshot
customer*Kundenadresse, Snapshot
invoice*Rechnungsadresse, Snapshot
languageSprache des Belegs
notesNotizen
marktplaceMarktplatz
projectProjekt
salesPersonVerkäufer
freightFracht
isGrossPricePreise am Beleg sind brutto
isPartlyDeliveryRequestedTeillieferung ist gewünscht
isSalesSetSeparatedSet-Positionen dieses Belegs getrennt
isPreInvoiceCreatedAnzahlungsrechnung ist erzeugt
subTotal, taxAmount, totalAmountNetto, Steuer, Brutto
bankIban, bankBic, bankName, bankHolderBank am Beleg
isEinvoice, einvoiceNumber, einvoiceStatusTextE-Rechnung, Nummer und Status
fulfillmentOrderIdFulfillment-Auftrag
refOrderDocNumberBelegnummer des referenzierten Auftrags
offerLoseReasonGrund, wenn das Angebot verloren ist
customFieldsZusatzfelder
itemsPositionen
packsPackstücke
discounts, texts, tagsRabatte, Texte, Schlagwörter

orderStatus.type: 0 offen, 1 in Bearbeitung, 2 komplett abgeschlossen, 3 teilweise abgeschlossen, 4 storniert, 5 zur Lieferung bereit, 6 teilweise ausgeliefert, 7 komplett ausgeliefert, 8 Klärung.

4.2 Position ​

FeldBedeutung
materialArtikel, in der Liste per id
positionPositionsnummer
quantityMenge
openQuantityNoch nicht weitergereichte Menge
price, grossPrice, priceUnitNetto, Brutto, Preiseinheit
isGrossPrice, calculatePrice, isPriceSetManuallyPreissteuerung
unit, warehouseUnitVerkaufs- und Lagereinheit
warehouse, stockplaceLager und Platz
vatKeySteuer
materialVariantVariante, per id
variantCode, attributeCodeVarianten-Code und Attribut
batchnumCharge
shortDescriptionBezeichnung der Position
customerMatCode, customerMatNameArtikelnummer und Bezeichnung des Kunden
deliveryDateLieferdatum der Position
nettAmount, totalAmountNetto und Brutto der Position
deliveryStatus, deliveredQuantityLieferfortschritt
invoiceStatus, invoicedQuantityRechnungsfortschritt
isOversoldÜberverkauf
isSentToFulfillmentAn das Fulfillment übergeben
refSalesItemVorgängerposition
isSetHead, isSetItem, setItemsSet-Kopf und Komponenten
bomItemNumber, refSetItem, setItemQuantitySet-Zeile, Bezug zum Kopf, Menge je Set
targetWarehouseZiellager bei Umlagerung
customFieldsZusatzfelder
isDelete, isCanceled, isManuallyClosedPosition geschlossen

Set-Komponenten stehen unter setItems der Kopfposition: material.id, quantity, setItemQuantity, unit.id, optional batchnum, variantCode, price. Der Kopf erhält isSetHead. Die Komponenten werden als eigene Zeilen mit isSetItem gespeichert.

5. Lesen ​

5.1 Ein Beleg ​

GET /api/salesHead/{id}

Unbekannte Id: Ressource nicht gefunden. isExport=1 startet einen CSV-Export im Hintergrund und liefert den Beleg nicht inline.

5.2 Vorlage ​

GET /api/salesHead/?docTypeId={id}&customerId={id}&docDate=2026-10-12

Nichts wird gespeichert. Die Antwort ist ein vorbelegter Kopf (Kunde, Währung, Kondition, Adressen, Texte).

5.3 Listen ​

MethodePfadInhalt
GET / POST/api/salesHead/salesOrdersAufträge
GET / POST/api/salesHead/salesOffersAngebote
GET / POST/api/salesHead/salesDeliveryNotesLieferscheine
GET / POST/api/salesHead/salesInvoicesRechnungen
GET / POST/api/salesHead/salesContractsKontrakte
GET/api/salesHead/cashRegisterReceiptsKassenbelege
GET/api/salesHead/?docNumber=AB-100Liste, gefiltert auf Belegnummern, die den Text enthalten
GET/api/salesHead/showOrdersAuftragsliste, Query isSend als true oder false
GET/api/salesHead/getOpenOrdersOffene Aufträge
GET/api/salesHead/ordersByEanOrTrackingSuche über EAN oder Sendungsnummer

5.4 Status ​

GET /api/salesHead/status/{id}

json
{
  "status": 0,
  "connectorStatus": 0,
  "sendStatus": 0,
  "isPaid": false,
  "isPacked": false,
  "isPosted": false,
  "isPrinted": false,
  "isSend": false,
  "isEmailSend": false,
  "isInvoiceSend": false,
  "isManuallyClosed": false,
  "isCanceled": false,
  "isDelete": false,
  "salesHeadStatus": {},
  "orderStatus": { "id": 1, "type": 0 },
  "paymentStatus": {}
}

GET /api/salesHead/isSend/{id} liest das Versandkennzeichen. GET /api/salesHead/checkCancelDocument prüft, ob ein Storno zulässig ist.

6. Anlegen ​

Kundendaten, Belegart, Artikel, Einheit, Lager und Steuer vorher lesen. Die Artikel-Ids in den Positionen stammen aus diesem Lesen.

6.1 Auftrag, Einzelartikel ​

POST /api/salesHead/

json
{
  "docType": { "name": "Auftrag" },
  "customer": { "customerNo": "KD-1000" },
  "currency": { "code": "EUR" },
  "paymcond": { "code": "14" },
  "docDate": "2026-10-12",
  "orderDescription": "Shop-10001",
  "items": [
    {
      "position": 10,
      "quantity": 2,
      "price": 12.9,
      "priceUnit": 1,
      "material": { "id": 100100 },
      "unit": { "code": "ST" },
      "warehouse": { "code": "HAUPT" },
      "vatKey": { "code": "19" }
    }
  ]
}

100100 ist die Id von ART-1000.

6.2 Angebot ​

docType.name ist der Name der Angebotsart (isOffer). dueDate ist die Gültigkeit. Annahme läuft über referencingDocuments, nicht über ein zweites Feld am Angebot.

json
{
  "docType": { "name": "Angebot" },
  "customer": { "customerNo": "KD-1000" },
  "currency": { "code": "EUR" },
  "paymcond": { "code": "14" },
  "docDate": "2026-10-12",
  "dueDate": "2026-11-12",
  "orderDescription": "Anfrage Torstraße",
  "items": [
    {
      "position": 10,
      "quantity": 2,
      "price": 12.9,
      "priceUnit": 1,
      "material": { "id": 100100 },
      "unit": { "code": "ST" },
      "warehouse": { "code": "HAUPT" },
      "vatKey": { "code": "19" }
    }
  ]
}

Response. Der Server setzt docNumber, totalAmount und die Flags. 61010 ist die Id der Angebotsart.

json
{
  "id": 510010,
  "docNumber": "AN-10001",
  "totalAmount": 25.8,
  "docType": {
    "id": 61010,
    "isOffer": true,
    "isOrder": false,
    "isContract": false,
    "isDelnote": false,
    "isInvoice": false,
    "isCreditnote": false,
    "isTransfer": false
  },
  "materialIdsForMrp": [],
  "tags": [],
  "fiskalyTransaction": {},
  "cashRegister": { "dontPrint": true }
}

isOfferConfirmed setzt die Annahme, isOfferLost den Verlust. Beides ist eine Änderung des bestehenden Angebots:

json
{ "id": 510010, "isOfferConfirmed": true }

6.3 Variantenartikel ​

material in der Position ist der Kopfartikel. Die Variante steht in variantCode, dem Code aus MaterialVariant, nicht dem Namen. Jede Variante ist eine eigene Position. attributeCode ist ein zusätzliches Merkmal und ersetzt variantCode nicht.

Varianten vorher lesen: GET /api/materialVariant?materialId=100400. 100400 ist der Kopfartikel VAR-4000. Dieselbe Liste liefert GET /api/salesHead/findMaterial im Feld variants, sobald materialId gesetzt ist. Der Preis der Variante kommt aus Preis vor dem Speichern mit variantCode oder materialVariantId.

Liegt materialVariant mit id an der Position, übernimmt das Speichern variantCode von dieser Variante. Bei Angebot, Lieferschein und Rechnung bricht das Speichern ab, wenn der Artikel nicht gelöschte Varianten hat und weder variantCode noch materialVariant gesetzt ist: position.error.no.materialVariant. Ein Auftrag (isOrder) führt diese Prüfung nicht aus. Bestand und Preis hängen trotzdem an der Variante.

Zwei Varianten desselben Kopfes:

json
{
  "docType": { "name": "Auftrag" },
  "customer": { "customerNo": "KD-1000" },
  "currency": { "code": "EUR" },
  "items": [
    {
      "position": 10,
      "quantity": 1,
      "price": 19.9,
      "priceUnit": 1,
      "material": { "id": 100400 },
      "variantCode": "ROT-M",
      "unit": { "code": "ST" },
      "warehouse": { "code": "HAUPT" },
      "vatKey": { "code": "19" }
    },
    {
      "position": 20,
      "quantity": 1,
      "price": 19.9,
      "priceUnit": 1,
      "material": { "id": 100400 },
      "variantCode": "BLAU-L",
      "unit": { "code": "ST" },
      "warehouse": { "code": "HAUPT" },
      "vatKey": { "code": "19" }
    }
  ]
}

Eine Variante mit Merkmal. attributeCode kommt aus den Attributen des Artikels, variantCode aus der Variante ROT-M.

json
{
  "docType": { "name": "Auftrag" },
  "customer": { "customerNo": "KD-1000" },
  "currency": { "code": "EUR" },
  "docDate": "2026-10-12",
  "items": [
    {
      "position": 10,
      "quantity": 3,
      "price": 19.9,
      "priceUnit": 1,
      "material": { "id": 100400 },
      "materialVariant": { "id": 3301 },
      "variantCode": "ROT-M",
      "attributeCode": "FARBE-ROT",
      "unit": { "code": "ST" },
      "warehouse": { "code": "HAUPT" },
      "vatKey": { "code": "19" }
    }
  ]
}

3301 ist die Id der Variante ROT-M. Steht materialVariant im Body, gewinnt dessen variantCode beim Speichern.

6.4 Set-Artikel ​

Die verkaufte Zeile ist der Set-Kopf. Komponenten werden eigene Positionen mit derselben position. Der Kopf hat isSetHead und bomItemNumber 0. Jede Komponente hat isSetItem, refSetItem auf den Kopf und bomItemNumber ab 1. setItemQuantity ist die Menge der Komponente je ein Set. quantity der Komponente ist die Kopfmenge mal dieser Stücklistenmenge, solange die Belegart isSalesSetSeparated nicht setzt.

Komponenten vorher lesen: GET /api/salesHead/findMaterial?materialId=100300&warehouseId=7001&docTypeId=61011. Ohne isSalesSetSeparated stehen sie in setItems. Mit isSalesSetSeparated ist setItems leer und die Komponenten stehen in splitedItems, jede schon mit isSetItem. Eine Komponente, die selbst ein Set ist, bricht mit setItem.material.isSet.error ab. Die Suche einer einzelnen Komponente setzt isForSetItem=true.

100300 ist SET-3000, 100200 ist LM-2000, 100301 ist VERP-3001. Der Verkaufspreis steht am Kopf. Die Komponenten haben price 0. 6001 ist die Id der Einheit Stück.

json
{
  "docType": { "name": "Auftrag" },
  "customer": { "customerNo": "KD-1000" },
  "currency": { "code": "EUR" },
  "docDate": "2026-10-12",
  "items": [
    {
      "position": 10,
      "quantity": 2,
      "price": 6.9,
      "priceUnit": 1,
      "isSetHead": true,
      "material": { "id": 100300 },
      "unit": { "code": "ST" },
      "warehouse": { "code": "HAUPT" },
      "vatKey": { "code": "7" },
      "setItems": [
        {
          "bomItemNumber": 1,
          "material": { "id": 100200 },
          "quantity": 4,
          "setItemQuantity": 2,
          "unit": { "id": 6001 },
          "price": 0
        },
        {
          "bomItemNumber": 2,
          "material": { "id": 100301 },
          "quantity": 2,
          "setItemQuantity": 1,
          "unit": { "id": 6001 },
          "price": 0
        }
      ]
    }
  ]
}

Kopfmenge 2 und setItemQuantity 2 ergeben die Komponentenmenge 4. Nach dem Speichern teilen sich Kopf und Komponenten die position 10.

Komponente mit Variante und Charge. Die Variante und die Charge gehören zur Komponente, nicht zum Set-Kopf.

json
{
  "docType": { "name": "Auftrag" },
  "customer": { "customerNo": "KD-1000" },
  "currency": { "code": "EUR" },
  "items": [
    {
      "position": 10,
      "quantity": 1,
      "price": 6.9,
      "priceUnit": 1,
      "isSetHead": true,
      "material": { "id": 100300 },
      "unit": { "code": "ST" },
      "warehouse": { "code": "HAUPT" },
      "vatKey": { "code": "7" },
      "setItems": [
        {
          "bomItemNumber": 1,
          "material": { "id": 100200 },
          "quantity": 2,
          "setItemQuantity": 2,
          "variantCode": "ROT-M",
          "batchnum": "LOT-2026-10-A",
          "unit": { "id": 6001 },
          "price": 0
        }
      ]
    }
  ]
}

Eine Folgebeleg-Regel mit resolveBom löst die Stückliste beim Kopieren zusätzlich auf. Dabei werden die Komponenten zu eigenen Positionen ohne isSetHead und ohne isSetItem.

6.5 Charge ​

batchnum steht an der Position, wenn die Charge schon feststeht. Eine Position trägt eine Charge. Zwei Chargen derselben Menge sind zwei Positionen. Das Mindesthaltbarkeitsdatum hängt am Bestand der Charge, nicht an der Verkaufsposition.

Der Artikel 100200 (LM-2000) ist chargengeführt (isLotEnabled). Chargen mit Bestand vorher lesen: GET /api/salesHead/findMaterial mit materialId, warehouseId und stockplaceId. Die Antwort enthält batchnums und setzt batchnum auf die erste Charge, sofern die automatische Chargenbuchung aus ist. 8001 ist der Lagerplatz WE-01 im Lager HAUPT. In der Position bleibt diese id, weil der Platz nur zusammen mit dem Lager eindeutig ist.

json
{
  "docType": { "name": "Auftrag" },
  "customer": { "customerNo": "KD-1000" },
  "currency": { "code": "EUR" },
  "docDate": "2026-10-12",
  "items": [
    {
      "position": 10,
      "quantity": 4,
      "price": 1.49,
      "priceUnit": 1,
      "material": { "id": 100200 },
      "batchnum": "LOT-2026-10-A",
      "unit": { "code": "ST" },
      "warehouse": { "code": "HAUPT" },
      "stockplace": { "id": 8001 },
      "vatKey": { "code": "7" }
    },
    {
      "position": 20,
      "quantity": 2,
      "price": 1.49,
      "priceUnit": 1,
      "material": { "id": 100200 },
      "batchnum": "LOT-2026-10-B",
      "unit": { "code": "ST" },
      "warehouse": { "code": "HAUPT" },
      "stockplace": { "id": 8001 },
      "vatKey": { "code": "7" }
    }
  ]
}

Ohne batchnum bleibt die Position ohne Charge. Ist isBatchnumRequired gesetzt oder die automatische Chargenbuchung aktiv, kommt die Charge bei der Bestandsbuchung über batchNumberDefinition. Jeder Eintrag nennt salesItemId oder position und die Chargen in serialNumbers.

Charge und Variante an derselben Position. Der Bestand wird über variantCode und batchnum gemeinsam gelesen.

json
{
  "docType": { "name": "Auftrag" },
  "customer": { "customerNo": "KD-1000" },
  "currency": { "code": "EUR" },
  "items": [
    {
      "position": 10,
      "quantity": 6,
      "price": 1.49,
      "priceUnit": 1,
      "material": { "id": 100200 },
      "variantCode": "ROT-M",
      "batchnum": "LOT-2026-10-A",
      "unit": { "code": "ST" },
      "warehouse": { "code": "HAUPT" },
      "stockplace": { "id": 8001 },
      "vatKey": { "code": "7" }
    }
  ]
}

Bestand der Position: GET /api/salesHead/getStockData. Überverkäufe: POST /api/salesHead/oversoldList.

6.6 Preis, Steuer, Menge ​

AufrufBedeutung
GET /api/salesHead/findMaterialArtikel für eine Position suchen
GET /api/salesHead/getSalesItemPricePositionspreis
POST /api/salesHead/getSalesPricePreisberechnung
GET /api/salesHead/getSalesItemQuantityMenge und offene Menge
POST /api/salesHead/materialsVatKeysSteuerschlüssel mehrerer Artikel
POST /api/salesHead/getMaterialsVatKeysSteuerschlüssel zu den übergebenen Artikeln
GET /api/salesHead/salesHeadLookupDataNachschlagelisten der Maske
GET /api/salesHead/getTextsForMaterialTextbausteine zum Artikel

Den Stammpreis am Artikel ändert die Artikel-API. Am Beleg steht der Preis an der Position (price oder grossPrice). isPriceSetManually hält einen manuell gesetzten Preis.

6.7 Ändern, Empfänger, Löschen ​

Preis an einer bestehenden Position. 71011 ist die Positions-id aus GET /api/salesHead/510100. isPriceSetManually hält den Preis bei einer späteren Neuberechnung.

json
{
  "id": 510100,
  "items": [
    {
      "id": 71011,
      "price": 14.9,
      "isPriceSetManually": true
    }
  ]
}

Kopfrabatt und Positionsrabatt. discountType ist eine Rabattart aus GET /api/salesHead/salesHeadLookupData oder den Prüftabellen.

json
{
  "id": 510100,
  "discounts": [
    {
      "discountType": { "code": "RABATT10" },
      "discountRate": 10,
      "orderPos": 1
    }
  ],
  "items": [
    {
      "id": 71011,
      "discounts": [
        {
          "discountType": { "code": "POS5" },
          "discountAmount": 0.5,
          "orderPos": 1
        }
      ]
    }
  ]
}

Empfängeradresse, ohne den ganzen Beleg zu senden: POST /api/salesHead/receiverAddress/{id}

json
{
  "receiverCountry": { "id": 1 },
  "receiverZipStreet": "10115",
  "receiverStreet1": "Torstraße 1",
  "receiverCity": "Berlin",
  "receiverPhone": "+4930123456",
  "receiverAddressline1": "Lager Nord",
  "receiverProvince": "Berlin"
}

receiverCountry wird per id gelesen.

Löschen: DELETE /api/salesHead/ mit { "ids": [510100] }. Antwort { "success": true }.

Schlagwörter ersetzen die bisherige Liste. Eine Zeichenkette legt das Schlagwort an, falls es noch fehlt. Eine Map mit id verwendet ein bestehendes.

POST /api/salesHead/updateSalesHeadTags

json
{
  "salesHeadId": 510100,
  "tags": ["Shop", "Eilig"]
}

Antwort: { "success": true }.

Gedruckt setzen. POST /api/salesHead/setPrinted erwartet ids. Die Antwort ist { "success": true } oder { "success": false }, wenn keine Zeile getroffen wurde.

json
{ "ids": [510100, 510200] }

Liefersperre aufheben. Die Antwort schreibt succes mit einem s.

POST /api/salesHead/unlockDeliveryBlocks

json
{ "salesHeadIds": [510100] }

Kommissioniernummer aus dem Nummernkreis. Fehlt der Nummernkreis, bricht der Aufruf ab.

POST /api/salesHead/assignPickNumber

json
{ "ids": [510100], "pickingProfileId": 9001 }

pickingProfileId ist optional. Entfernen: POST /api/salesHead/removePickNumber mit { "ids": [510100] }.

7. Lieferschein, Rechnung, Gutschrift ​

7.1 Lieferschein aus Auftrag ​

Der Lieferschein entsteht über referencingDocuments. 61020 ist die Lieferschein-Belegart aus GET /api/salesHead/docTypes?salesHeadId=510100. 510100 ist der Auftrag AB-10001. Seine Positionen 71011 und 71012 stehen in salesItems von POST /api/salesHead/salesItemsFromSalesHeads mit { "salesHeadIds": [510100] }. Die kopierte Menge ist die openQuantity der jeweiligen Position.

Lieferschein 1:1, alle offenen Positionen:

json
{
  "salesHeadIds": [510100],
  "docType1": { "id": 61020 },
  "isDocument1Created": true,
  "closeRefDocAsManuel": false
}

Response

json
{
  "document1Ids": [510200],
  "document2Ids": [],
  "blockedSalesHeads": []
}

510200 ist der neue Lieferschein. Ein gesperrter Auftrag landet in blockedSalesHeads und bekommt keinen Lieferschein.

Lieferschein mit Teilpositionen, nur Position 71011. Die Position 71012 bleibt am Auftrag offen. partlyDelivery am Auftrag erlaubt die Teilmenge. openQuantity der kopierten Position sinkt um die weitergereichte Menge.

json
{
  "salesHeadIds": [510100],
  "docType1": { "id": 61020 },
  "isDocument1Created": true,
  "salesItemsToCopy": [71011]
}

Dieselbe Teilmenge über splitSales, wenn ein eigener Beleg aus einzelnen Positionen entstehen soll. partlyDelivery am Auftrag erlaubt die Teilmenge. openQuantity der Position sinkt um die weitergereichte Menge.

Lieferschein und Rechnung in einem Aufruf, wenn beide Regeln existieren. 61030 ist die Rechnungsart:

json
{
  "salesHeadIds": [510100],
  "docType1": { "id": 61020 },
  "docType2": { "id": 61030 },
  "isDocument1Created": true,
  "isDocument2Created": true
}

Response

json
{
  "document1Ids": [510200],
  "document2Ids": [510300],
  "blockedSalesHeads": []
}

GET /api/salesHead/getDeliveryNotes listet Lieferscheine für den Rechnungslauf. Es legt keinen Lieferschein an. POST /api/salesHead/getDeliveryNotes erzeugt daraus Rechnungen, siehe Rechnung.

Parameter der Lieferliste: GET /api/salesHead/getDeliveryNotesParameters.

Sammelbelege mit Kundenbündel brauchen die Belegarten MR, VR, M-ER, ER, MJ und PJ. POST /api/salesHead/saveDeliveryNotesWithCustomerBundle:

json
{
  "ids": [71011, 71012],
  "docTypeId": 61030,
  "dateFrom": "2026-10-01",
  "dateUntil": "2026-10-31",
  "areSingleInvoicesCreated": false
}

ids sind hier Positions-Ids. Die Antwort enthält deliveryNotes und docNumbers. Fehlt eine der sechs Belegarten, bricht der Aufruf mit dem Hinweis auf MR, VR, M-ER, ER, MJ und PJ ab.

7.2 Rechnung ​

Rechnung ohne Vorgängerbeleg. docType.name ist der Name der Rechnungsart (isInvoice, invoiceType 1). POST /api/salesHead/ legt den Beleg direkt an. VK ist die Zahlart Vorkasse.

json
{
  "docType": { "name": "Rechnung" },
  "customer": { "customerNo": "KD-1000" },
  "currency": { "code": "EUR" },
  "paymcond": { "code": "14" },
  "paymentType": { "code": "VK" },
  "docDate": "2026-10-12",
  "deliveryDate": "2026-10-12",
  "dueDate": "2026-10-26",
  "orderDescription": "Shop-10001",
  "items": [
    {
      "position": 10,
      "quantity": 2,
      "price": 12.9,
      "priceUnit": 1,
      "material": { "id": 100100 },
      "unit": { "code": "ST" },
      "warehouse": { "code": "HAUPT" },
      "vatKey": { "code": "19" }
    }
  ]
}

Response (Auszug). 510300 ist diese Rechnung, 61030 die Rechnungsart.

json
{
  "id": 510300,
  "docNumber": "RE-10001",
  "totalAmount": 25.8,
  "docType": {
    "id": 61030,
    "isInvoice": true,
    "isOrder": false,
    "isDelnote": false
  },
  "materialIdsForMrp": [],
  "tags": []
}

Rechnung aus dem Lieferschein. GET /api/salesHead/createInvoicesFromDelNotes?salesHeads={lieferscheinIds}&docTypeId={rechnungsartId}

salesHeads ist eine kommagetrennte Liste der Lieferschein-Ids. docTypeId ist die Rechnungs-Belegart. Fehlt sie, antwortet salesDocType.not.found.error. Hat der Kunde Sammelrechnung und es gibt mehrere Lieferscheine, entsteht eine gemeinsame Rechnung, sonst eine Rechnung je Lieferschein. Die Antwort ist die Id-Liste der neuen Belege als Text für den Druck, kein Objekt mit document1Ids. Optional docDate.

Anzahlungs- und Schlussrechnungsmerker zurücksetzen:

  • POST /api/salesHead/resetPreInvoiceCreated
  • POST /api/salesHead/resetPreInvoiceAndFinalInvoiceCreated

Liefersperre aufheben: POST /api/salesHead/unlockDeliveryBlocks.

Wiederkehrende Rechnungen: GET /api/salesHead/invoiceRecurrences.

7.3 Gutschrift ​

POST /api/salesHead/createCreditNotes

json
{ "salesHeadIds": [510300] }

510300 ist die Rechnungs-Id. Die Ziel-Belegart wählt die Anwendung. Antwort:

json
{
  "success": [
    { "salesHeadId": 510300, "docNumber": "GS-10001", "creditNoteId": 510400 }
  ],
  "errors": []
}

7.4 Retoure ​

POST /api/salesHead/return

json
{
  "customerNo": "KD-1000",
  "orderDescription": "AB-10001",
  "reasonCode": "RETOURE",
  "returnComment": "Größe passt nicht",
  "items": [
    {
      "sku": "ART-1000",
      "itemCode": "ART-1000",
      "returnQuantity": 1,
      "notes": "ungeöffnet"
    }
  ]
}

Positionen mit returnQuantity über 0 werden übernommen. Chargenretouren stehen in items[].batchnums mit batchnum und returnQuantity. Die Rückliefer-Mail: GET /api/salesHead/getReturnDeliveryEmail. Vorlage erzeugen: GET /api/salesHead/createReturnTemplate und GET /api/salesHead/triggerCreateReturnTemplate.

Eine Belegart mit isAutomaticCreditNoteForReturn legt zur Retoure die Gutschrift an. Der Lieferschein-Feintyp 3 ist die Rücklieferung.

7.5 Storno ​

GET /api/salesHead/checkCancelDocument vor dem Storno. Auftragsstorno ist eine neue Belegart mit isOrder und orderType 1 und refSalesHeadId des Originals. Das Fulfillment wird dabei storniert.

8. Versand und Kommissionierung ​

AufrufBedeutung
GET /api/salesHead/validateShipmentSendung prüfen
POST /api/salesHead/updateShippingVersanddaten schreiben
POST /api/salesHead/refreshSalesHeadsShippingDataVersanddaten neu lesen
POST /api/salesHead/extractSendung heraustrennen
GET /api/salesHead/showShipmentReportVersandbericht
GET /api/salesHead/unfinishedShipmentsOffene Sendungen
GET /api/salesHead/lastTransportationNumberLetzte Transportnummer
GET /api/salesHead/calculateMeasuresMaße, Query salesHeadId
GET /api/salesHead/getSalesHeadMeasurementsGespeicherte Maße
GET /api/salesHead/pickNumberListKommissioniernummern
POST /api/salesHead/assignPickNumberNummer zuweisen
POST /api/salesHead/removePickNumberNummer entfernen
POST /api/salesHead/skipPackingPacken überspringen
DELETE /api/salesHead/packs/{id}Packstück löschen
POST /api/salesHead/materialLabelArtikeletikett
GET /api/salesHead/getDatesForOrderLiefertermine
POST /api/salesHead/salesItemsPrintPositionen drucken

9. E-Mail, FiBu, E-Rechnung ​

AufrufBedeutung
POST /api/salesHead/salesHeadEmailDialogMail-Dialog, Body id, optional templateKey
POST /api/salesHead/sendSalesEmailMail senden, Body ids
GET /api/salesHead/getSalesHeadEmailsGesendete Mails
GET /api/salesHead/getSalesHeadEdisEDI-Nachrichten
GET /api/salesHead/emailHistoryMail-Historie
GET /api/salesHead/getVouchers/{id}Zugeordnete FiBu-Belege
GET /api/salesHead/listAllNonTransferedInvoicesNoch nicht an die Finanzbuchhaltung übergebene Rechnungen
POST /api/salesHead/datevCheckDATEV-Prüfung
GET /api/salesHead/transferSingleInvoiceToFinanceEine Rechnung übergeben
POST /api/salesHead/transferInvoicesToFinanceMehrere Rechnungen übergeben
GET /api/salesHead/getXInvoiceXml/{id}XRechnung-XML
POST /api/salesHead/getEInvoicePrefixListE-Rechnungs-Präfixe
POST /api/salesHead/getCustomerTaxpayerPkListSteuerpflichtigen-Schlüssel des Kunden
GET /api/salesHead/getTaxExemptionDefaultReasonCodeListSteuerbefreiungsgründe

Eine gebuchte Rechnung (isPosted) lässt sich über POST /api/salesHead/ nicht mehr ändern.

9.1 PDF der Rechnung ​

POST /api/report/salesHeadDownload liefert die Rechnung 510300 (RE-10001) als PDF-Datei. Der Kopf Content-disposition ist attachment und nennt den Dateinamen. Ohne responseType ist das Format PDF.

json
{ "ids": [510300] }

Dieselbe Datei über die Belegnummer, wenn ids leer bleibt:

json
{ "docNumbers": ["RE-10001"] }

POST /api/report/salesHeadPrint mit demselben Body liefert das PDF inline.

9.2 X-Rechnung ​

GET /api/salesHead/getXInvoiceXml/510300

Die Antwort enthält fileName und bytes. fileName ist xInvoice_ plus Belegnummer plus .xml, hier xInvoice_RE-10001.xml. bytes ist das XML in UTF-8.

Vor dem Abruf braucht die Rechnung deliveryDate, orderDescription und paymentType. Die Belegart und die Zahlart brauchen xInvoiceType. Die Firma braucht ustdid und eine Bankverbindung mit IBAN. Der Kunde braucht eInvoiceId. Die Adresse braucht Straße, Ort, PLZ und Land: mit invoiceAddressline1 die Felder invoiceStreet1, invoiceCity, invoiceZipStreet und invoiceCountry, sonst customerStreet1, customerCity, customerZipStreet und customerCountry.

Fehlender WertMeldung
Bank mit IBANcompanyBank.not.found.error
deliveryDatesalesHead.deliveryDate.not.found.error
orderDescriptionsalesHead.orderDescription.not.found.error
paymentTypesalesHead.paymentType.not.found.error
xInvoiceType an der BelegartsalesHead.docType.xInvoiceType.not.found
xInvoiceType an der ZahlartsalesHead.paymentType.xInvoiceType.not.found
USt-Id der Firmacompany.ustdid.not.found.error
eInvoiceId des KundensalesHead.customer.eInvoiceId.not.found

eInvoiceType des Kunden: EU-Kunde. 1 ist XRechnung.

9.3 ZUGFeRD ​

GET /api/zugferd/getPdf/510300

Die Antwort ist JSON mit fileName und bytes. fileName ist ZUGFeRD_ plus Belegnummer plus .pdf, hier ZUGFeRD_RE-10001.pdf. bytes ist das PDF mit der eingebetteten Rechnungs-XML. eInvoiceType 3 am Kunden setzt das Profil EXTENDED (ZUGFeRD Markant), sonst EN16931.

Dieselben Pflichtwerte wie bei der X-Rechnung, ohne eInvoiceId und ohne die Adressprüfung. Fehlt xInvoiceType an der Belegart, gilt salesHead.docType.xInvoiceType.not.found.

10. Konnektor ​

Diese Pfade sind für Konnektoren, nicht für die normale Beleganlage:

MethodePfad
POST/api/salesHead/connector
GET/api/salesHead/connector
POST/api/salesHead/importOrders
POST/api/salesHead/importFromCSV

Shop-Aufträge der Fach-API gehen an POST /api/salesHead/. Die externe Nummer steht in orderDescription oder marktplaceOrderId.

POST /api/salesHead/prepareAndCreate ist ein flacher Import, der intern speichert und Adressen setzt. Bei Betrag 0 kann ein zweiter Beleg entfallen.

POST /api/salesHead/saveSimpleSalesDoc speichert einen reduzierten Beleg. POST /api/salesHead/createDocForPartner legt einen Beleg im Partnerkontext an.

11. Umlagerung ​

Beide Seiten, Verkauf und Einkauf, müssen eine Belegart mit isTransfer haben.

MethodePfadBedeutung
POST/api/salesHead/salesTransfersUmlagerung anlegen
POST/api/salesHead/salesTransfers/salesVerkaufsseite der Umlagerung
GET/api/salesHead/salesTransfers/salesVerkaufsseite lesen
POST/api/salesHead/salesTransfers/materialMaterial der Umlagerung
GET/api/salesHead/getStockTransfersBestandsbuchungen der Umlagerung

Die Einkaufsseite: Transfer. Die Position trägt targetWarehouse.

Bedarf aus dem Auftrag an den Einkauf: POST /api/salesHead/createProposalFromSalesHead.

12. Schnellerfassung ​

MethodePfadBedeutung
GET / POST/api/salesHead/quickOfferSchnellangebot
GET / POST/api/salesHead/quickOrderSchnellauftrag
GET/api/salesHead/quickListSchnellliste
POST/api/salesHead/infoForQuickListZusatzdaten zur Liste
GET/api/salesHead/quickOrderAttachmentAnhang
GET/api/salesHead/quickOrderEmailMail der Schnellerfassung
GET/api/salesHead/realTimeLetzten Echtzeit-Beleg des Benutzers holen und das Kennzeichen zurücksetzen
GET/api/salesHead/invoiceRechnungssicht

13. Auswertungen ​

Listen und Berichte. Filter kommen als Query oder Body, die Antwort ist eine Liste mit meta.

MethodePfad
GET/api/salesHead/salesItemTurnovers
GET/api/salesHead/modifiedSalesItemTurnovers
GET/api/salesHead/showSalesItemTurnovers/{id}
GET/api/salesHead/listBacklog
POST/api/salesHead/sendEmailBacklogInfo
GET/api/salesHead/listMaterialTurnovers
GET/api/salesHead/listMaterialTurnoversByYear
GET/api/salesHead/listMaterialMarginsByYear
GET/api/salesHead/listCustomerTurnover12Months
GET/api/salesHead/listArticleSales12Months
GET/api/salesHead/listCustomerContribution
GET/api/salesHead/customerTurnoverReportParameters
POST/api/salesHead/customerTurnoverReport
GET/api/salesHead/getArticleTurnoverComparisonParameters
GET/api/salesHead/getArticleTurnoverComparison
GET/api/salesHead/getCustomerTurnoverComparisonParameters
GET/api/salesHead/getCustomerTurnoverComparison
POST/api/salesHead/listRecapitulativeStatement
POST/api/salesHead/exportRecapitulativeStatement
POST/api/salesHead/listBusinessDevelopment
GET/api/salesHead/listSalesRepresentativeMarge
GET/api/salesHead/customerListAndArticleTurnovers
GET/api/salesHead/listSalesPersons
GET/api/salesHead/cycleSummary
GET/api/salesHead/salesItemsWithInvoiceCustomer
GET/api/salesHead/getOrderData
POST/api/salesHead/getForceUpdateInfo

listBacklog kann einen CSV-Export im Hintergrund starten.

14. Massenpflege ​

MethodePfadBedeutung
GET/api/salesHead/massPatchLookupDataFelder, die sich massenhaft setzen lassen
PATCH/api/salesHead/massPatchSalesHeadDieselben Felder an vielen Belegen setzen
GET/api/salesHead/massUpdateRegeln der Massenbearbeitung
GET/api/salesHead/operatorsAndValuesOperatoren und Werte
POST/api/salesHead/massUpdateMassenbearbeitung ausführen

Geschlossene und gebuchte Belege bleiben auch hier unverändert, weil jedes Speichern dieselbe Statusprüfung nutzt.

15. Sonderendpunkte ​

Diese beiden Aufrufe sind für Tests, nicht für die produktive Partnerintegration:

MethodePfad
GET/api/salesHead/calculateDisposalFeeSpecialSurcharge/{salesItemId}
GET/api/salesHead/exportOrdersToMarketplaceForTenant

POST /api/salesHead/changeAttachmentIsPrinted/{id} setzt das Druckkennzeichen eines Anhangs.

16. Weitere Beispiele ​

Dieselben Beispiel-Ids wie oben: Kunde KD-1000, Artikel 100100 = ART-1000, 100200 = LM-2000, 100300 = SET-3000, 100400 = VAR-4000, Einheit 6001 = Stück, Lagerplatz 8001 = WE-01. Belegarten 61010 Angebot, 61011 Auftrag, 61020 Lieferschein, 61030 Rechnung. Belege 510010 Angebot, 510100 Auftrag, 510200 Lieferschein, 510300 Rechnung.

16.1 Rahmenkontrakt ​

isContract, Feintyp contractType 1. startDate und endDate begrenzen die Laufzeit. Abrufe sind Folgebelege über referencingDocuments, sobald GET /api/salesHead/docTypes?salesHeadId={id} die Zielart liefert.

json
{
  "docType": { "name": "Rahmenkontrakt" },
  "customer": { "customerNo": "KD-1000" },
  "currency": { "code": "EUR" },
  "docDate": "2026-10-12",
  "startDate": "2026-10-12",
  "endDate": "2027-10-11",
  "orderDescription": "Jahresabruf Tasche",
  "items": [
    {
      "position": 10,
      "quantity": 500,
      "price": 11.5,
      "priceUnit": 1,
      "material": { "id": 100100 },
      "unit": { "code": "ST" },
      "warehouse": { "code": "HAUPT" },
      "vatKey": { "code": "19" }
    }
  ]
}

16.2 Marktplatzauftrag ​

marktplaceOrderId ist die externe Bestellnummer. Dieselbe Nummer ein zweites Mal anzulegen erzeugt einen zweiten Beleg, wenn der Aufruf nicht vorher prüft. Vorher GET /api/salesHead/?docNumber= ersetzt diese Prüfung nicht. Die Liste nach docNumber filtert die Belegnummer, nicht die Marktplatznummer.

json
{
  "docType": { "name": "Auftrag" },
  "customer": { "customerNo": "KD-1000" },
  "currency": { "code": "EUR" },
  "marktplaceOrderId": "AMZ-304-1234567",
  "orderDescription": "AMZ-304-1234567",
  "orderDate": "2026-10-12",
  "partlyDelivery": false,
  "items": [
    {
      "position": 10,
      "quantity": 1,
      "price": 19.9,
      "priceUnit": 1,
      "material": { "id": 100400 },
      "variantCode": "ROT-M",
      "unit": { "code": "ST" },
      "warehouse": { "code": "HAUPT" },
      "vatKey": { "code": "19" }
    }
  ]
}

16.3 Attribut an der Position ​

attributeCode ist der gespeicherte Merkmalcode des Artikels, gelesen aus der Attributpflege. attributeOptions am Item wird beim Speichern in attributeCode umgerechnet, wenn material.id gesetzt ist.

json
{
  "docType": { "name": "Auftrag" },
  "customer": { "customerNo": "KD-1000" },
  "currency": { "code": "EUR" },
  "items": [
    {
      "position": 10,
      "quantity": 3,
      "price": 8.5,
      "priceUnit": 1,
      "material": { "id": 100500 },
      "attributeCode": "MATERIAL",
      "unit": { "code": "ST" },
      "warehouse": { "code": "HAUPT" },
      "vatKey": { "code": "19" }
    }
  ]
}

100500 ist PIM-5000.

16.4 Preis vor dem Speichern ​

POST /api/salesHead/getSalesPrice und GET /api/salesHead/getSalesItemPrice rechnen denselben Preis. Ids, kein Suchschlüssel.

json
{
  "materialId": 100100,
  "customerId": 30001,
  "docTypeId": 61011,
  "quantity": 2,
  "unitId": 6001,
  "currencyId": 1,
  "docDate": "2026-10-12",
  "warehouseId": 7001
}

30001 ist Kunde KD-1000, 7001 das Lager HAUPT, 1 die Währung EUR.

Response (Auszug)

json
{
  "price": 12.9,
  "grossPrice": 15.35,
  "priceUnit": 1,
  "quantity": 2,
  "variantCode": null,
  "materialId": 100100,
  "customerId": 30001,
  "foundFrom": "Material",
  "priceFoundInMaterial": true,
  "customerPriceDiscounts": [],
  "minOrderQuantity": 1
}

foundFrom nennt die Preisquelle: Material, MaterialPrices, SalesPriceList, SalesCustomerPrice, SalesCustomerMatGroupPrice, CashRegister oder none. Variante zusätzlich mit variantCode oder materialVariantId.

Artikel zur Position suchen: GET /api/salesHead/findMaterial?customerId=30001&materialId=100100&warehouseId=7001. Ohne Treffer: { "material": {}, "unit": {} }. Für eine Set-Komponente isForSetItem=true. Ein Set-Artikel als Komponente bricht mit setItem.material.isSet.error ab. Ein unbekannter Artikel mit material.not.found.error.

16.5 Angebot annehmen, dann liefern und rechnen ​

  1. Angebot anlegen, Abschnitt Angebot. Ergebnis 510010.
  2. Zielarten lesen: GET /api/salesHead/docTypes?salesHeadId=510010. Die Auftragsart sei 61011.
  3. Auftrag erzeugen:
json
{
  "salesHeadIds": [510010],
  "docType1": { "id": 61011 },
  "isDocument1Created": true
}

Antwort document1Ids: [510100]. Nur Position 71001 des Angebots, die Position 71002 bleibt offen:

json
{
  "salesHeadIds": [510010],
  "docType1": { "id": 61011 },
  "isDocument1Created": true,
  "salesItemsToCopy": [71001]
}
  1. Lieferschein, Abschnitt Lieferschein. 1:1 übernimmt alle offenen Auftragspositionen. Mit salesItemsToCopy: [71011] nur diese Position. Ergebnis 510200.
  2. Rechnung aus diesem Lieferschein. POST /api/salesHead/getDeliveryNotes macht dasselbe wie GET /api/salesHead/createInvoicesFromDelNotes: aus den übergebenen Belegen werden Rechnungen. salesHeads ist eine kommagetrennte Id-Liste, im JSON ein Feld.
json
{
  "salesHeads": "510200",
  "docTypeId": 61030,
  "docDate": "2026-10-12"
}

Response: { "ids": "510300" }

Mehrere Lieferscheine desselben Kunden mit Sammelrechnung werden eine Rechnung, sonst eine Rechnung je Lieferschein. GET /api/salesHead/createInvoicesFromDelNotes?salesHeads=510200&docTypeId=61030 liefert die neuen Ids als Text, nicht als Objekt.

  1. Status: GET /api/salesHead/status/510300. Steht isPosted auf true, lehnt POST /api/salesHead/ jede Änderung ab.
  2. PDF: POST /api/report/salesHeadDownload mit { "ids": [510300] }, Abschnitt PDF.
  3. X-Rechnung: GET /api/salesHead/getXInvoiceXml/510300, Abschnitt X-Rechnung.
  4. ZUGFeRD: GET /api/zugferd/getPdf/510300, Abschnitt ZUGFeRD.

Eine Rechnung ohne Lieferschein entsteht direkt mit POST /api/salesHead/ und docType.name Rechnung, Abschnitt Rechnung.

16.6 Storno ​

Zuerst GET /api/salesHead/checkCancelDocument?id=510100. Die Storno-Belegart hat isOrder und orderType 1. refSalesHeadId ist der Originalauftrag. Das Fulfillment wird vorher storniert.

json
{
  "docType": { "name": "Auftragsstorno" },
  "customer": { "customerNo": "KD-1000" },
  "refSalesHeadId": 510100,
  "currency": { "code": "EUR" }
}

Schlägt das Fulfillment fehl, enthält die Antwort fulfillmentCancelFail: true und fulfillmentCancelFailMessage. Der Storno-Beleg wird dann nicht gespeichert.

16.7 Gutschrift und Chargenretoure ​

Wert- oder Mengengutschrift wählt die Anwendung aus der Rechnung. 510300 ist die Rechnung.

json
{ "salesHeadIds": [510300] }
json
{
  "success": [
    { "salesHeadId": 510300, "docNumber": "GS-10001", "creditNoteId": 510400 }
  ],
  "errors": []
}

Retourenmenge einer Charge. returnQuantity über 0 wird übernommen. emailTo ist hier nicht beteiligt.

POST /api/salesHead/return

json
{
  "customerNo": "KD-1000",
  "orderDescription": "AB-10001",
  "reasonCode": "RETOURE",
  "returnComment": "MHD zu kurz",
  "items": [
    {
      "sku": "LM-2000",
      "itemCode": "LM-2000",
      "returnQuantity": 0,
      "batchnums": [
        {
          "batchnum": "LOT-2026-10-A",
          "returnQuantity": 2,
          "reasonCode": "MHD"
        }
      ]
    }
  ]
}

16.8 Zusammenführen ​

GET /api/salesHead/mergableSalesHead/510100 listet Belege, die sich mit 510100 zusammenführen lassen. POST /api/salesHead/merge zieht targetIds in sourceId.

json
{
  "sourceId": 510100,
  "targetIds": [510101, 510102]
}

Antwort: { "success": true }. GET /api/salesHead/merge/510100 liest das Ergebnis.

16.9 Versand und Mail ​

Versandart und Fracht per Id. POST /api/salesHead/updateShipping

json
{
  "orderId": 510100,
  "shipping": { "id": 6201 },
  "freight": { "id": 6202 }
}

Antwort: { "success": true }. Fehlt der Auftrag: Ressource nicht gefunden. Carrier und Versandprodukt kommen aus der Versandart.

Mail zuerst vorbereiten. POST /api/salesHead/salesHeadEmailDialog

json
{ "id": 510100, "templateKey": "SALES_ORDER" }

Die Antwort enthält email.emailFrom, email.emailTo, email.subject, email.body, contacts. Senden erwartet die Empfänger als Liste. emailTo.join setzt voraus, dass emailTo ein Array ist.

POST /api/salesHead/sendSalesEmail

json
{
  "ids": [510100],
  "emailFrom": "vertrieb@firma.example",
  "emailTo": ["einkauf@kunde.example"],
  "emailCc": ["buchhaltung@firma.example"]
}

Response: { "success": true, "failedList": [] }

Ein fehlgeschlagener Beleg steht in failedList mit salesHeadId und message. success ist dann false.

16.10 Flacher Import ​

POST /api/salesHead/prepareAndCreate speichert über denselben Weg wie POST /api/salesHead/ und setzt danach die Adressen. docType und shipping sind Namen, customerNumber die Kundennummer, items[].material eine Zeichenkette. Fehlt customerNumber, wird 100 plus companyCode verwendet. Das Belegdatum setzt der Aufruf auf heute.

json
{
  "docType": "Auftrag",
  "customerNumber": "KD-1000",
  "currency": "EUR",
  "language": "de",
  "profitCenter": "B2C",
  "shipping": "DHL",
  "items": [
    {
      "material": "ART-1000",
      "quantity": 2,
      "price": 12.9
    }
  ]
}

Response: { "id": 510100 }

Ist der Gesamtbetrag 0, wird der Beleg auf Status 2 gesetzt und ein zweiter Folgebeleg entfällt.

17. Endpoint-Katalog ​

17.1 Beleg ​

MethodePfad
GET/api/salesHead/{id}
GET/api/domains/salesHead
POST/api/salesHead/
DELETE/api/salesHead/
GET/api/salesHead/status/{id}
GET/api/salesHead/isSend/{id}
POST/api/salesHead/receiverAddress/{id}
GET/api/salesHead/docTypes
GET/api/salesHead/checkCancelDocument
POST/api/salesHead/setPrinted
POST/api/salesHead/updateSalesHeadTags
POST/api/salesHead/changeAttachmentIsPrinted/{id}
GET/api/salesHead/salesOrders
POST/api/salesHead/salesOrders
GET/api/salesHead/salesOffers
POST/api/salesHead/salesOffers
GET/api/salesHead/salesDeliveryNotes
POST/api/salesHead/salesDeliveryNotes
GET/api/salesHead/salesInvoices
POST/api/salesHead/salesInvoices
GET/api/salesHead/salesContracts
POST/api/salesHead/salesContracts
GET/api/salesHead/cashRegisterReceipts
GET/api/salesHead/showOrders
GET/api/salesHead/getOpenOrders
GET/api/salesHead/ordersByEanOrTracking
GET/api/salesHead/invoice
GET/api/salesHead/getOrderData
GET/api/salesHead/realTime

17.2 Kette, Preis, Bestand ​

MethodePfad
POST/api/salesHead/referencingDocuments
GET/api/salesHead/referencingDocuments
POST/api/salesHead/salesItemsFromSalesHeads
POST/api/salesHead/splitSales
GET/api/salesHead/merge/{id}
GET/api/salesHead/mergableSalesHead/{id}
POST/api/salesHead/merge
GET/api/salesHead/getDeliveryNotesParameters
GET/api/salesHead/getDeliveryNotes
POST/api/salesHead/getDeliveryNotes
GET/api/salesHead/createInvoicesFromDelNotes
POST/api/salesHead/saveDeliveryNotesWithCustomerBundle
POST/api/salesHead/createCreditNotes
POST/api/salesHead/return
GET/api/salesHead/getReturnDeliveryEmail
GET/api/salesHead/createReturnTemplate
GET/api/salesHead/triggerCreateReturnTemplate
POST/api/salesHead/resetPreInvoiceCreated
POST/api/salesHead/resetPreInvoiceAndFinalInvoiceCreated
POST/api/salesHead/unlockDeliveryBlocks
POST/api/salesHead/createProposalFromSalesHead
GET/api/salesHead/findMaterial
GET/api/salesHead/getSalesItemPrice
POST/api/salesHead/getSalesPrice
GET/api/salesHead/getSalesItemQuantity
POST/api/salesHead/materialsVatKeys
POST/api/salesHead/getMaterialsVatKeys
GET/api/salesHead/getStockData
POST/api/salesHead/oversoldList
GET/api/salesHead/salesHeadLookupData
GET/api/salesHead/getTextsForMaterial
GET/api/salesHead/getDatesForOrder
POST/api/salesHead/getForceUpdateInfo

17.3 Versand, Finanzen, Konnektor, Masse, Berichte ​

Versand: validateShipment, updateShipping, refreshSalesHeadsShippingData, extract, showShipmentReport, unfinishedShipments, lastTransportationNumber, calculateMeasures, getSalesHeadMeasurements, pickNumberList, assignPickNumber, removePickNumber, skipPacking, DELETE /packs/{id}, materialLabel, salesItemsPrint.

Finanzen und Mail: salesHeadEmailDialog, sendSalesEmail, getSalesHeadEmails, getSalesHeadEdis, emailHistory, getVouchers/{id}, listAllNonTransferedInvoices, datevCheck, transferSingleInvoiceToFinance, transferInvoicesToFinance, getXInvoiceXml/{id}, getEInvoicePrefixList, getCustomerTaxpayerPkList, getTaxExemptionDefaultReasonCodeList, invoiceRecurrences.

Konnektor und Import: POST /connector, GET /connector, importOrders, importFromCSV, prepareAndCreate, saveSimpleSalesDoc, createDocForPartner.

Umlagerung: salesTransfers, salesTransfers/sales, salesTransfers/material, getStockTransfers.

Schnell: quickOffer, quickOrder, quickList, infoForQuickList, quickOrderAttachment, quickOrderEmail.

Masse: massPatchLookupData, PATCH /massPatchSalesHead, GET /massUpdate, operatorsAndValues, POST /massUpdate.

Auswertungen: die Pfade aus Auswertungen. Test: die Pfade aus Sonderendpunkte.

17.4 Position, Preis, Retoure, Vertrag ​

MethodePfadBedeutung
GET/api/salesItem/{id}Eine Position
GET/api/domains/salesItemPositionen über Generic Domain lesen
GET/api/salesItem/showForGridPositionen für die Tabelle
POST/api/salesItem/getSalItemRequirementsBedarf
POST/api/salesItem/validateAvailableStockBestand prüfen
GET/api/salesItem/lastSalesPriceListLetzter Preis
GET/api/salesItem/averageSalesPriceListDurchschnittspreis
GET/api/salesItem/attributeAttribut der Position
GET/api/salesItem/purchaseRequestBestellanforderung lesen
POST/api/salesItem/createPurchaseRequestBestellanforderung anlegen
POST/api/salesItem/updatePurchaseRequestBestellanforderung ändern
POST/api/salesItem/scriptBlockSkript an der Position
GET/api/salesItem/customerBundlesKundenbündel
GET/api/salesItem/salesProductionDetail/{id}Produktionsdetail
GET/api/salesItem/reimbursementsErstattungen
GET/api/salesItem/checkSalesItemIsDeletable/{salesItemId}Ob die Position löschbar ist
PATCH/api/salesItem/massPatchSalesItemMehrere Positionen setzen
GET/api/salesDocType/{id}Eine Belegart oder die Liste
GET/api/salesCustomerPrice/{id}Ein Kundenpreis
POST/api/salesCustomerPrice/Kundenpreis speichern
DELETE/api/salesCustomerPrice/Kundenpreis löschen
POST/api/salesCustomerPrice/materialCustomerSalesPriceMehrere Preise, salesCustomerPrices
POST/api/salesImport/fetchFromCSVPositionen aus CSV, importMatchingHeadId und fileContent
POST/api/salesImport/itemsImportzeilen
POST/api/salesImport/importCSVCSV importieren
POST/api/salesImport/importFromCSVBeleg aus CSV, items
POST/api/salesImport/updatePricesPreise nachziehen, items
POST/api/salesExport/exportBelege exportieren, ids
GET/api/documentRules/{id}Eine Belegregel
POST/api/documentRules/Regel speichern
DELETE/api/documentRules/{id}Regel löschen
GET/api/zugferd/getPdf/{id}ZUGFeRD-PDF des Belegs, JSON mit bytes und fileName
POST/api/report/salesHeadDownloadRechnungs-PDF als Datei, Body ids
POST/api/report/salesHeadPrintDasselbe PDF inline
GET/api/returnHead/{id}Eine Retoure
GET/api/returnHead/getReturnHeadByOrderId/{id}Retoure zum Auftrag
POST/api/returnHead/Retoure speichern, Antwort { "id" }
POST/api/returnHead/quickSaveSchnell anlegen, customerNo
POST/api/returnHead/createSalesHeadVerkaufsbeleg, Antwort { "salesHeadId" }
POST/api/returnHead/openSalesHeadBeleg öffnen
DELETE/api/returnHead/{id}Retoure löschen, Antwort { "success": true }
POST/api/returnHead/batchRemoveMehrere, ids
GET/api/returnHead/getReturnTrackingData/{id}Sendungsverfolgung
GET/api/returnHead/getSalesVouchers/{id}Verkaufsbelege
GET/api/returnHead/getPurVouchers/{id}Einkaufsbelege
POST/api/returnHead/returnPackPackstück, id
DELETE/api/returnHead/returnPack/{id}Packstück löschen
POST/api/returnHead/printDocumentsDokumente drucken
GET/api/contract/{id}Ein Vertrag
POST/api/contract/Vertrag speichern
DELETE/api/contract/{id}Vertrag löschen, Antwort { "success": true }
POST/api/contract/fromOfferAus einem Angebot, salesHeadId
POST/api/contract/renewVerlängern
POST/api/contract/approveFreigeben, approvedSign
GET/api/contract/{id}/externalAuditExternes Protokoll
GET/api/contract/attachmentsAnhänge
GET/api/contract/documentsDokumente
GET/api/contract/externalDesignsExterne Layouts
POST/api/contract/previewExternalDesignLayoutvorschau
POST/api/contract/setExternalDesignLayout setzen
POST/api/contract/sendToExternalExtern senden
GET/api/contract/externalContractContentExterner Inhalt
POST/api/contract/externalSignCallbackSignatur-Rückmeldung
POST/api/contract/externalAuditEventExternes Ereignis

POST /api/salesImport/fetchFromCSV liest importMatchingHeadId, fileContent und optional salesHeadId sowie warehouseId. Fehlt die Spaltenzuordnung: HTTP 404. POST /api/salesImport/updatePrices liest currency, customer, docDate, docType und items.

POST /api/salesExport/export nimmt ids. Ohne Ids: financeExport.ids.not.found. Kein Beleg: salesHeads.not.found. Optional isDeliveryNote, importMatchingHeadId und characterEncoding.

json
{ "ids": [510100] }

POST /api/returnHead/quickSave liest customerNo, items, orderDescription, notes und shipping. Unbekannter Kunde: customer.not.found.error. Verkaufsbeleg aus der Retoure 97001, Belegart Rechnung 61030, Lagerplatz 8001:

json
{
  "returnHeadId": 97001,
  "docTypeId": 61030,
  "stockPlaceId": 8001
}

Response: { "salesHeadId": … }

97001 ist die Retoure. Fehlt die Belegart: salesDocType.not.found.error. Fehlt die Retoure: returnHead.not.found.error. openSalesHead liest dieselben Felder. Ist die Belegart ein Auftrag, gelten exchangeItems, sonst items.

Vertrag aus dem Angebot 510010:

json
{ "salesHeadId": 510010 }

Response: { "id": …, "alreadyExisted": false }

Kein Angebot: contract.fromOffer.notOffer. Angebot ohne Kunde: contract.fromOffer.customerRequired. Ohne Id: HTTP 404. Verlängern liest refContractHead.id, validUntil, optional validFrom, totalAmount und isCloseOldContract. Fehlt der alte Vertrag: HTTP 404. Antwort { "id" }. Freigeben liest contractHeadId und approvedSign. Leere Signatur: contract.approve.sign.empty.

18. Häufige Fehler ​

SituationUrsache
message.salesHead.already.closed.errorstatus ab 2 oder isPosted
Ressource nicht gefundenGET /api/salesHead/{id} ohne Beleg
fulfillmentCancelFailAuftragsstorno, Fulfillment lehnt ab
Leeres success bei splitSalesids oder docTypeId fehlen, oder openQuantity ist 0
Leeres success bei createCreditNotessalesHeadIds fehlen oder die Rechnung lässt keine Gutschrift zu
Zielbeleg fehltKeine SalesHeadDocRule von der Quellart zur Zielart
Lieferschein nicht in docTypesblockedDelivery am Auftrag
Position ohne ArtikelIn items[] wurde ein Suchschlüssel statt der Artikel-id gesendet
Doppelter Shop-AuftragDieselbe marktplaceOrderId erneut anlegen
financeExport.ids.not.foundsalesExport/export ohne ids
salesHeads.not.foundKeine der Ids ist ein Verkaufsbeleg
customer.not.found.errorquickSave ohne bekannten customerNo
salesDocType.not.found.errorcreateSalesHead oder Rechnung aus Lieferschein ohne Belegart
returnHead.not.found.errorreturnHeadId unbekannt
contract.fromOffer.notOffersalesHeadId ist kein Angebot
contract.fromOffer.customerRequiredDas Angebot hat keinen Kunden
contract.approve.sign.emptyFreigabe ohne approvedSign
companyBank.not.found.errorX-Rechnung oder ZUGFeRD ohne Bank mit IBAN
salesHead.deliveryDate.not.found.errorX-Rechnung oder ZUGFeRD ohne deliveryDate
salesHead.orderDescription.not.found.errorX-Rechnung oder ZUGFeRD ohne orderDescription
salesHead.paymentType.not.found.errorX-Rechnung oder ZUGFeRD ohne paymentType
salesHead.docType.xInvoiceType.not.foundBelegart ohne xInvoiceType
salesHead.paymentType.xInvoiceType.not.foundZahlart ohne xInvoiceType
company.ustdid.not.found.errorFirma ohne USt-Id
salesHead.customer.eInvoiceId.not.foundX-Rechnung, Kunde ohne eInvoiceId

19. Ablauf Auftrag bis Rechnung ​

  1. Kunde, Belegart Auftrag, Artikel, Einheit, Lager und Steuer lesen.
  2. POST /api/salesHead/ mit Positionen. Variante über variantCode, Set über setItems, Charge über batchnum.
  3. GET /api/salesHead/docTypes?salesHeadId={id} und die Lieferschein-Id merken.
  4. POST /api/salesHead/referencingDocuments mit dieser Zielart. Bei Teillieferung nur die gewünschten Positions-Ids.
  5. Aus dem Lieferschein GET /api/salesHead/createInvoicesFromDelNotes.
  6. Status über GET /api/salesHead/status/{id}. Nach isPosted den Beleg nicht mehr per POST /api/salesHead/ ändern.
  7. Gutschrift mit POST /api/salesHead/createCreditNotes, Retoure mit POST /api/salesHead/return.

Fachlicher Hintergrund: Aufträge, Auftrag zu Rechnung, Angebote, Lieferscheine, Rechnungen, Retouren.

Nur für reybex-Partner. Nicht für Endkunden bestimmt.