Veröffentlicht von Markus Wals

Mehr API, als die Doku zeigt: inoffizielle weclapp-Endpunkte sicher nutzen

API Filter Integration OpenAPI Praxiswissen weclapp

Grafik: weclapp API, Das Handbuch, Teil 10. Mehr API, als die Doku zeigt: öffentliche Spec und zusätzliche Mandanten-Spec mit includeHidden.

Kurz gesagt: Die weclapp API kann mehr, als die öffentliche Pfadliste zeigt, und der nützlichste Fund ist POST /{entity}/query: Damit legst du lange Filter in den Body statt in die URL. Nutze solche Endpunkte nur mit offiziellem Fallback und prüfe regelmäßig, ob sie auf deinem Mandanten noch vorhanden sind.

Du willst 400 Kundendatensätze anhand einer Liste von Kundennummern abgleichen. Mit GET packst du alle 400 Nummern in einen Filter, und plötzlich ist die URL länger als das, was Proxy und Server annehmen. Die übliche Lösung ist, die Liste in kleine Pakete zu zerlegen und viele Requests zu schicken. Es geht auch eleganter: mit einem Endpunkt, den die weclapp-Doku im Text empfiehlt, der in der öffentlichen Pfadliste aber fehlt.

Er ist nicht der einzige. Die öffentliche Spec ist die Grundlage jeder Integration, aber sie ist nicht die ganze API. In diesem Artikel zeigen wir dir, wie du lange Filter mit POST /query in den Body legst, welche Regeln für Endpunkte außerhalb der öffentlichen Pfadliste gelten und wie du deine Integration so baust, dass sie nicht an einem einzelnen Endpunkt hängt.

Alle Beispiele nutzen die Basis-URL https://<dein-mandant>.weclapp.com/webapp/api/v2/ und den Header AuthenticationToken: <dein-token>. Probiere sie zuerst auf einem Testsystem aus, nie direkt auf deinem Produktivmandanten.

Das Wichtigste in Kürze

  • Die Spec deines Mandanten kennt rund 300 Pfade mehr. Mit includeHidden=true waren es an unseren Testmandanten 1.013 und 1.020 statt 712 öffentlich gelisteter Pfade.
  • Lange Filter gehören in den Body. POST /{entity}/query ersetzt viele GET-Requests mit langen URLs durch einen einzigen.
  • Die meisten inoffiziellen Endpunkte haben keinen Vertrag. Du nutzt sie nur mit eingebautem Plan B.
  • Prüfe deine Endpunkte regelmäßig. Ein kurzes Skript zeigt dir, ob sie auf deinem Mandanten vorhanden sind.

Mehr API, als die Pfadliste zeigt

Die öffentliche v2-Spec auf weclapp.com listet 712 Pfade. Rufst du die Spec stattdessen an einem Mandanten ab, mit dem Parameter includeHidden=true, sind es deutlich mehr: An unseren beiden Testmandanten waren es 1.013 und 1.020 Pfade. Rund 300 Pfade, die in keiner öffentlichen Liste stehen.

Was heißt das für dich? Diese Endpunkte funktionieren, aber die meisten haben keinen Vertrag. Schon für die offizielle API behält sich weclapp in der Change Policy vor, Ressourcen ohne Vorankündigung zu ändern. Für Endpunkte, die nicht einmal im Katalog stehen, solltest du damit erst recht rechnen. Eine Ausnahme ist POST /query, dazu gleich mehr. Dazu kommt: Ein Mandant zeigt nur die Endpunkte seiner Lizenz. Was bei dir fehlt, kann es bei einem Kunden mit anderem Modulumfang geben, und umgekehrt.

Grafik: Mehr API, als die Pfadliste zeigt. Die öffentliche weclapp-Spec v2 hat 712 Pfade, zwei Testmandanten mit includeHidden=true haben 1.013 und 1.020 Pfade, also 301 und 308 mehr.

Fazit: Inoffizielle Endpunkte sind kein Tabu, aber jede Nutzung ist eine bewusste Entscheidung mit eingebautem Plan B.

So prüfst du deine Endpunkte

Die Spec deines Mandanten lädst du direkt an deinem Mandanten-Endpunkt herunter. Den Pfad meta/openapi.yaml nennt die weclapp-Doku selbst, der Parameter includeHidden=true liefert die vollständige Fassung. Mit einem Download und ein paar Zeilen Python prüfst du, ob die Endpunkte, auf die sich deine Integration verlässt, auf deinem Mandanten vorhanden sind:

curl -s --compressed -H "AuthenticationToken: <dein-token>" \
  "https://<dein-mandant>.weclapp.com/webapp/api/v2/meta/openapi.yaml?includeHidden=true" -o tenant.yaml

