Zum Hauptinhalt springen
Markdown

Benutzung der Stammdaten-API

Workist benötigt die Stammdaten aus Ihrem ERP-System. Per API übermitteln Sie sie:

  • als CSV-Datei,
  • als Link zu einer öffentlich erreichbaren CSV-Datei,
  • als Liste von Objekten im JSON-Format, bei großen Mengen in mehreren Blöcken.

Jeder Import ersetzt den gesamten Bestand der Lookup-Definition: Zeilen, die im neuen Import fehlen, löscht Workist. Senden Sie deshalb immer den vollständigen Bestand. Delta-Importe richtet Workist auf Anfrage ein.

API Dokumentation (Swagger): https://api.workist.com/v1/swagger/

Grundlagen​

  • Basis-URL: https://api.workist.com/v1/master-data
  • Authentifizierung: derselbe API-Schlüssel wie für die Dokumenten-API, im Header Authorization: Bearer <API-Schlüssel> (siehe Quickstart).
  • Lookup-Definition: Jeder Import gehört zu genau einer Lookup-Definition, angegeben mit lookup_definition_id. Wo Sie die ID finden, steht unter Lookup Definition IDs.
  • Kein Schrägstrich am Ende der Pfade.

Endpunkte​

Für jeden Stammdatentyp gibt es einen eigenen Endpunkt, der einen Import anlegt. Die Lookup-Definition muss zum Typ des Endpunkts passen. Jeder Pfad führt zur Beschreibung des Endpunkts in Swagger.

StammdatenEndpunktLookup-TypSpalten
Artikel und kundenspezifische ArtikelPOST /master-data/articles/importsARTICLE_LOOKUPBeschreibung
KundenPOST /master-data/clients/importsCLIENT_LOOKUPBeschreibung
KundenkontaktePOST /master-data/contacts/importsCONTACT_LOOKUPBeschreibung
Liefer- und RechnungsempfängerPOST /master-data/addresses/importsADDRESS_LOOKUPBeschreibung
EinheitenkonvertierungPOST /master-data/conversion-factors/importsCONVERSION_FACTOR_LOOKUPBeschreibung
RahmenverträgePOST /master-data/framework-contracts/importsFRAMEWORK_CONTRACT_LOOKUPBeschreibung
Abzugleichende BestellungenPOST /master-data/order-matching/importsORDER_MATCHING_LOOKUPBeschreibung
AngebotePOST /master-data/offer-matching/importsOFFER_MATCHING_LOOKUPBeschreibung

Dazu kommen allgemeine Endpunkte für alle Typen:

MethodePfadZweck
GET/master-data/importsImporte auflisten (seitenweise, bis 1000 pro Seite)
POST/master-data/importsImport anlegen, für jeden Stammdatentyp
GET/master-data/imports/{import_id}Status eines Imports abrufen
POST/master-data/imports/{import_id}/dataWeiteren Datenblock an einen Batch-Import anhängen
POST/master-data/imports/{import_id}/startBatch-Import starten

Anfragefelder​

Ein Import enthält genau eines der Felder file, file_url oder data. Senden Sie die Anfrage als multipart/form-data oder als JSON. Bei multipart/form-data übergeben Sie data als JSON-Text.

FeldInhalt
lookup_definition_idID der Lookup-Definition (Pflicht).
batchedtrue: Batch-Import anlegen, der weitere Datenblöcke annimmt. Standard: false (Import startet sofort).
fileCSV-Datei (Dateiendung .csv), höchstens 10 MB.
file_urlÖffentlich erreichbarer http/https-Link auf eine CSV-Datei. Der Pfad endet auf .csv, die Datei hat höchstens 10 MB.
dataListe von Objekten (JSON), höchstens 10.000 Zeilen. Alle Objekte brauchen dieselben Felder.

