Diese Seite ist die vollständige Übersicht aller REST-API-Endpunkte von ComBinder.
Sie ist für zwei Zielgruppen geschrieben:

  1. Normale Benutzer, die z. B. in n8n eine HTTP-Request-Node konfigurieren möchten.
  2. Maschinen-Benutzer (KI-Bots, Code-Generatoren), die aus dieser Seite heraus direkt eine funktionierende n8n- oder Python-Lösung bauen sollen — dafür gibt es weiter unten einen maschinenlesbaren JSON-Block mit allen Endpunkten.

Die REST-API ergänzt die ComBinder MCP-Funktionen. Beide Wege sprechen dieselbe Datenbasis an: REST ist der Weg für eigene Integrationen (n8n, Skripte, externe Systeme), MCP ist der Weg für KI-Agenten innerhalb von Claude/Tools.

1. Eckdaten (Quick Facts)

Basis-URL http://<host>:<port>/api (Standard-Port: 8765, einstellbar in den ComBinder-Einstellungen unter „REST API“)
Auth-Verfahren Bearer Token (UUID), gültig 24 Stunden
Content-Type application/json; charset=UTF-8 für alle Request- und Response-Bodies
Antwort-Hülle Jede Antwort ist ein ApiResponse-Objekt: { "success": bool, "data": ..., "error": "..." }
CORS Access-Control-Allow-Origin: *, erlaubt GET, POST, PUT, DELETE, OPTIONS
Monitor/Debugging Alle Requests werden im ComBinder „REST API Monitor“ (Fenster-Menü) protokolliert
Sprachcodes ISO 639-2/B, z. B. deu, eng, fra (BMEcat-Standard)

Antwort-Format

Erfolg:

{ "success": true, "data": { /* ... */ } }

Fehler:

{ "success": false, "error": "Beschreibung des Fehlers" }

Authentifizierung

Jeder Endpunkt außer /api/auth/login benötigt den Header:

Authorization: Bearer <token>

Das Token wird über POST /api/auth/login erzeugt und ist 24 Stunden gültig.

2. Endpunkt-Übersicht

Methode Pfad Zweck Auth
POST /api/auth/login Login, liefert Bearer-Token
POST /api/auth/logout Token invalidieren, ggf. Desktop-Session schließen
GET /api/workspace Alle Workspaces auflisten
POST /api/workspace/open Workspace öffnen
GET /api/product Produkte auflisten (?all=true inkl. Varianten)
POST /api/product Produkt anlegen
GET /api/product/{id} Produkt abrufen
PUT /api/product/{id} Produkt aktualisieren (Teil-Update)
DELETE /api/product/{id} Produkt löschen
GET /api/product/{id}/variants Varianten eines Produkts auflisten
POST /api/product/{id}/variants Variante anlegen
GET /api/product/{id}/texts/short Alle Kurztexte (alle Sprachen)
GET /api/product/{id}/texts/short/{lang} Kurztext einer Sprache
PUT /api/product/{id}/texts/short/{lang} Kurztext setzen/anlegen
DELETE /api/product/{id}/texts/short/{lang} Kurztext löschen
GET /api/product/{id}/texts/long Alle Langtexte (alle Sprachen)
GET /api/product/{id}/texts/long/{lang} Langtext einer Sprache
PUT /api/product/{id}/texts/long/{lang} Langtext setzen/anlegen
DELETE /api/product/{id}/texts/long/{lang} Langtext löschen
GET /api/product/{id}/features Alle Merkmale (alle Sprachen)
GET /api/product/{id}/features/{ftidref} Ein Merkmal (alle Sprachen)
GET /api/product/{id}/features/{ftidref}/{lang} Merkmalswert einer Sprache
PUT /api/product/{id}/features/{ftidref} Merkmal anlegen/Werte bulk setzen
PUT /api/product/{id}/features/{ftidref}/{lang} Merkmalswert einer Sprache setzen
DELETE /api/product/{id}/features/{ftidref} Merkmal komplett entfernen
DELETE /api/product/{id}/features/{ftidref}/{lang} Merkmalswert einer Sprache entfernen
GET /api/group Alle Produktgruppen (flach)
POST /api/group Produktgruppe anlegen
GET /api/group/tree Komplette Baumstruktur
GET /api/group/{id} Produktgruppe abrufen
PUT /api/group/{id} Produktgruppe umbenennen
DELETE /api/group/{id} Produktgruppe löschen (?deleteProducts=true|false)
POST /api/group/{id}/move Gruppe im Baum verschieben
GET /api/group/{id}/products Produkte in der Gruppe auflisten
POST /api/group/{id}/products Produkt(e) der Gruppe zuordnen
DELETE /api/group/{id}/products/{productId} Produkt aus Gruppe entfernen

