Darstellung
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.
| Ziel | Suchschlüssel |
|---|---|
Kunde customer | customerNo |
| Artikel am Kopf, falls als ToOne | matCode, sonst sku |
| Lager | code, sonst name |
| Lagerplatz | stockplaceCode oder name, immer mit warehouse |
| Belegart, Währung, Einheit, Steuer, Zahlungsbedingung | code, 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.
| Situation | HTTP | Körper |
|---|---|---|
| Beleg nicht gefunden | Fachlicher Fehler | { "error": "…" } oder { "data": { "error": "…" } } |
| Beleg geschlossen oder gebucht | 500 | message.salesHead.already.closed.error |
| Fehlende Anmeldung | 401 | — |
2. Belegarten
Flags und Feintypen von SalesDocType:
| Flag | Feintyp | Bedeutung |
|---|---|---|
isOffer | offerType 1 | Angebot |
isContract | contractType 1 | Rahmenkontrakt |
isOrder | orderType 0 | Auftragsbestätigung |
isOrder | orderType 1 | Auftragsstorno |
isDelnote | delnoteType 1 | Lieferschein |
isDelnote | delnoteType 2 | Eil-Lieferschein |
isDelnote | delnoteType 3 | Rücklieferung |
isInvoice | invoiceType 1 | Rechnung |
isInvoice | invoiceType 2 | Sammelrechnung |
isInvoice | invoiceType 6 | Proforma |
isInvoice | invoiceType 7 | Anzahlungsrechnung |
isInvoice | invoiceType 8 | Anzahlungsrechnung B2B |
isInvoice | invoiceType 9 | Schlussrechnung |
isCreditnote | creditnoteType 1 | Wertgutschrift |
isCreditnote | creditnoteType 2 | Mengengutschrift |
isCreditnote | creditnoteType 3 | Storno-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:
| Feld | Wirkung |
|---|---|
calculatePrice | Preis im Ziel neu berechnen |
searchVatKey | Steuerschlüssel neu suchen |
forceToUpdateWarehouse | Lager im Ziel überschreiben |
splitDocumentPerItem | Ein Zielbeleg je Position |
resolveBom | Stückliste auflösen |
overReferencedQuantityPercentage | Erlaubte Mehrmenge gegenüber der offenen Menge |
ignoreQuantityOnItemCopy | Menge beim Kopieren nicht übernehmen |
resetNewDocumentOnCopy | Ziel wie ein neuer Beleg zurücksetzen |
isManuallyClosed | Quelle beim Kopieren manuell schließen |
isDisabled | Regel 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.
| Feld | Bedeutung |
|---|---|
salesHeadIds | Quellbelege |
docType1, docType2 | Bis zu zwei Zielbelegarten, je { "id" } |
isDocument1Created, isDocument2Created | Ob das jeweilige Ziel gespeichert wird |
closeRefDocAsManuel | Quelle manuell schließen |
salesItemsToCopy | Nur diese Positionen |
isSaved | Dialogeinstellung 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:
| Quelle | Ziel | Aufruf |
|---|---|---|
| Angebot | Auftrag | referencingDocuments mit Auftrags-Belegart |
| Auftrag | Lieferschein | referencingDocuments mit der Lieferschein-Belegart |
| Lieferschein | Rechnung | GET /api/salesHead/createInvoicesFromDelNotes |
| Rechnung | Gutschrift | POST /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
| Aufruf | Bedeutung |
|---|---|
GET /api/salesHead/mergableSalesHead/{id} | Belege, die sich mit diesem Beleg zusammenführen lassen |
GET /api/salesHead/merge/{id} | Zusammenführungsdaten |
POST /api/salesHead/merge | Zusammenfü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
| Feld | Bedeutung |
|---|---|
docType | Belegart |
docNumber | Belegnummer |
customer | Kunde |
docDate, orderDate, dueDate | Beleg-, Bestell- und Fälligkeitsdatum |
deliveryDate, desiredInvoiceDate | Liefer- und Wunschrechnungsdatum |
paymcond, currency, exchangeRate | Kondition, Währung, Kurs |
orderDescription | Bestellzeichen, oft die externe Bestellnummer |
marktplaceOrderId | Marktplatz-Bestellnummer, Duplikatschutz |
paymentType | Zahlart |
shipping | Versandart |
partlyDelivery | Teillieferung erlaubt |
blockedDelivery | Liefersperre |
refSalesHead | Vorgänger |
status | Belegstatus; ab 2 ist der Beleg für Updates geschlossen |
orderStatus | Auftragsstatus, Typen 0 offen bis 8 Klärung |
connectorStatus, sendStatus, paymentStatus | Konnektor, Versand, Zahlung |
isPaid, isPacked, isPosted, isPrinted | Bezahlt, gepackt, gebucht, gedruckt |
isSend, isEmailSend, isInvoiceSend | Versandkennzeichen |
isCanceled, isDelete, isManuallyClosed | Storno, Löschung, manueller Abschluss |
isOfferConfirmed, isOfferLost | Angebot angenommen oder verloren |
isReturnOrder | Retourenauftrag |
pickNumber | Kommissioniernummer |
receiver* | Empfängeradresse, Snapshot |
customer* | Kundenadresse, Snapshot |
invoice* | Rechnungsadresse, Snapshot |
language | Sprache des Belegs |
notes | Notizen |
marktplace | Marktplatz |
project | Projekt |
salesPerson | Verkäufer |
freight | Fracht |
isGrossPrice | Preise am Beleg sind brutto |
isPartlyDeliveryRequested | Teillieferung ist gewünscht |
isSalesSetSeparated | Set-Positionen dieses Belegs getrennt |
isPreInvoiceCreated | Anzahlungsrechnung ist erzeugt |
subTotal, taxAmount, totalAmount | Netto, Steuer, Brutto |
bankIban, bankBic, bankName, bankHolder | Bank am Beleg |
isEinvoice, einvoiceNumber, einvoiceStatusText | E-Rechnung, Nummer und Status |
fulfillmentOrderId | Fulfillment-Auftrag |
refOrderDocNumber | Belegnummer des referenzierten Auftrags |
offerLoseReason | Grund, wenn das Angebot verloren ist |
customFields | Zusatzfelder |
items | Positionen |
packs | Packstücke |
discounts, texts, tags | Rabatte, 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
| Feld | Bedeutung |
|---|---|
material | Artikel, in der Liste per id |
position | Positionsnummer |
quantity | Menge |
openQuantity | Noch nicht weitergereichte Menge |
price, grossPrice, priceUnit | Netto, Brutto, Preiseinheit |
isGrossPrice, calculatePrice, isPriceSetManually | Preissteuerung |
unit, warehouseUnit | Verkaufs- und Lagereinheit |
warehouse, stockplace | Lager und Platz |
vatKey | Steuer |
materialVariant | Variante, per id |
variantCode, attributeCode | Varianten-Code und Attribut |
batchnum | Charge |
shortDescription | Bezeichnung der Position |
customerMatCode, customerMatName | Artikelnummer und Bezeichnung des Kunden |
deliveryDate | Lieferdatum der Position |
nettAmount, totalAmount | Netto und Brutto der Position |
deliveryStatus, deliveredQuantity | Lieferfortschritt |
invoiceStatus, invoicedQuantity | Rechnungsfortschritt |
isOversold | Überverkauf |
isSentToFulfillment | An das Fulfillment übergeben |
refSalesItem | Vorgängerposition |
isSetHead, isSetItem, setItems | Set-Kopf und Komponenten |
bomItemNumber, refSetItem, setItemQuantity | Set-Zeile, Bezug zum Kopf, Menge je Set |
targetWarehouse | Ziellager bei Umlagerung |
customFields | Zusatzfelder |
isDelete, isCanceled, isManuallyClosed | Position 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
| Methode | Pfad | Inhalt |
|---|---|---|
GET / POST | /api/salesHead/salesOrders | Aufträge |
GET / POST | /api/salesHead/salesOffers | Angebote |
GET / POST | /api/salesHead/salesDeliveryNotes | Lieferscheine |
GET / POST | /api/salesHead/salesInvoices | Rechnungen |
GET / POST | /api/salesHead/salesContracts | Kontrakte |
GET | /api/salesHead/cashRegisterReceipts | Kassenbelege |
GET | /api/salesHead/?docNumber=AB-100 | Liste, gefiltert auf Belegnummern, die den Text enthalten |
GET | /api/salesHead/showOrders | Auftragsliste, Query isSend als true oder false |
GET | /api/salesHead/getOpenOrders | Offene Aufträge |
GET | /api/salesHead/ordersByEanOrTracking | Suche ü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
| Aufruf | Bedeutung |
|---|---|
GET /api/salesHead/findMaterial | Artikel für eine Position suchen |
GET /api/salesHead/getSalesItemPrice | Positionspreis |
POST /api/salesHead/getSalesPrice | Preisberechnung |
GET /api/salesHead/getSalesItemQuantity | Menge und offene Menge |
POST /api/salesHead/materialsVatKeys | Steuerschlüssel mehrerer Artikel |
POST /api/salesHead/getMaterialsVatKeys | Steuerschlüssel zu den übergebenen Artikeln |
GET /api/salesHead/salesHeadLookupData | Nachschlagelisten der Maske |
GET /api/salesHead/getTextsForMaterial | Textbausteine 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/resetPreInvoiceCreatedPOST /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
| Aufruf | Bedeutung |
|---|---|
GET /api/salesHead/validateShipment | Sendung prüfen |
POST /api/salesHead/updateShipping | Versanddaten schreiben |
POST /api/salesHead/refreshSalesHeadsShippingData | Versanddaten neu lesen |
POST /api/salesHead/extract | Sendung heraustrennen |
GET /api/salesHead/showShipmentReport | Versandbericht |
GET /api/salesHead/unfinishedShipments | Offene Sendungen |
GET /api/salesHead/lastTransportationNumber | Letzte Transportnummer |
GET /api/salesHead/calculateMeasures | Maße, Query salesHeadId |
GET /api/salesHead/getSalesHeadMeasurements | Gespeicherte Maße |
GET /api/salesHead/pickNumberList | Kommissioniernummern |
POST /api/salesHead/assignPickNumber | Nummer zuweisen |
POST /api/salesHead/removePickNumber | Nummer entfernen |
POST /api/salesHead/skipPacking | Packen überspringen |
DELETE /api/salesHead/packs/{id} | Packstück löschen |
POST /api/salesHead/materialLabel | Artikeletikett |
GET /api/salesHead/getDatesForOrder | Liefertermine |
POST /api/salesHead/salesItemsPrint | Positionen drucken |
9. E-Mail, FiBu, E-Rechnung
| Aufruf | Bedeutung |
|---|---|
POST /api/salesHead/salesHeadEmailDialog | Mail-Dialog, Body id, optional templateKey |
POST /api/salesHead/sendSalesEmail | Mail senden, Body ids |
GET /api/salesHead/getSalesHeadEmails | Gesendete Mails |
GET /api/salesHead/getSalesHeadEdis | EDI-Nachrichten |
GET /api/salesHead/emailHistory | Mail-Historie |
GET /api/salesHead/getVouchers/{id} | Zugeordnete FiBu-Belege |
GET /api/salesHead/listAllNonTransferedInvoices | Noch nicht an die Finanzbuchhaltung übergebene Rechnungen |
POST /api/salesHead/datevCheck | DATEV-Prüfung |
GET /api/salesHead/transferSingleInvoiceToFinance | Eine Rechnung übergeben |
POST /api/salesHead/transferInvoicesToFinance | Mehrere Rechnungen übergeben |
GET /api/salesHead/getXInvoiceXml/{id} | XRechnung-XML |
POST /api/salesHead/getEInvoicePrefixList | E-Rechnungs-Präfixe |
POST /api/salesHead/getCustomerTaxpayerPkList | Steuerpflichtigen-Schlüssel des Kunden |
GET /api/salesHead/getTaxExemptionDefaultReasonCodeList | Steuerbefreiungsgrü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 Wert | Meldung |
|---|---|
| Bank mit IBAN | companyBank.not.found.error |
deliveryDate | salesHead.deliveryDate.not.found.error |
orderDescription | salesHead.orderDescription.not.found.error |
paymentType | salesHead.paymentType.not.found.error |
xInvoiceType an der Belegart | salesHead.docType.xInvoiceType.not.found |
xInvoiceType an der Zahlart | salesHead.paymentType.xInvoiceType.not.found |
| USt-Id der Firma | company.ustdid.not.found.error |
eInvoiceId des Kunden | salesHead.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:
| Methode | Pfad |
|---|---|
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.
| Methode | Pfad | Bedeutung |
|---|---|---|
POST | /api/salesHead/salesTransfers | Umlagerung anlegen |
POST | /api/salesHead/salesTransfers/sales | Verkaufsseite der Umlagerung |
GET | /api/salesHead/salesTransfers/sales | Verkaufsseite lesen |
POST | /api/salesHead/salesTransfers/material | Material der Umlagerung |
GET | /api/salesHead/getStockTransfers | Bestandsbuchungen der Umlagerung |
Die Einkaufsseite: Transfer. Die Position trägt targetWarehouse.
Bedarf aus dem Auftrag an den Einkauf: POST /api/salesHead/createProposalFromSalesHead.
12. Schnellerfassung
| Methode | Pfad | Bedeutung |
|---|---|---|
GET / POST | /api/salesHead/quickOffer | Schnellangebot |
GET / POST | /api/salesHead/quickOrder | Schnellauftrag |
GET | /api/salesHead/quickList | Schnellliste |
POST | /api/salesHead/infoForQuickList | Zusatzdaten zur Liste |
GET | /api/salesHead/quickOrderAttachment | Anhang |
GET | /api/salesHead/quickOrderEmail | Mail der Schnellerfassung |
GET | /api/salesHead/realTime | Letzten Echtzeit-Beleg des Benutzers holen und das Kennzeichen zurücksetzen |
GET | /api/salesHead/invoice | Rechnungssicht |
13. Auswertungen
Listen und Berichte. Filter kommen als Query oder Body, die Antwort ist eine Liste mit meta.
| Methode | Pfad |
|---|---|
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
| Methode | Pfad | Bedeutung |
|---|---|---|
GET | /api/salesHead/massPatchLookupData | Felder, die sich massenhaft setzen lassen |
PATCH | /api/salesHead/massPatchSalesHead | Dieselben Felder an vielen Belegen setzen |
GET | /api/salesHead/massUpdate | Regeln der Massenbearbeitung |
GET | /api/salesHead/operatorsAndValues | Operatoren und Werte |
POST | /api/salesHead/massUpdate | Massenbearbeitung 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:
| Methode | Pfad |
|---|---|
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
- Angebot anlegen, Abschnitt Angebot. Ergebnis
510010. - Zielarten lesen:
GET /api/salesHead/docTypes?salesHeadId=510010. Die Auftragsart sei61011. - 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]
}- Lieferschein, Abschnitt Lieferschein. 1:1 übernimmt alle offenen Auftragspositionen. Mit
salesItemsToCopy: [71011]nur diese Position. Ergebnis510200. - Rechnung aus diesem Lieferschein.
POST /api/salesHead/getDeliveryNotesmacht dasselbe wieGET /api/salesHead/createInvoicesFromDelNotes: aus den übergebenen Belegen werden Rechnungen.salesHeadsist 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.
- Status:
GET /api/salesHead/status/510300. StehtisPostedauftrue, lehntPOST /api/salesHead/jede Änderung ab. - PDF:
POST /api/report/salesHeadDownloadmit{ "ids": [510300] }, Abschnitt PDF. - X-Rechnung:
GET /api/salesHead/getXInvoiceXml/510300, Abschnitt X-Rechnung. - 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
| Methode | Pfad |
|---|---|
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
| Methode | Pfad |
|---|---|
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
| Methode | Pfad | Bedeutung |
|---|---|---|
GET | /api/salesItem/{id} | Eine Position |
GET | /api/domains/salesItem | Positionen über Generic Domain lesen |
GET | /api/salesItem/showForGrid | Positionen für die Tabelle |
POST | /api/salesItem/getSalItemRequirements | Bedarf |
POST | /api/salesItem/validateAvailableStock | Bestand prüfen |
GET | /api/salesItem/lastSalesPriceList | Letzter Preis |
GET | /api/salesItem/averageSalesPriceList | Durchschnittspreis |
GET | /api/salesItem/attribute | Attribut der Position |
GET | /api/salesItem/purchaseRequest | Bestellanforderung lesen |
POST | /api/salesItem/createPurchaseRequest | Bestellanforderung anlegen |
POST | /api/salesItem/updatePurchaseRequest | Bestellanforderung ändern |
POST | /api/salesItem/scriptBlock | Skript an der Position |
GET | /api/salesItem/customerBundles | Kundenbündel |
GET | /api/salesItem/salesProductionDetail/{id} | Produktionsdetail |
GET | /api/salesItem/reimbursements | Erstattungen |
GET | /api/salesItem/checkSalesItemIsDeletable/{salesItemId} | Ob die Position löschbar ist |
PATCH | /api/salesItem/massPatchSalesItem | Mehrere 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/materialCustomerSalesPrice | Mehrere Preise, salesCustomerPrices |
POST | /api/salesImport/fetchFromCSV | Positionen aus CSV, importMatchingHeadId und fileContent |
POST | /api/salesImport/items | Importzeilen |
POST | /api/salesImport/importCSV | CSV importieren |
POST | /api/salesImport/importFromCSV | Beleg aus CSV, items |
POST | /api/salesImport/updatePrices | Preise nachziehen, items |
POST | /api/salesExport/export | Belege 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/salesHeadDownload | Rechnungs-PDF als Datei, Body ids |
POST | /api/report/salesHeadPrint | Dasselbe 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/quickSave | Schnell anlegen, customerNo |
POST | /api/returnHead/createSalesHead | Verkaufsbeleg, Antwort { "salesHeadId" } |
POST | /api/returnHead/openSalesHead | Beleg öffnen |
DELETE | /api/returnHead/{id} | Retoure löschen, Antwort { "success": true } |
POST | /api/returnHead/batchRemove | Mehrere, ids |
GET | /api/returnHead/getReturnTrackingData/{id} | Sendungsverfolgung |
GET | /api/returnHead/getSalesVouchers/{id} | Verkaufsbelege |
GET | /api/returnHead/getPurVouchers/{id} | Einkaufsbelege |
POST | /api/returnHead/returnPack | Packstück, id |
DELETE | /api/returnHead/returnPack/{id} | Packstück löschen |
POST | /api/returnHead/printDocuments | Dokumente 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/fromOffer | Aus einem Angebot, salesHeadId |
POST | /api/contract/renew | Verlängern |
POST | /api/contract/approve | Freigeben, approvedSign |
GET | /api/contract/{id}/externalAudit | Externes Protokoll |
GET | /api/contract/attachments | Anhänge |
GET | /api/contract/documents | Dokumente |
GET | /api/contract/externalDesigns | Externe Layouts |
POST | /api/contract/previewExternalDesign | Layoutvorschau |
POST | /api/contract/setExternalDesign | Layout setzen |
POST | /api/contract/sendToExternal | Extern senden |
GET | /api/contract/externalContractContent | Externer Inhalt |
POST | /api/contract/externalSignCallback | Signatur-Rückmeldung |
POST | /api/contract/externalAuditEvent | Externes 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
| Situation | Ursache |
|---|---|
message.salesHead.already.closed.error | status ab 2 oder isPosted |
| Ressource nicht gefunden | GET /api/salesHead/{id} ohne Beleg |
fulfillmentCancelFail | Auftragsstorno, Fulfillment lehnt ab |
Leeres success bei splitSales | ids oder docTypeId fehlen, oder openQuantity ist 0 |
Leeres success bei createCreditNotes | salesHeadIds fehlen oder die Rechnung lässt keine Gutschrift zu |
| Zielbeleg fehlt | Keine SalesHeadDocRule von der Quellart zur Zielart |
Lieferschein nicht in docTypes | blockedDelivery am Auftrag |
| Position ohne Artikel | In items[] wurde ein Suchschlüssel statt der Artikel-id gesendet |
| Doppelter Shop-Auftrag | Dieselbe marktplaceOrderId erneut anlegen |
financeExport.ids.not.found | salesExport/export ohne ids |
salesHeads.not.found | Keine der Ids ist ein Verkaufsbeleg |
customer.not.found.error | quickSave ohne bekannten customerNo |
salesDocType.not.found.error | createSalesHead oder Rechnung aus Lieferschein ohne Belegart |
returnHead.not.found.error | returnHeadId unbekannt |
contract.fromOffer.notOffer | salesHeadId ist kein Angebot |
contract.fromOffer.customerRequired | Das Angebot hat keinen Kunden |
contract.approve.sign.empty | Freigabe ohne approvedSign |
companyBank.not.found.error | X-Rechnung oder ZUGFeRD ohne Bank mit IBAN |
salesHead.deliveryDate.not.found.error | X-Rechnung oder ZUGFeRD ohne deliveryDate |
salesHead.orderDescription.not.found.error | X-Rechnung oder ZUGFeRD ohne orderDescription |
salesHead.paymentType.not.found.error | X-Rechnung oder ZUGFeRD ohne paymentType |
salesHead.docType.xInvoiceType.not.found | Belegart ohne xInvoiceType |
salesHead.paymentType.xInvoiceType.not.found | Zahlart ohne xInvoiceType |
company.ustdid.not.found.error | Firma ohne USt-Id |
salesHead.customer.eInvoiceId.not.found | X-Rechnung, Kunde ohne eInvoiceId |
19. Ablauf Auftrag bis Rechnung
- Kunde, Belegart Auftrag, Artikel, Einheit, Lager und Steuer lesen.
POST /api/salesHead/mit Positionen. Variante übervariantCode, Set übersetItems, Charge überbatchnum.GET /api/salesHead/docTypes?salesHeadId={id}und die Lieferschein-Id merken.POST /api/salesHead/referencingDocumentsmit dieser Zielart. Bei Teillieferung nur die gewünschten Positions-Ids.- Aus dem Lieferschein
GET /api/salesHead/createInvoicesFromDelNotes. - Status über
GET /api/salesHead/status/{id}. NachisPostedden Beleg nicht mehr perPOST /api/salesHead/ändern. - Gutschrift mit
POST /api/salesHead/createCreditNotes, Retoure mitPOST /api/salesHead/return.
Fachlicher Hintergrund: Aufträge, Auftrag zu Rechnung, Angebote, Lieferscheine, Rechnungen, Retouren.