pip install pyyaml
python3 - <<'EOF'
import yaml
USED = {("POST", "/party/query")}  # trag hier die Endpunkte ein, auf die sich deine Integration verlässt
spec = yaml.safe_load(open("tenant.yaml"))
have = {(m.upper(), p) for p, item in spec["paths"].items()
        for m, o in item.items() if isinstance(o, dict) and "responses" in o}
missing = sorted(USED - have)
for method, path in missing:
    print("fehlt:", method, path)
raise SystemExit(1 if missing else 0)
EOF

Lass das Skript regelmäßig laufen, zum Beispiel einmal pro Woche. Fehlt ein Endpunkt, den du nutzt, siehst du es sofort und nicht erst, wenn ein Kunde anruft.

Fazit: Du hast in fünf Minuten ein Frühwarnsystem für genau die Endpunkte, auf die du dich verlässt.

Der nützlichste Fund: Filter im Body mit POST /query

Den größten Block in dieser Liste bilden zwei Operationen, die es für jede Entity gibt: POST /{entity}/query und POST /{entity}/count, in unserer Spec je 183 Mal. Das Spannende daran: Sie sind kein Geheimnis. Die weclapp-Doku beschreibt im Abschnitt „Querying“ ausdrücklich POST /party/query und empfiehlt für POST-Abfragen Filter Expressions im Request-Body, weil POST weniger Einschränkungen hat als GET. Nur in der Pfadliste der öffentlichen Spec tauchen sie nicht auf. Laut Florian Wisheckel (Software Engineer bei weclapp) wird POST /{entity}/query in einem der nächsten Changelogs offiziell.

Damit löst sich das Problem vom Anfang. Die lange Liste wandert aus der URL in den Body:

POST https://<dein-mandant>.weclapp.com/webapp/api/v2/party/query
AuthenticationToken: <dein-token>
Content-Type: application/json

{
  "filter": "customerNumber in [\"10004\", \"10005\", \"10006\"]",
  "pageSize": 1000
}

Die Antwort hat dieselbe Form wie bei GET /party, ein Objekt mit result. Brauchst du nur die Anzahl, nimmst du POST /party/count mit demselben Filter.

Zwei Unterschiede zu GET solltest du kennen. Erstens kennt der Body keine Einzelfilter wie customerNumber-in, sondern nur das Feld filter mit einer Filter Expression. Die Doku kennzeichnet Filter Expressions noch als Beta. Zweitens heißen einige Felder anders: Laut Schema gibt es neben filter, page, pageSize und offset auch properties, includeReferencedEntities, additionalProperties und orderBy, jeweils als Liste von Strings. Wie bei GET gilt: Mehr als 1.000 Einträge pro Seite liefert weclapp in der Regel nicht.

Grafik: Lange Filter gehören in den Body. GET /party mit customerNumber-in in der URL führt zu langen URLs und vielen Requests, POST /party/query mit Filter Expression im Body braucht einen Request und liefert dieselbe Antwort.

Fazit: Abgleiche gegen lange ID- oder Nummernlisten brauchen einen Request statt vieler, und deine URLs bleiben kurz und lesbar.

So setzt du inoffizielle Endpunkte sicher ein

Ein Endpunkt außerhalb der öffentlichen Pfadliste ist dann unproblematisch, wenn dein Code auch ohne ihn weiterläuft. Bei POST /query ist der Fallback ein Praxistipp: Er trägt dich, bis der Endpunkt offiziell gelistet ist, und schützt dich bei Mandanten, auf denen er nicht antwortet. Der offizielle Weg existiert: GET mit id-in, in Paketen, damit die URL kurz bleibt. Der Code versucht zuerst den POST, und erst wenn weclapp mit 404 oder 405 antwortet, schaltet er um und meldet das:

// POST /party/query steht in der weclapp-Doku, fehlt aber noch in der öffentlichen Pfadliste.
// Fallback: GET /party mit id-in in Paketen zu 100 IDs.
async function queryParties(ids) {
  const filter = `id in [${ids.map((id) => `"${id}"`).join(",")}]`;
  try {
    return await post("/party/query", { filter, pageSize: 1000 });
  } catch (err) {
    if (![404, 405].includes(err.status)) throw err;
    console.warn("POST /party/query nicht verfügbar, Fallback auf GET");
    const result = [];
    for (let i = 0; i < ids.length; i += 100) {
      const chunk = ids.slice(i, i + 100);
      const page = await get(`/party?id-in=${encodeURIComponent(JSON.stringify(chunk))}&pageSize=100`);
      result.push(...page.result);
    }
    return { result };
  }
}

Die Funktion ist für bis zu 1.000 IDs ausgelegt. Hast du mehr, teilst du die Liste vorher auf.