3. Authentifizierung im Detail

POST /api/auth/login

Request:

{ "username": "admin", "password": "geheim" }

Response (200):

{
  "success": true,
  "data": { "token": "550e8400-e29b-...", "username": "admin", "role": "ADMIN" }
}

Fehler (401): falsches Passwort, Benutzer bereits anderswo eingeloggt, etc.

POST /api/auth/logout

Header Authorization: Bearer <token> mitsenden. Invalidiert das Token; falls es der aktuell aktive Desktop-Benutzer ist, wird auch die App-Session geschlossen.

4. Workspace

Endpoint Beschreibung
GET /api/workspace Liste aller bekannten Workspaces inkl. active-Flag
POST /api/workspace/open Öffnet einen Workspace per {"workspaceId": 1} oder {"workspaceName": "Demo"}

WorkspaceDto: { id, name, rootpath, active }

Wichtig: Alle Produkt- und Gruppen-Endpunkte erfordern einen geöffneten Workspace (409 Conflict, falls keiner offen ist).

5. Produkte

ProductDto: { id, supplierPid, supplierIdRef, name, ean, manufacturerPid, masterProduct, variantCount, masterProductId }

Endpoint Body Beschreibung
GET /api/product?all=true Standard: nur Hauptprodukte. all=true inkl. Varianten
POST /api/product CreateProductRequest supplierPid ist Pflicht
GET /api/product/{id}
PUT /api/product/{id} UpdateProductRequest Alle Felder optional – nur gesetzte Felder werden geändert
DELETE /api/product/{id}
GET /api/product/{id}/variants
POST /api/product/{id}/variants CreateProductRequest Variante wird automatisch mit Hauptprodukt verknüpft

CreateProductRequest / UpdateProductRequest: { supplierPid, supplierIdRef, name, language, ean, manufacturerPid, masterProductId* }
(* nur bei Create; language steuert, in welcher Sprache name als Kurztext gespeichert wird – Default: Workspace-Standardsprache)

6. Produkttexte (sprachabhängig)

Für KI-gestützte Übersetzung/Optimierung gedacht: jede Sprache ist einzeln adressierbar.

Endpoint Beschreibung
GET /api/product/{id}/texts/short Alle Kurztexte (DESCRIPTIONSHORT)
GET /api/product/{id}/texts/short/{lang} Kurztext einer Sprache
PUT /api/product/{id}/texts/short/{lang} Body {"value": "..."} – Upsert
DELETE /api/product/{id}/texts/short/{lang}
GET /api/product/{id}/texts/long Alle Langtexte (DESCRIPTIONLONG)
GET /api/product/{id}/texts/long/{lang} Langtext einer Sprache
PUT /api/product/{id}/texts/long/{lang} Body {"value": "..."} – Upsert
DELETE /api/product/{id}/texts/long/{lang}

TextEntryDto: { lang, value }  ·  SetTextRequest: { value }

7. Produktmerkmale / Features (sprachabhängig)

Merkmale (FEATURE/FVALUE) werden über ihre stabile FT_IDREF adressiert, nicht über einen Index.

Endpoint Beschreibung
GET /api/product/{id}/features Alle Merkmale, alle Sprachen
GET /api/product/{id}/features/{ftidref} Ein Merkmal, alle Sprachen
GET /api/product/{id}/features/{ftidref}/{lang} Ein Wert
PUT /api/product/{id}/features/{ftidref} Bulk-Set mehrerer Sprachen, legt Merkmal an falls nicht vorhanden
PUT /api/product/{id}/features/{ftidref}/{lang} Body {"value": "..."} – einzelne Sprache
DELETE /api/product/{id}/features/{ftidref} Merkmal komplett entfernen
DELETE /api/product/{id}/features/{ftidref}/{lang} Nur einen Sprachwert entfernen

FeatureDto: { ftidref, funit, names: [TextEntryDto], values: [TextEntryDto] }
SetFeatureValuesRequest: { ftidref, funit, values: [{lang, value}, ...] }

8. Produktgruppen & Baumstruktur

ProductGroupDto: { id, groupId, name, parentGroupId, childGroupCount, productCount }
ProductGroupNodeDto (rekursiv, für /tree): { id, groupId, name, productCount, children: [...] }

id ist der DB-Primärschlüssel und wird in URLs verwendet (analog zu Produkten). groupId ist die hierarchische BMEcat-ID (z. B. "1.2.3") und nur informativ im Response.

