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.
| Stammdaten | Endpunkt | Lookup-Typ | Spalten |
|---|---|---|---|
| Artikel und kundenspezifische Artikel | POST /master-data/articles/imports | ARTICLE_LOOKUP | Beschreibung |
| Kunden | POST /master-data/clients/imports | CLIENT_LOOKUP | Beschreibung |
| Kundenkontakte | POST /master-data/contacts/imports | CONTACT_LOOKUP | Beschreibung |
| Liefer- und Rechnungsempfänger | POST /master-data/addresses/imports | ADDRESS_LOOKUP | Beschreibung |
| Einheitenkonvertierung | POST /master-data/conversion-factors/imports | CONVERSION_FACTOR_LOOKUP | Beschreibung |
| Rahmenverträge | POST /master-data/framework-contracts/imports | FRAMEWORK_CONTRACT_LOOKUP | Beschreibung |
| Abzugleichende Bestellungen | POST /master-data/order-matching/imports | ORDER_MATCHING_LOOKUP | Beschreibung |
| Angebote | POST /master-data/offer-matching/imports | OFFER_MATCHING_LOOKUP | Beschreibung |
Dazu kommen allgemeine Endpunkte für alle Typen:
| Methode | Pfad | Zweck |
|---|---|---|
GET | /master-data/imports | Importe auflisten (seitenweise, bis 1000 pro Seite) |
POST | /master-data/imports | Import anlegen, für jeden Stammdatentyp |
GET | /master-data/imports/{import_id} | Status eines Imports abrufen |
POST | /master-data/imports/{import_id}/data | Weiteren Datenblock an einen Batch-Import anhängen |
POST | /master-data/imports/{import_id}/start | Batch-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.
| Feld | Inhalt |
|---|---|
lookup_definition_id | ID der Lookup-Definition (Pflicht). |
batched | true: Batch-Import anlegen, der weitere Datenblöcke annimmt. Standard: false (Import startet sofort). |
file | CSV-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. |
data | Liste 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:
| Feld | Inhalt |
|---|---|
import_id | ID des Imports. |
customer_id | ID Ihrer Organisation. |
lookup_type | Stammdatentyp, z. B. ARTICLE_LOOKUP. |
lookup_definition | ID der Lookup-Definition. |
ingestion_file_url | Speicherort der zusammengeführten Importdatei. |
ingestion_file_num_rows | Anzahl der importierten Zeilen. |
error_type | Fehlerart, falls der Import fehlgeschlagen ist. |
error_message | Fehlermeldung, falls der Import fehlgeschlagen ist. |
trigger | Auslöser, z. B. PUBLIC_API, SFTP_FILE_UPLOAD oder WORKBENCH_FILE_UPLOAD. |
created_at | Angelegt am. |
updated_at | Zuletzt geändert am. |
started_at | Verarbeitung gestartet am. |
finished_at | Verarbeitung beendet am. |
status | Status, siehe unten. |
input_file_url | Speicherort der ersten übermittelten Datei bzw. des ersten Datenblocks. |
input_file_num_rows | Zeilen in dieser Datei. |
status | Bedeutung |
|---|---|
PENDING | Angelegt, noch nicht gestartet (Batch-Import wartet auf Daten oder Start). |
RUNNING | Wird verarbeitet. |
SUCCESS | Erfolgreich abgeschlossen. |
FAILED | Fehlgeschlagen, siehe error_type und error_message. |
CANCELED | Abgebrochen. |
Alle Importe, auch die per API, sehen Sie außerdem im Stammdaten-Hub der Workbench.
Grenzen
- Pro Anfrage:
datamit höchstens 10.000 Zeilen,fileundfile_urlmit 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
400ab (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: nurhttpundhttps. 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:
- Batch-Import mit
"batched": trueanlegen, z. B. überPOST /master-data/articles/imports. Die Antwort enthält dieimport_id. - Datenblöcke anhängen mit
POST /master-data/imports/{import_id}/data, so oft wie nötig. CSV-Blöcke brauchen alle dieselbe Kopfzeile. - 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-Status | Ursache | Antwort |
|---|---|---|
400 | Ungü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>"] |
401 | API-Schlüssel fehlt | {"detail": "Authentication credentials were not provided or invalid."} |
503 | Die 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