Aus unserem Integrationsalltag haben sich dazu ein paar Regeln bewährt:

  • Kommentieren: Jeder inoffizielle Endpunkt im Code bekommt einen Kommentar wie oben, damit auch Kolleg:innen in einem Jahr wissen, worauf sie sich verlassen.
  • Regelmäßig prüfen: Die wöchentliche Prüfung zeigt dir, ob die Endpunkte noch da sind.
  • Lesen ja, Schreiben nur kontrolliert: Lesende Endpunkte wie /count sind ein überschaubares Risiko. Schreibende inoffizielle Endpunkte gehören nur mit Vorschau, Freigabe und anschließender Kontrolle in eine Integration und nie in einen Auftragsfluss, der ohne sie stillsteht.
  • Beim Rollout prüfen: Weil jeder Mandant nur die Endpunkte seiner Lizenz zeigt, prüfst du bei einem neuen Kunden, ob der Endpunkt dort überhaupt existiert.

Grafik: Inoffiziell nutzen, offiziell absichern. Drei Schritte: zuerst POST /query mit allen IDs, bei 404 oder 405 schaltet der Code um und meldet es, dann der offizielle Weg GET mit id-in in Paketen zu 100 IDs.

Fazit: Du bekommst den Komfort der zusätzlichen Endpunkte, ohne dass deine Integration an ihnen hängt.

Checkliste

  • Spec deines Mandanten mit includeHidden=true abgerufen und gegen die Liste der genutzten Endpunkte geprüft
  • Genutzte inoffizielle Endpunkte im Code kommentiert
  • Offizieller Fallback je inoffiziellem Endpunkt vorhanden
  • Prüfung läuft regelmäßig
  • Schreibende inoffizielle Aufrufe nur mit Vorschau, Freigabe und Kontrolle
  • Beim Rollout zu einem neuen Kunden Verfügbarkeit geprüft

Weiterlesen und Werkzeuge

Die offiziellen Endpunkte probierst du am schnellsten mit unserer kostenlosen Postman Collection 4 weclapp aus. Die Requests aus diesem Artikel (POST /party/query, POST /party/count) legst du dort als eigene Requests an, Mandant und Token setzt du einmal als Variablen. Wie du große Datenmengen gezielt und paketweise liest, zeigt Teil 2 der Serie (Gezielt lesen). Die Grundlagen zu Filtern und Projektion erklärt das YouTube-Webinar „weclapp API Deep Dive“.

Du willst wissen, wie robust deine Integrationen gegenüber Änderungen an der weclapp-API sind? Lass uns draufschauen: wals.pro/termin.

Quellen und Grenzen

  • Webinar „weclapp API Deep Dive“ (Stand der Veröffentlichung, 19.10.2026): Grundlagen zu Filtern und Projektion.
  • Die weclapp-Doku (Change Policy, Abschnitt „Querying“) und die Aussage von Florian Wisheckel (weclapp) zum offiziellen Changelog stehen im Artikel ohne Link (Stand der Veröffentlichung, 19.10.2026).

Die Pfadzahlen stammen aus unserer Spec-Abfrage an zwei Testmandanten. Ein Mandant zeigt nur die Endpunkte seiner Lizenz, bei dir können die Zahlen abweichen. Inoffizielle Endpunkte können sich ohne Vorankündigung ändern.

Häufige Fragen

Wie lege ich lange Filter in den Body statt in die URL?

Mit POST /{entity}/query gibst du im Body das Feld filter mit einer Filter Expression und optional pageSize mit. Die Antwort hat dieselbe Form wie bei GET, ein Objekt mit result.

Ist POST /query ein offizieller Endpunkt?

Die weclapp-Doku beschreibt POST /party/query im Abschnitt „Querying“ und empfiehlt ihn, in der öffentlichen Pfadliste fehlt er aber. Laut Florian Wisheckel (weclapp) wird er in einem der nächsten Changelogs offiziell.

Wie prüfe ich, ob ein Endpunkt auf meinem Mandanten existiert?

Lade die Spec deines Mandanten mit meta/openapi.yaml?includeHidden=true herunter und vergleiche die genutzten Endpunkte mit den Pfaden darin. Ein kurzes Python-Skript, das du wöchentlich laufen lässt, zeigt dir fehlende Endpunkte sofort.

Was ist mein Fallback, wenn der Endpunkt nicht antwortet?

Der offizielle Weg ist GET mit id-in, in Paketen zu 100 IDs. Der Code versucht zuerst den POST und schaltet erst bei 404 oder 405 um.

Darf ich schreibende inoffizielle Endpunkte nutzen?

Nur mit Vorschau, Freigabe und anschließender Kontrolle, und nie in einem Auftragsfluss, der ohne sie stillsteht. Lesende Endpunkte wie /count sind ein überschaubares Risiko.