Endpoint Body Beschreibung
GET /api/group Flache Liste aller Gruppen
POST /api/group { name, language?, parentId? } parentId weglassen = Gruppe auf Root-Ebene
GET /api/group/tree Vollständiger Baum ab Root
GET /api/group/{id} Einzelne Gruppe
PUT /api/group/{id} { name, language? } Umbenennen
DELETE /api/group/{id}?deleteProducts=false deleteProducts=true löscht auch enthaltene Produkte, sonst werden sie nur „entgruppiert“
POST /api/group/{id}/move { parentId } (null = Root) Verschiebt die Gruppe im Baum
GET /api/group/{id}/products Direkt zugeordnete Produkte (keine Rekursion)
POST /api/group/{id}/products { productIds: [1,2,3] } Produkte der Gruppe zuordnen
DELETE /api/group/{id}/products/{productId} Produkt aus der Gruppe entfernen (wird „wurzel-los“)

9. Für n8n-Nutzer

  1. HTTP Request Node → Method/URL entsprechend Tabelle oben setzen.
  2. Authentication: „Generic Credential Type“ → „Header Auth“ mit Authorization: Bearer {{$json.token}}, oder das Token aus dem Login-Schritt per Set-Node zwischenspeichern.
  3. Empfohlener Workflow-Aufbau:
    [Login Node: POST /api/auth/login]
         └─> [Set Node: token = {{$json.data.token}}]
               └─> [HTTP Request Node: eigentlicher Aufruf, Header Authorization=Bearer {{token}}]
  4. Antworten immer über $json.data auslesen (Erfolg) bzw. $json.error (Fehlerfall) prüfen, da jede Antwort in der ApiResponse-Hülle steckt.
  5. Für Massenoperationen (z. B. alle Produkte einer Gruppe übersetzen): zuerst GET /api/group/{id}/products, dann pro Produkt GET .../texts/short, KI-Übersetzung, anschließend PUT .../texts/short/{lang}.

10. Für KI-Bots / Maschinen-Benutzer (maschinenlesbare Spezifikation)

Der folgende JSON-Block beschreibt alle Endpunkte strukturiert (Methode, Pfad, Auth, Body-Schema, Beschreibung). Er ist bewusst kompakt gehalten, damit ein LLM oder Codegenerator daraus direkt n8n-Workflows oder Python-Clients ableiten kann.

{
  "baseUrl": "http://<host>:<port>/api",
  "defaultPort": 8765,
  "auth": { "type": "bearer", "obtainVia": "POST /auth/login", "ttlHours": 24 },
  "responseEnvelope": { "success": "boolean", "data": "any", "error": "string|null" },
  "endpoints": [
    { "method": "POST",   "path": "/auth/login",  "auth": false, "body": {"username":"string","password":"string"}, "returns": "{token,username,role}" },
    { "method": "POST",   "path": "/auth/logout", "auth": true,  "body": null },
    { "method": "GET",    "path": "/workspace", "auth": true },
    { "method": "POST",   "path": "/workspace/open", "auth": true, "body": {"workspaceId":"int?","workspaceName":"string?"} },
    { "method": "GET",    "path": "/product", "auth": true, "query": {"all":"bool?"} },
    { "method": "POST",   "path": "/product", "auth": true, "body": {"supplierPid":"string","supplierIdRef":"string?","name":"string?","language":"string?","ean":"string?","manufacturerPid":"string?","masterProductId":"int?"} },
    { "method": "GET",    "path": "/product/{id}", "auth": true },
    { "method": "PUT",    "path": "/product/{id}", "auth": true, "body": {"supplierPid":"string?","supplierIdRef":"string?","name":"string?","language":"string?","ean":"string?","manufacturerPid":"string?"} },
    { "method": "DELETE", "path": "/product/{id}", "auth": true },
    { "method": "GET",    "path": "/product/{id}/variants", "auth": true },
    { "method": "POST",   "path": "/product/{id}/variants", "auth": true, "body": {"supplierPid":"string","supplierIdRef":"string?","name":"string?","language":"string?","ean":"string?","manufacturerPid":"string?"} },
    { "method": "GET",    "path": "/product/{id}/texts/short", "auth": true },
    { "method": "GET",    "path": "/product/{id}/texts/short/{lang}", "auth": true },
    { "method": "PUT",    "path": "/product/{id}/texts/short/{lang}", "auth": true, "body": {"value":"string"} },
    { "method": "DELETE", "path": "/product/{id}/texts/short/{lang}", "auth": true },
    { "method": "GET",    "path": "/product/{id}/texts/long", "auth": true },
    { "method": "GET",    "path": "/product/{id}/texts/long/{lang}", "auth": true },
    { "method": "PUT",    "path": "/product/{id}/texts/long/{lang}", "auth": true, "body": {"value":"string"} },
    { "method": "DELETE", "path": "/product/{id}/texts/long/{lang}", "auth": true },
    { "method": "GET",    "path": "/product/{id}/features", "auth": true },
    { "method": "GET",    "path": "/product/{id}/features/{ftidref}", "auth": true },
    { "method": "GET",    "path": "/product/{id}/features/{ftidref}/{lang}", "auth": true },
    { "method": "PUT",    "path": "/product/{id}/features/{ftidref}", "auth": true, "body": {"ftidref":"string?","funit":"string?","values":[{"lang":"string","value":"string"}]} },
    { "method": "PUT",    "path": "/product/{id}/features/{ftidref}/{lang}", "auth": true, "body": {"value":"string"} },
    { "method": "DELETE", "path": "/product/{id}/features/{ftidref}", "auth": true },
    { "method": "DELETE", "path": "/product/{id}/features/{ftidref}/{lang}", "auth": true },
    { "method": "GET",    "path": "/group", "auth": true },
    { "method": "POST",   "path": "/group", "auth": true, "body": {"name":"string","language":"string?","parentId":"int?"} },
    { "method": "GET",    "path": "/group/tree", "auth": true },
    { "method": "GET",    "path": "/group/{id}", "auth": true },
    { "method": "PUT",    "path": "/group/{id}", "auth": true, "body": {"name":"string?","language":"string?"} },
    { "method": "DELETE", "path": "/group/{id}", "auth": true, "query": {"deleteProducts":"bool?"} },
    { "method": "POST",   "path": "/group/{id}/move", "auth": true, "body": {"parentId":"int|null"} },
    { "method": "GET",    "path": "/group/{id}/products", "auth": true },
    { "method": "POST",   "path": "/group/{id}/products", "auth": true, "body": {"productIds":["int"]} },
    { "method": "DELETE", "path": "/group/{id}/products/{productId}", "auth": true }
  ]
}