Die Feldnamen der Objekte und CSV-Spalten sind die Spaltennamen der jeweiligen Stammdatenseite (Spalte „Spalten" oben). JSON-Daten wandelt Workist in eine kommagetrennte CSV-Datei um. Haben Sie für die Lookup-Definition eine Transformer-Konfiguration hinterlegt, z. B. Spaltenzuordnungen oder ein anderes Trennzeichen, gilt sie auch für Importe per API.

Antwort und Import-Status​

Workist verarbeitet Importe im Hintergrund. Jeder Aufruf, der einen Import anlegt, Daten anhängt oder startet, antwortet mit 202 und der Import-ID:

{"import_id": "0b7c6a52-5d0e-4f43-9a8e-3c2b1d0e9f11"}

Der Header Location enthält die Adresse für den Status. Fragen Sie ihn mit GET /master-data/imports/{import_id} ab, bis status den Wert SUCCESS, FAILED oder CANCELED hat:

import time

url = f"{base_url}/imports/{import_id}"
while True:
run = requests.request("GET", url, headers=headers).json()
if run["status"] in ("SUCCESS", "FAILED", "CANCELED"):
break
time.sleep(60)
# z. B. {"import_id": "...", "status": "SUCCESS", "lookup_type": "ARTICLE_LOOKUP", ...}

Die Antwort enthält:

FeldInhalt
import_idID des Imports.
customer_idID Ihrer Organisation.
lookup_typeStammdatentyp, z. B. ARTICLE_LOOKUP.
lookup_definitionID der Lookup-Definition.
ingestion_file_urlSpeicherort der zusammengeführten Importdatei.
ingestion_file_num_rowsAnzahl der importierten Zeilen.
error_typeFehlerart, falls der Import fehlgeschlagen ist.
error_messageFehlermeldung, falls der Import fehlgeschlagen ist.
triggerAuslöser, z. B. PUBLIC_API, SFTP_FILE_UPLOAD oder WORKBENCH_FILE_UPLOAD.
created_atAngelegt am.
updated_atZuletzt geändert am.
started_atVerarbeitung gestartet am.
finished_atVerarbeitung beendet am.
statusStatus, siehe unten.
input_file_urlSpeicherort der ersten übermittelten Datei bzw. des ersten Datenblocks.
input_file_num_rowsZeilen in dieser Datei.
statusBedeutung
PENDINGAngelegt, noch nicht gestartet (Batch-Import wartet auf Daten oder Start).
RUNNINGWird verarbeitet.
SUCCESSErfolgreich abgeschlossen.
FAILEDFehlgeschlagen, siehe error_type und error_message.
CANCELEDAbgebrochen.

Alle Importe, auch die per API, sehen Sie außerdem im Stammdaten-Hub der Workbench.

Grenzen​

  • Pro Anfrage: data mit höchstens 10.000 Zeilen, file und file_url mit höchstens 10 MB. Größere Bestände übertragen Sie als Batch-Import.
  • Pro Stunde: Wurden für eine Lookup-Definition in der letzten Stunde mehr als 12 Importe angelegt, lehnt die API weitere mit 400 ab (Too many imports scheduled for this lookup definition recently). Importe aus allen Quellen zählen mit, auch Uploads per SFTP. Ein SFTP-Upload über der Grenze wird ohne Meldung übersprungen.
  • file_url: nur http und https. Adressen, die auf interne oder private Netze zeigen, lehnt die API ab. Workist lädt die Datei während der Anfrage herunter.

Batch-Importe​

Für Bestände über 10.000 Zeilen oder 10 MB legen Sie einen Batch-Import an und übertragen die Daten in Blöcken:

  1. Batch-Import mit "batched": true anlegen, z. B. über POST /master-data/articles/imports. Die Antwort enthält die import_id.
  2. Datenblöcke anhängen mit POST /master-data/imports/{import_id}/data, so oft wie nötig. CSV-Blöcke brauchen alle dieselbe Kopfzeile.
  3. Import starten mit POST /master-data/imports/{import_id}/start. Danach nimmt der Import keine Daten mehr an.
import requests
import json

def chunk(it, size):
from itertools import islice
it = iter(it)
return iter(lambda: tuple(islice(it, size)), ())

base_url = "https://api.workist.com/v1/master-data"
lookup_definition_id = "<Article Lookup Definition ID>"
token = "<Your Auth Token>"
headers = {"Authorization": f"Bearer {token}"}

articles = [
{"article_id1": "123", "description": "abc", "order_units": ["PCS", "KG"]},
{"article_id1": "456", "description": "def", "order_units": ["KG"]},
{"article_id1": "789", "description": "def", "order_units": ["M"]}
]
articles_chunked = list(chunk(articles, 10000))

url = f"{base_url}/articles/imports"
response = requests.request("POST", url, headers=headers, data={
"lookup_definition_id": lookup_definition_id,
"batched": True,
})
import_id = response.json().get("import_id")

for articles_batch in articles_chunked:
url = f"{base_url}/imports/{import_id}/data"
response = requests.request("POST", url, headers=headers, data={"data": json.dumps(articles_batch)})

url = f"{base_url}/imports/{import_id}/start"
response = requests.request("POST", url, headers=headers)

Kunden​

clients = [
{"client_id1": "C-001", "company_name": "Test SE", "address1": "Test street 1", ...},
{"client_id1": "C-002", "company_name": "Muster GmbH&Co. KG", ...}
]
url = f"{base_url}/clients/imports"
payload = {"lookup_definition_id": "<your lookup definition>", "data": json.dumps(clients)}
response = requests.request("POST", url, headers=headers, data=payload)

Lieferadressen​

Verknüpfung mit Kunden über partition_id. Das Feld für die Lieferadresse sollte ausschließlich Firmennamen enthalten.

delivery_addresses = [
{"partition_id": "C-001", "address_id1": "L-001", "name": "Tester 2 GmbH", "address1": "Test street 2", ...}
]
url = f"{base_url}/addresses/imports"
payload = {"lookup_definition_id": "<your lookup definition>", "data": json.dumps(delivery_addresses)}
response = requests.request("POST", url, headers=headers, data=payload)

Artikel​

order_units muss als Array übermittelt werden (z. B. ["KG", "STK"]).

articles = [
{"article_id1": "ART-001", "description": "Sensor Module", "order_units": ["PCE", "KG"]},
]
url = f"{base_url}/articles/imports"
payload = {"lookup_definition_id": "<your lookup definition>", "data": json.dumps(articles)}
response = requests.request("POST", url, headers=headers, data=payload)

Kundenspezifische Artikel​

Jeder Eintrag braucht partition_id (Kundenverweis) und article_id1 (interner Artikel). article_id2 enthält die Kundenartikelnummer.

client_articles = [
{"partition_id": "C-001", "article_id1": "ART-001", "article_id2": "CUST-ART-555"},
]
url = f"{base_url}/articles/imports"
payload = {"lookup_definition_id": "<your client-specific lookup definition>", "data": json.dumps(client_articles)}
response = requests.request("POST", url, headers=headers, data=payload)

Fehler​

HTTP-StatusUrsacheAntwort
400Ungültige Anfrage, z. B. fehlende lookup_definition_id, Datei keine CSV-Datei, zu viele Zeilen, Lookup-Definition passt nicht zum Endpunkt, Import nicht mehr im Status PENDING, zu viele Importe pro Stunde{"detail": "<Meldung>"} oder ["<Meldung>"]
401API-Schlüssel fehlt{"detail": "Authentication credentials were not provided or invalid."}
503Die Anfrage hat länger als 30 Sekunden gedauert{"detail": "Please try again later"}

Postman Collection​

Eine Postman Collection für die Stammdaten-API ist auf Anfrage verfügbar. Wenden Sie sich an Ihren Workist-Ansprechpartner oder an support@workist.com.

Lookup Definition IDs​

Lookup-Definitionen legen Benutzer mit der Rolle Manager, IT oder Admin im Stammdaten-Hub an. Die ID finden Sie an zwei Stellen:

  • im Stammdaten-Hub: in der Übersicht in der Spalte ID und auf der Detailseite der Lookup-Definition,
  • im Kanal unter Kanal verwalten → Stammdaten, unter der jeweils ausgewählten Lookup-Definition.

Weitere Details: Lookup-IDs abrufen