Python-Quickstart (für Bots/Skripte)

import requests

class ComBinderClient:
    def __init__(self, base_url="http://localhost:8765/api"):
        self.base_url = base_url
        self.token = None

    def login(self, username, password):
        r = requests.post(f"{self.base_url}/auth/login",
                           json={"username": username, "password": password})
        data = r.json()
        if not data["success"]:
            raise RuntimeError(data["error"])
        self.token = data["data"]["token"]
        return data["data"]

    def _headers(self):
        return {"Authorization": f"Bearer {self.token}"}

    def _call(self, method, path, **kwargs):
        r = requests.request(method, f"{self.base_url}{path}",
                              headers=self._headers(), **kwargs)
        data = r.json()
        if not data["success"]:
            raise RuntimeError(f"{r.status_code}: {data.get('error')}")
        return data.get("data")

    # Produkte
    def list_products(self, all_variants=False):
        return self._call("GET", "/product", params={"all": str(all_variants).lower()})

    def create_product(self, supplier_pid, **fields):
        return self._call("POST", "/product", json={"supplierPid": supplier_pid, **fields})

    def set_short_text(self, product_id, lang, value):
        return self._call("PUT", f"/product/{product_id}/texts/short/{lang}", json={"value": value})

    # Gruppen
    def get_group_tree(self):
        return self._call("GET", "/group/tree")

    def assign_products_to_group(self, group_id, product_ids):
        return self._call("POST", f"/group/{group_id}/products", json={"productIds": product_ids})


client = ComBinderClient()
client.login("admin", "geheim")
products = client.list_products(all_variants=True)

curl-Beispiele

# Login
curl -s -X POST http://localhost:8765/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"geheim"}'

# Produkt anlegen (Token aus Login einsetzen)
curl -s -X POST http://localhost:8765/api/product \
  -H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
  -d '{"supplierPid":"ART-1001","name":"Bürostuhl Comfort","language":"deu"}'

# Kurztext auf Englisch setzen (z. B. nach KI-Übersetzung)
curl -s -X PUT http://localhost:8765/api/product/42/texts/short/eng \
  -H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
  -d '{"value":"Comfort Office Chair"}'

# Komplette Gruppen-Baumstruktur abrufen
curl -s http://localhost:8765/api/group/tree -H "Authorization: Bearer <token>"

Verhältnis zur MCP-Schnittstelle

Die REST-API ist die generische, transportunabhängige Schnittstelle für eigene Integrationen (n8n, Skripte, Drittsysteme). Die ComBinder-MCP-Tools (mcp__combinder__*) bilden einen Teil dieser Funktionalität zusätzlich als direkt aufrufbare KI-Werkzeuge ab (z. B. create_product, get_group_tree, set_product_text) – praktisch für KI-Agenten, die ohne eigenen HTTP-Client arbeiten. Beide Wege wirken auf denselben Workspace; Änderungen über REST sind sofort auch über MCP sichtbar und umgekehrt.

Wer eine Lösung außerhalb eines MCP-fähigen Agenten baut (n8n, Python-Skript, externe Webanwendung), verwendet die REST-API direkt wie auf dieser Seite beschrieben.

Weiterlesen